def test_getFail404() -> None: time.sleep(0.5) app = QCoreApplication([]) http_request_manager = HttpRequestManager.getInstance() cbo = mock.Mock() def callback(*args, **kwargs): cbo.callback(*args, **kwargs) # quit now so we don't need to wait http_request_manager.callLater(0, app.quit) def error_callback(*args, **kwargs): cbo.error_callback(*args, **kwargs) # quit now so we don't need to wait http_request_manager.callLater(0, app.quit) request_data = http_request_manager.get( url="http://localhost:8080/do_not_exist", callback=callback, error_callback=error_callback) # Make sure that if something goes wrong, we quit after 10 seconds http_request_manager.callLater(10.0, app.quit) app.exec() http_request_manager.cleanup() # Remove all unscheduled events cbo.error_callback.assert_called_once_with( request_data.reply, QNetworkReply.ContentNotFoundError) cbo.callback.assert_not_called()
def start_import_data(self): config = self.getCurrentConfig() dest_dir = config.get('hdf5', 'dir') if not os.path.exists(dest_dir) or not os.path.isdir(dest_dir): print("错误:", '指定的目标数据存放目录不存在!') sys.exit(-1) #return if config.getboolean('tdx', 'enable') \ and (not os.path.exists(config['tdx']['dir'] or os.path.isdir(config['tdx']['dir']))): print("错误:", "请确认通达信安装目录是否正确!") sys.exit(-1) #return self.import_running = True print("正在启动任务....") QCoreApplication.processEvents() if config.getboolean('tdx', 'enable'): self.hdf5_import_thread = UseTdxImportToH5Thread(config) else: self.hdf5_import_thread = UsePytdxImportToH5Thread(config) self.hdf5_import_thread.message.connect(self.on_message_from_thread) self.hdf5_import_thread.start() self.escape_time = 0.0 self.escape_time_thread = EscapetimeThread() self.escape_time_thread.message.connect(self.on_message_from_thread) self.escape_time_thread.start()
def update_cache(self, parent=None, timeout=10, force=False, suppress_progress=False): if self.lock.acquire(False): try: update_thread = CacheUpdateThread(self.cache, self.seralize_books, timeout) if not suppress_progress: progress = CacheProgressDialog(parent) progress.set_message(_('Updating MobileRead book cache...')) update_thread.total_changed.connect(progress.set_total) update_thread.update_progress.connect(progress.set_progress) update_thread.update_details.connect(progress.set_details) progress.rejected.connect(update_thread.abort) progress.open() update_thread.start() while update_thread.is_alive() and not progress.canceled: QCoreApplication.processEvents() if progress.isVisible(): progress.accept() return not progress.canceled else: update_thread.start() finally: self.lock.release()
def __ask_for_continue_if_unsaved_changes(self): if not self.__command_handler.can_undo.get(): # Continue if there are no unsaved changes return True else: # Ask if there are unsaved changes box = QMessageBox() box.addButton(QCoreApplication.translate("main_window", "Yes"), box.YesRole) no_button = box.addButton(QCoreApplication.translate("main_window", "No"), box.NoRole) box.setDefaultButton(no_button) box.setWindowTitle(QCoreApplication.translate("main_window", "Unsaved changes")) box.setText(QCoreApplication.translate( "main_window", "Do you really want to continue " "without saving changes?")) box.setIcon(box.Icon.Question) response = box.exec() if (response == 1): # Do not continue because user wants to stop return False else: return True
def test_getBasicAuthSuccess() -> None: time.sleep(0.5) app = QCoreApplication([]) http_request_manager = HttpRequestManager.getInstance() cbo = mock.Mock() def callback(*args, **kwargs): cbo.callback(*args, **kwargs) # quit now so we don't need to wait http_request_manager.callLater(0, app.quit) def error_callback(*args, **kwargs): cbo.callback(*args, **kwargs) # quit now so we don't need to wait http_request_manager.callLater(0, app.quit) request_data = http_request_manager.get( url="http://localhost:8080/auth", headers_dict={"Authorization": "Basic dXNlcjp1c2Vy"}, callback=callback, error_callback=error_callback) # Make sure that if something goes wrong, we quit after 10 seconds http_request_manager.callLater(10.0, app.quit) app.exec() http_request_manager.cleanup() # Remove all unscheduled events cbo.callback.assert_called_once_with(request_data.reply) cbo.error_callback.assert_not_called()
def test_getTimeout() -> None: time.sleep(0.5) app = QCoreApplication([]) http_request_manager = HttpRequestManager.getInstance() cbo = mock.Mock() def error_callback(*args, **kwargs): cbo.error_callback(*args, **kwargs) # quit now so we don't need to wait http_request_manager.callLater(0, app.quit) request_data = http_request_manager.get( url="http://localhost:8080/timeout", error_callback=error_callback, timeout=4) # Make sure that if something goes wrong, we quit after 10 seconds http_request_manager.callLater(10.0, app.quit) app.exec() http_request_manager.cleanup() # Remove all unscheduled events cbo.error_callback.assert_called_once_with( request_data.reply, QNetworkReply.OperationCanceledError) assert request_data.is_aborted_due_to_timeout
def __init__(self, project_tree_controller, node, new_parent, parent=None): """Constructor. Raises ValueError if it is determined that the reparent operation would fail. project_tree_controller -- Reference to the ProjectTreeController in charge of making high-level changes to the project tree. node -- ProjectTreeNode to reparent. new_parent -- New parent node for the ProjectTreeNode. parent -- Parent QUndoCommand. """ super().__init__(project_tree_controller, parent) # Check that the operation is valid. if node.parent is None: raise ValueError( QCoreApplication.translate('ReparentProjectTreeNodeCommand', 'Cannot reparent root project tree node.')) if new_parent is None: raise ValueError( QCoreApplication.translate('ReparentProjectTreeNodeCommand', 'Cannot make a new root project tree node.')) new_parent.verify_can_add_as_child(node) self._node = node self._old_parent = node.parent self._new_parent = new_parent self.setText( QCoreApplication.translate('ReparentProjectTreeNodeCommand', "Move '{}' to Parent '{}'").format(self._node.name, self._new_parent.name)) self.setObsolete(self._old_parent is self._new_parent)
def reparent_node(self, node, new_parent): """Performs a reparent operation on a node in the project tree. Raises ValueError if the operation cannot be performed. node -- Project tree node to reparent. new_parent -- New parent for the project tree node. """ # Do nothing if the node already has the specified parent. if node.parent is new_parent: return # Check that the operation is valid before notifying the ProjectTreeQtModel. if node.parent is None: raise ValueError( QCoreApplication.translate( 'ProjectTreeController', 'Cannot reparent root project tree node.')) if new_parent is None: raise ValueError( QCoreApplication.translate( 'ProjectTreeController', 'Cannot make a new root project tree node.')) new_parent.verify_can_add_as_child(node) old_parent = node.parent # Notify the ProjectTreeQtModel before and after making the change. with self.project_tree_qt_model.begin_reparent_node(node, new_parent): node.parent = new_parent # Send out appropriate signals to notify other GUI components. self.node_reparented.emit(node, new_parent, old_parent)
def update_cache(self, parent=None, timeout=10, force=False, suppress_progress=False): if self.lock.acquire(False): try: update_thread = CacheUpdateThread(self.cache, self.seralize_books, timeout) if not suppress_progress: progress = CacheProgressDialog(parent) progress.set_message( _('Updating MobileRead book cache...')) update_thread.total_changed.connect(progress.set_total) update_thread.update_progress.connect( progress.set_progress) update_thread.update_details.connect(progress.set_details) progress.rejected.connect(update_thread.abort) progress.open() update_thread.start() while update_thread.is_alive() and not progress.canceled: QCoreApplication.processEvents() if progress.isVisible(): progress.accept() return not progress.canceled else: update_thread.start() finally: self.lock.release()
def add_node(self, node, parent): """Adds a node to a sequence component tree. Raises ValueError if the operation cannot be performed. node -- New sequence component tree node to add. parent -- Parent to which the new node will be added. """ if node.parent is not None or node is node.tree_owner.root_seq_component_node: raise ValueError( QCoreApplication.translate( 'SequenceComponentTreeController', 'Cannot add a node that already exists in the sequence component tree.' )) if node.tree_owner is not parent.tree_owner: raise ValueError( QCoreApplication.translate( 'SequenceComponentTreeController', "Cannot mix sequence component nodes from different project tree nodes." )) # Notify the SeqComponentTreeQtModel before and after making the change. with self.seq_component_tree_qt_model.begin_add_node(node, parent): node.parent = parent # Send out appropriate signals to notify other GUI components. self.node_added.emit(node)
def encode_seq_component_tree_node_path(project_tree_path, seq_component_tree_path): """Encodes a path-based reference to a sequence component tree node. Suitable for use with the SEQUENCE_COMPONENT_TREE_NODE_PATH_MEDIA_TYPE media type. Returns the data as a bytes-like object. Raises ValueError if either specified path is relative. project_tree_path -- Absolute TreeNamePath giving the path of the project tree node that owns the relevant sequence component tree. seq_component_tree_path -- Absolute TreeNamePath giving the path of the relevant node in the sequence component tree. """ if not project_tree_path.is_absolute: raise ValueError( QCoreApplication.translate( 'MIMEData', 'Cannot encode relative path as project tree node path data.')) if not seq_component_tree_path.is_absolute: raise ValueError( QCoreApplication.translate( 'MIMEData', 'Cannot encode relative path as sequence component tree node path data.' )) project_tree_path_bytes = str(project_tree_path).encode(MEDIA_STR_ENCODING) seq_component_tree_path_bytes = str(seq_component_tree_path).encode( MEDIA_STR_ENCODING) return pickle.dumps( (project_tree_path_bytes, seq_component_tree_path_bytes))
def __init__(self, seq_component_tree_controller, node, parent_node, parent=None): """Constructor. Raises ValueError if it is determined that the addition operation would fail. seq_component_tree_controller -- Reference to the SequenceComponentTreeController in charge of making high-level changes to the sequence component tree. node -- New BaseSequenceComponentNode to add. parent_node -- Parent BaseSequenceComponentNode to which the new node will be added. parent -- Parent QUndoCommand. """ super().__init__(seq_component_tree_controller, parent) if node.parent is not None: raise ValueError( QCoreApplication.translate( 'AddSequenceComponentTreeNodeCommand', 'Cannot add a node that already exists in the sequence component tree.' )) parent_node.verify_can_add_as_child(node) self._new_node = node self._parent_node = parent_node self.setText( QCoreApplication.translate('AddSequenceComponentTreeNodeCommand', "Create '{}'").format(node.name))
def make_context_menu(self, undo_stack, seq_component_tree_controller, seq_component_node_controller, parent=None): menu = super().make_context_menu(undo_stack, seq_component_tree_controller, seq_component_node_controller, parent) # Add menu items for changing the component type, if that is allowed. change_type_menu = menu.addMenu(QCoreApplication.translate('NonInstancedSequenceComponentNode', 'Change &Type')) def change_type_func_maker(new_component_type): def change_type_func(): undo_stack.push(SetComponentTypeCommand(seq_component_node_controller, self, new_component_type)) return change_type_func for component_type in SUPPORTED_COMPONENT_TYPES: change_type_action = change_type_menu.addAction(component_type.get_icon(), component_type.menu_text) change_type_action.setEnabled(component_type != self.component_type) change_type_action.triggered.connect(change_type_func_maker(component_type)) # Add menu items for creating child nodes, if creating children is allowed. if self.can_have_children: add_menu = menu.addMenu(QCoreApplication.translate('NonInstancedSequenceComponentNode', '&Create Child')) def add_func_maker(component_type): def add_func(): new_node = NonInstancedSequenceComponentNode(self.suggest_child_name(component_type.node_default_name), component_type=component_type, tree_owner=self.tree_owner) undo_stack.push(AddSequenceComponentTreeNodeCommand(seq_component_tree_controller, new_node, self)) return add_func for component_type in SUPPORTED_COMPONENT_TYPES: add_action = add_menu.addAction(component_type.get_icon(), component_type.menu_text) add_action.triggered.connect(add_func_maker(component_type)) # Add a menu item for deleting the node, if it can be deleted. if self.parent is not None: def delete_func(): undo_stack.push(DeleteSequenceComponentTreeNodeCommand(seq_component_tree_controller, self)) delete_action = menu.addAction(QCoreApplication.translate('NonInstancedSequenceComponentNode', '&Delete')) delete_action.triggered.connect(delete_func) return menu
def show_shutdown_message(self, message): smw = self.shutdown_message_widget smw.setVisible(True) txt = smw.text() txt += '\n' + message smw.setText(txt) # Force processing the events needed to show the message QCoreApplication.processEvents()
def show_shutdown_message(self, message=''): smw = self.shutdown_message_widget smw.setGeometry(0, 0, self.width(), self.height()) smw.setVisible(True) smw.raise_() smw.setText(_('<h2>Shutting down</h2><div>') + message) # Force processing the events needed to show the message QCoreApplication.processEvents()
def scale_path(sel, *args): dialog = QInputDialog() text, ok = dialog.getText( self, QCoreApplication.translate("side_widget", "Scale factor"), QCoreApplication.translate("side_widget", "Scale factor")) if (ok): self.__operation_controller.scale_path(sel, text)
def chapter_rendered(self, num): if num > 0: self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(num) self.progress_bar.setValue(0) self.progress_label.setText('Laying out '+ self.document_title) else: self.progress_bar.setValue(self.progress_bar.value()+1) QCoreApplication.processEvents()
def __init__(self, gui_enabled=True): # Start Qt if EventLoop.qt is None: EventLoop.qt = QCoreApplication.instance() or QApplication( []) if gui_enabled else QCoreApplication([]) asyncframes.AbstractEventLoop.__init__(self) QObject.__init__(self) self.moveToThread(QThread.currentThread())
def mouse_dbl_click(self, widget: QWidget, pos: QPoint = QPoint(0, 0), btn: int = Qt.LeftButton, delay: float = 0) -> None: """Send mouse double click to widget""" widget.setFocus() mouse_dbl = self._mouse_event(QEvent.MouseButtonDblClick, pos, btn) QCoreApplication.postEvent(widget, mouse_dbl) self.sleep(delay)
def make_context_menu(self, undo_stack, project_tree_controller, parent=None): """Creates a context menu for this node. undo_stack -- QUndoStack that should receive undoable editing commands generated by the menu. project_tree_controller -- ProjectTreeController in charge of high-level changes to the project tree. parent -- Parent QObject for the context menu. """ menu = QMenu(parent) # Add menu items for creating child nodes, if the node is allowed to have children. if self.can_have_children: def add_dir_func(): new_node = DirProjectTreeNode( self.suggest_child_name(_DIR_NODE_NAME_PREFIX)) undo_stack.push( AddProjectTreeNodeCommand(project_tree_controller, new_node, self)) def add_sequence_func(): new_node = SequenceProjectTreeNode( self.suggest_child_name(_SEQUENCE_NODE_NAME_PREFIX)) undo_stack.push( AddProjectTreeNodeCommand(project_tree_controller, new_node, self)) add_menu = menu.addMenu( QCoreApplication.translate('BaseProjectTreeNode', '&Create Child')) add_dir_action = add_menu.addAction( DirProjectTreeNode.get_icon(), QCoreApplication.translate('BaseProjectTreeNode', '&Directory')) add_sequence_action = add_menu.addAction( SequenceProjectTreeNode.get_icon(), QCoreApplication.translate('BaseProjectTreeNode', '&Sequence')) add_dir_action.triggered.connect(add_dir_func) add_sequence_action.triggered.connect(add_sequence_func) # Add a menu item for deleting the node, if it is not the root node. if self.parent is not None: def delete_func(): undo_stack.push( DeleteProjectTreeNodeCommand(project_tree_controller, self)) delete_action = menu.addAction( QCoreApplication.translate('BaseProjectTreeNode', '&Delete')) delete_action.triggered.connect(delete_func) return menu
def test_install_translators(self): install_translators("ru_RU") txt = QCoreApplication.translate("@default", "Question") self.assertEqual(txt, "Вопрос") # i18n install_translators("en_EN") txt = QCoreApplication.translate("@default", "Question") self.assertEqual(txt, "Question") install_translators() if QLocale.system().name() == "ru_RU": txt = QCoreApplication.translate("@default", "Question") self.assertEqual(txt, "Вопрос") # i18n
def _change_multisampling(self, sample_count): """Creates a new instance of SceneViewer, to support interactive changing of multisampling parameters""" new_canvas = SceneCanvas(self.sceneContainer, samples=sample_count) old_canvas = self.openGLWidget self.sceneContainer.layout().removeWidget(old_canvas) old_canvas.setParent(None) self.sceneContainer.layout().addWidget(new_canvas) self.openGLWidget = new_canvas old_canvas.deleteLater() self._setup_canvas() QCoreApplication.processEvents() # required for repaint below to take self.openGLWidget.repaint()
def check_library(self): from calibre.gui2.dialogs.check_library import CheckLibraryDialog, DBCheck self.gui.library_view.save_state() m = self.gui.library_view.model() m.stop_metadata_backup() db = m.db db.prefs.disable_setting = True d = DBCheck(self.gui, db) d.start() try: d.conn.close() except: pass d.break_cycles() self.gui.library_moved(db.library_path, call_close=not d.closed_orig_conn) if d.rejected: return if d.error is None: if not question_dialog( self.gui, _("Success"), _( "Found no errors in your calibre library database." " Do you want calibre to check if the files in your " " library match the information in the database?" ), ): return else: return error_dialog( self.gui, _("Failed"), _("Database integrity check failed, click Show details" " for details."), show=True, det_msg=d.error[1], ) self.gui.status_bar.show_message(_("Starting library scan, this may take a while")) try: QCoreApplication.processEvents() d = CheckLibraryDialog(self.gui, m.db) if not d.do_exec(): info_dialog( self.gui, _("No problems found"), _("The files in your library match the information " "in the database."), show=True, ) finally: self.gui.status_bar.clear_message()
def closeEvent_button(self, event): """This function is called when quit button is clicked. This function make sure the program quit safely. """ # Set qss to make sure the QMessageBox can be seen reply = QMessageBox.question(self, 'Quit',"Are you sure to quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: QCoreApplication.quit()
def downloadOpdsCatalog(self, gui, opdsCatalogUrl): print "downloading catalog: %s" % opdsCatalogUrl opdsCatalogFeed = parse(opdsCatalogUrl) self.books = self.makeMetadataFromParsedOpds(opdsCatalogFeed.entries) self.filterBooks() QCoreApplication.processEvents() nextUrl = self.findNextUrl(opdsCatalogFeed.feed) while nextUrl is not None: nextFeed = parse(nextUrl) self.books = self.books + self.makeMetadataFromParsedOpds(nextFeed.entries) self.filterBooks() QCoreApplication.processEvents() nextUrl = self.findNextUrl(nextFeed.feed)
def mouse_click(self, widget: QWidget, pos: QPoint = QPoint(0, 0), btn: int = Qt.LeftButton, delay: float = 0) -> None: """Send mouse click to widget""" # TODO: if delete a comment from the next line, the program crashes # Process finished with exit code 139 (interrupted signal 11: SIGSEGV) # widget.setFocus() # !!! find the cause of the error !!! mouse_press = self._mouse_event(QEvent.MouseButtonPress, pos, btn) mouse_release = self._mouse_event(QEvent.MouseButtonRelease, pos, btn) QCoreApplication.postEvent(widget, mouse_press) QCoreApplication.postEvent(widget, mouse_release) self.sleep(delay)
def check_library(self): from calibre.gui2.dialogs.check_library import CheckLibraryDialog, DBCheck self.gui.library_view.save_state() m = self.gui.library_view.model() m.stop_metadata_backup() db = m.db db.prefs.disable_setting = True library_path = db.library_path d = DBCheck(self.gui, db) d.start() try: m.close() except: pass d.break_cycles() self.gui.library_moved(library_path) if d.rejected: return if d.error is None: if not question_dialog( self.gui, _('Success'), _('Found no errors in your calibre library database.' ' Do you want calibre to check if the files in your ' ' library match the information in the database?')): return else: return error_dialog( self.gui, _('Failed'), _('Database integrity check failed, click Show details' ' for details.'), show=True, det_msg=d.error[1]) self.gui.status_bar.show_message( _('Starting library scan, this may take a while')) try: QCoreApplication.processEvents() d = CheckLibraryDialog(self.gui, m.db) if not d.do_exec(): info_dialog( self.gui, _('No problems found'), _('The files in your library match the information ' 'in the database.'), show=True) finally: self.gui.status_bar.clear_message()
def __init__(self, seq_component_tree_controller, node, new_name, parent=None): """Constructor. Raises ValueError if it is determined that the rename operation would fail. seq_component_tree_controller -- Reference to the SequenceComponentTreeController in charge of making high-level changes to the sequence component tree. node -- BaseSequenceComponentNode to rename. new_name -- New name for the BaseSequenceComponentNode. parent -- Parent QUndoCommand. """ super().__init__(seq_component_tree_controller, parent) # Check that the operation is valid. if node.parent is not None: node.parent.verify_child_name_available(new_name) else: NamedTreeNode.verify_name_valid(new_name) self._node = node self._old_name = node.name self._new_name = new_name self.setText( QCoreApplication.translate( 'RenameSequenceComponentTreeNodeCommand', "Rename '{}' to '{}'").format(self._old_name, new_name)) self.setObsolete(self._old_name == self._new_name)
def __init__(self, updater): super().__init__(QEvent.User) self._updater = updater self._result = None self._semaphore = QSemaphore(1) if QCoreApplication.instance().thread() != QThread.currentThread(): self._semaphore.acquire()
def _set_undo_stack_clean(self, is_clean): """Called when the undo stack changes clean status. is_clean -- Boolean indicating whether the undo stack is currently in a clean state. """ self.actionSaveProject.setEnabled(not is_clean) window_title = QCoreApplication.translate('MainWindow', 'ScriptASeq') self.setWindowTitle(window_title if is_clean else window_title + '*')
def delete_node(self, node): """Deletes a node from a sequence component tree. Raises ValueError if the operation cannot be performed. node -- Sequence component tree node to delete. """ if node.parent is None: raise ValueError( QCoreApplication.translate( 'SequenceComponentTreeController', 'Cannot delete root node from the sequence component tree.' )) # Reset the active node first, if it or one of its ancestors is being deleted. if self.active_node is not None and (node is self.active_node or node in self.active_node.ancestors): self.active_node = None parent_node = node.parent # Notify the SeqComponentTreeQtModel before and after making the change. with self.seq_component_tree_qt_model.begin_delete_node(node): node.parent = None # Send out appropriate signals to notify other GUI components. self.node_deleted.emit(node, parent_node)
def suggest_child_name(self, prefix=DEFAULT_NAME_PREFIX): """Suggests an available child name starting with the specified prefix. Raises ValueError if this node is not allowed to have children, or if the prefix is not a valid node name. prefix -- String that the child name must start with. """ # Check that the prefix is a valid name. NamedTreeNode.verify_name_valid(prefix) # Check that this node is allowed to have children. if not self.can_have_children: raise ValueError( QCoreApplication.translate( 'NamedTreeNode', "Node '{}' is not allowed to have children.").format( self.name)) # Use the prefix as the full name if it is available. if prefix not in self._children: return prefix # Otherwise, append a number to the prefix. suffix_num = 0 while prefix + _SUFFIX_FORMAT_STRING.format( suffix_num) in self._children: suffix_num += 1 return prefix + _SUFFIX_FORMAT_STRING.format(suffix_num)
def show_browser(self): ''' Show the currently loaded web page in a window. Useful for debugging. ''' if getattr(QCoreApplication.instance(), 'headless', False): raise RuntimeError('Cannot show browser when running in a headless Qt application') view = BrowserView(self.page) view.exec_()
def __init__(self, *args, **kwargs): QDialog.__init__(self, *args) self.setupUi(self) desktop = QCoreApplication.instance().desktop() geom = desktop.availableGeometry(self) nh, nw = max(550, geom.height()-25), max(700, geom.width()-10) nh = min(self.height(), nh) nw = min(self.width(), nw) self.resize(nw, nh)
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 check_library(self): from calibre.gui2.dialogs.check_library import CheckLibraryDialog, DBCheck self.gui.library_view.save_state() m = self.gui.library_view.model() m.stop_metadata_backup() db = m.db db.prefs.disable_setting = True library_path = db.library_path d = DBCheck(self.gui, db) d.start() try: m.close() except: pass d.break_cycles() self.gui.library_moved(library_path, call_close=False) if d.rejected: return if d.error is None: if not question_dialog(self.gui, _('Success'), _('Found no errors in your calibre library database.' ' Do you want calibre to check if the files in your ' ' library match the information in the database?')): return else: return error_dialog(self.gui, _('Failed'), _('Database integrity check failed, click Show details' ' for details.'), show=True, det_msg=d.error[1]) self.gui.status_bar.show_message( _('Starting library scan, this may take a while')) try: QCoreApplication.processEvents() d = CheckLibraryDialog(self.gui, m.db) if not d.do_exec(): info_dialog(self.gui, _('No problems found'), _('The files in your library match the information ' 'in the database.'), show=True) finally: self.gui.status_bar.clear_message()
def parsed(self): if not self.renderer.aborted and self.renderer.lrf is not None: width, height = self.renderer.lrf.device_info.width, self.renderer.lrf.device_info.height hdelta = self.tool_bar.height() + 3 s = QScrollBar(self) scrollbar_adjust = min(s.width(), s.height()) self.graphics_view.resize_for(width + scrollbar_adjust, height + scrollbar_adjust) desktop = QCoreApplication.instance().desktop() screen_height = desktop.availableGeometry(self).height() - 25 height = min(screen_height, height + hdelta + scrollbar_adjust) self.resize(width + scrollbar_adjust, height) self.setWindowTitle(self.renderer.lrf.metadata.title + " - " + __appname__) self.document_title = self.renderer.lrf.metadata.title if self.opts.profile: import cProfile lrf = self.renderer.lrf cProfile.runctx("self.document.render(lrf)", globals(), locals(), lrf.metadata.title + ".stats") print "Stats written to", self.renderer.lrf.metadata.title + ".stats" else: start = time.time() self.document.render(self.renderer.lrf) print "Layout time:", time.time() - start, "seconds" self.renderer.lrf = None self.graphics_view.setScene(self.document) self.graphics_view.show() self.spin_box.setRange(1, self.document.num_of_pages) self.slider.setRange(1, self.document.num_of_pages) self.spin_box.setSuffix(" of %d" % (self.document.num_of_pages,)) self.spin_box.updateGeometry() self.stack.setCurrentIndex(0) self.graphics_view.setFocus(Qt.OtherFocusReason) elif self.renderer.exception is not None: exception = self.renderer.exception print >> sys.stderr, "Error rendering document" print >> sys.stderr, exception print >> sys.stderr, self.renderer.formatted_traceback msg = ( u"<p><b>%s</b>: " % (exception.__class__.__name__,) + unicode(str(exception), "utf8", "replace") + u"</p>" ) msg += u"<p>Failed to render document</p>" msg += u"<p>Detailed <b>traceback</b>:<pre>" msg += self.renderer.formatted_traceback + "</pre>" d = ConversionErrorDialog(self, "Error while rendering file", msg) d.exec_()
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'))) QCoreApplication.setOrganizationName(ORG_NAME) QCoreApplication.setApplicationName(APP_UID) opts = normalize_settings(parser, opts) stream = open(args[1], 'rb') if len(args) > 1 else None main = file_renderer(stream, opts, logger=logger) sys.excepthook = main.unhandled_exception main.show() main.render() main.activateWindow() main.raise_() return app.exec_() return 0
def parsed(self): if not self.renderer.aborted and self.renderer.lrf is not None: width, height = self.renderer.lrf.device_info.width, \ self.renderer.lrf.device_info.height hdelta = self.tool_bar.height()+3 s = QScrollBar(self) scrollbar_adjust = min(s.width(), s.height()) self.graphics_view.resize_for(width+scrollbar_adjust, height+scrollbar_adjust) desktop = QCoreApplication.instance().desktop() screen_height = desktop.availableGeometry(self).height() - 25 height = min(screen_height, height+hdelta+scrollbar_adjust) self.resize(width+scrollbar_adjust, height) self.setWindowTitle(self.renderer.lrf.metadata.title + ' - ' + __appname__) self.document_title = self.renderer.lrf.metadata.title if self.opts.profile: import cProfile lrf = self.renderer.lrf cProfile.runctx('self.document.render(lrf)', globals(), locals(), lrf.metadata.title+'.stats') print('Stats written to', self.renderer.lrf.metadata.title+'.stats') else: start = time.time() self.document.render(self.renderer.lrf) print('Layout time:', time.time()-start, 'seconds') self.renderer.lrf = None self.graphics_view.setScene(self.document) self.graphics_view.show() self.spin_box.setRange(1, self.document.num_of_pages) self.slider.setRange(1, self.document.num_of_pages) self.spin_box.setSuffix(' of %d'%(self.document.num_of_pages,)) self.spin_box.updateGeometry() self.stack.setCurrentIndex(0) self.graphics_view.setFocus(Qt.OtherFocusReason) elif self.renderer.exception is not None: exception = self.renderer.exception print('Error rendering document', file=sys.stderr) print(exception, file=sys.stderr) print(self.renderer.formatted_traceback, file=sys.stderr) msg = u'<p><b>%s</b>: '%(exception.__class__.__name__,) + as_unicode(exception) + u'</p>' msg += u'<p>Failed to render document</p>' msg += u'<p>Detailed <b>traceback</b>:<pre>' msg += self.renderer.formatted_traceback + '</pre>' d = ConversionErrorDialog(self, 'Error while rendering file', msg) d.exec_()
def __init__(self, gui, row): self.is_pane = gprefs.get('quickview_is_pane', False) if not self.is_pane: QDialog.__init__(self, gui, flags=Qt.Widget) else: QDialog.__init__(self, gui) Ui_Quickview.__init__(self) self.setupUi(self) self.isClosed = False self.current_book = None self.closed_by_button = False if self.is_pane: self.main_grid_layout.setContentsMargins(0, 0, 0, 0) self.books_table_column_widths = None try: self.books_table_column_widths = \ gprefs.get('quickview_dialog_books_table_widths', None) if not self.is_pane: geom = gprefs.get('quickview_dialog_geometry', bytearray('')) self.restoreGeometry(QByteArray(geom)) except: pass if not self.is_pane: # Remove the help button from the window title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) self.setWindowFlags(self.windowFlags()|Qt.WindowStaysOnTopHint) self.setWindowIcon(icon) self.view = gui.library_view self.db = self.view.model().db self.gui = gui self.is_closed = False self.current_book_id = None # the db id of the book used to fill the lh pane self.current_column = None # current logical column in books list self.current_key = None # current lookup key in books list self.last_search = None self.no_valid_items = False self.fm = self.db.field_metadata self.items.setSelectionMode(QAbstractItemView.SingleSelection) self.items.currentTextChanged.connect(self.item_selected) self.items.setProperty('highlight_current_item', 150) focus_filter = WidgetFocusFilter(self.items) focus_filter.focus_entered_signal.connect(self.focus_entered) self.items.installEventFilter(focus_filter) self.tab_pressed_signal.connect(self.tab_pressed) return_filter = BooksTableFilter(self.books_table) return_filter.return_pressed_signal.connect(self.return_pressed) self.books_table.installEventFilter(return_filter) focus_filter = WidgetFocusFilter(self.books_table) focus_filter.focus_entered_signal.connect(self.focus_entered) self.books_table.installEventFilter(focus_filter) self.close_button.clicked.connect(self.close_button_clicked) self.refresh_button.clicked.connect(self.refill) self.tab_order_widgets = [self.items, self.books_table, self.lock_qv, self.dock_button, self.search_button, self.refresh_button, self.close_button] for idx,widget in enumerate(self.tab_order_widgets): widget.installEventFilter(WidgetTabFilter(widget, idx, self.tab_pressed_signal)) self.books_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.books_table.setSelectionMode(QAbstractItemView.SingleSelection) self.books_table.setProperty('highlight_current_item', 150) # Set up the books table columns self.add_columns_to_widget() self.books_table_header_height = self.books_table.height() self.books_table.cellDoubleClicked.connect(self.book_doubleclicked) self.books_table.currentCellChanged.connect(self.books_table_cell_changed) self.books_table.cellClicked.connect(self.books_table_set_search_string) self.books_table.cellActivated.connect(self.books_table_set_search_string) self.books_table.sortByColumn(0, Qt.AscendingOrder) # get the standard table row height. Do this here because calling # resizeRowsToContents can word wrap long cell contents, creating # double-high rows self.books_table.setRowCount(1) self.books_table.setItem(0, 0, TableItem('A', '')) self.books_table.resizeRowsToContents() self.books_table_row_height = self.books_table.rowHeight(0) self.books_table.setRowCount(0) # Add the data self.refresh(row) self.view.clicked.connect(self.slave) self.view.selectionModel().currentColumnChanged.connect(self.column_slave) QCoreApplication.instance().aboutToQuit.connect(self.save_state) self.search_button.clicked.connect(self.do_search) self.view.model().new_bookdisplay_data.connect(self.book_was_changed) self.close_button.setDefault(False) self.close_button_tooltip = _('The Quickview shortcut ({0}) shows/hides the Quickview panel') self.search_button_tooltip = _('Search in the library view for the currently highlighted selection') self.search_button.setToolTip(self.search_button_tooltip) if self.is_pane: self.dock_button.setText(_('Undock')) self.dock_button.setToolTip(_('Pop up the quickview panel into its own floating window')) self.dock_button.setIcon(QIcon(I('arrow-up.png'))) # Remove the ampersands from the buttons because shortcuts exist. self.lock_qv.setText(_('Lock Quickview contents')) self.search_button.setText(_('Search')) self.refresh_button.setText(_('Refresh')) self.gui.quickview_splitter.add_quickview_dialog(self) self.close_button.setVisible(False) else: self.dock_button.setToolTip(_('Embed the quickview panel into the main calibre window')) self.dock_button.setIcon(QIcon(I('arrow-down.png'))) self.set_focus() self.books_table.horizontalHeader().sectionResized.connect(self.section_resized) self.dock_button.clicked.connect(self.show_as_pane_changed) self.gui.search.cleared.connect(self.indicate_no_items) # Enable the refresh button only when QV is locked self.refresh_button.setEnabled(False) self.lock_qv.stateChanged.connect(self.lock_qv_changed) self.view_icon = QIcon(I('view.png')) self.view_plugin = self.gui.iactions['View'] self.books_table.setContextMenuPolicy(Qt.CustomContextMenu) self.books_table.customContextMenuRequested.connect(self.show_context_menu)
def initialization_failed(self): print('Catastrophic failure initializing GUI, bailing out...') QCoreApplication.exit(1) raise SystemExit(1)
def __init__(self, parent, dbspec, ids, db): import re, io from calibre import prints as info from PyQt5.uic import compileUi QDialog.__init__(self, parent) self.setupUi(self) self.dbspec, self.ids = dbspec, ids # Display the number of books we've been passed self.count.setText(unicode_type(self.count.text()).format(len(ids))) # Display the last-used title self.title.setText(dynamic.get('catalog_last_used_title', _('My books'))) self.fmts, self.widgets = [], [] for plugin in catalog_plugins(): if plugin.name in config['disabled_plugins']: continue name = plugin.name.lower().replace(' ', '_') if getattr(plugin, 'plugin_path', None) is None: try: catalog_widget = importlib.import_module('calibre.gui2.catalog.'+name) pw = catalog_widget.PluginWidget() pw.parent_ref = weakref.ref(self) pw.initialize(name, db) pw.ICON = I('forward.png') self.widgets.append(pw) [self.fmts.append([file_type.upper(), pw.sync_enabled,pw]) for file_type in plugin.file_types] except ImportError: info("ImportError initializing %s" % name) continue else: # Load dynamic tab form = os.path.join(plugin.resources_path,'%s.ui' % name) klass = os.path.join(plugin.resources_path,'%s.py' % name) compiled_form = os.path.join(plugin.resources_path,'%s_ui.py' % name) if os.path.exists(form) and os.path.exists(klass): # info("Adding widget for user-installed Catalog plugin %s" % plugin.name) # Compile the .ui form provided in plugin.zip if not os.path.exists(compiled_form): # info('\tCompiling form', form) buf = io.BytesIO() compileUi(form, buf) dat = buf.getvalue() dat = re.compile(r'QtGui.QApplication.translate\(.+?,\s+"(.+?)(?<!\\)",.+?\)', re.DOTALL).sub(r'_("\1")', dat) open(compiled_form, 'wb').write(dat) # Import the dynamic PluginWidget() from .py file provided in plugin.zip try: sys.path.insert(0, plugin.resources_path) catalog_widget = importlib.import_module(name) pw = catalog_widget.PluginWidget() pw.initialize(name) pw.ICON = I('forward.png') self.widgets.append(pw) [self.fmts.append([file_type.upper(), pw.sync_enabled,pw]) for file_type in plugin.file_types] except ImportError: info("ImportError with %s" % name) continue finally: sys.path.remove(plugin.resources_path) else: info("No dynamic tab resources found for %s" % name) self.widgets = sorted(self.widgets, key=lambda x: x.TITLE) # Generate a sorted list of installed catalog formats/sync_enabled pairs fmts = sorted([x[0] for x in self.fmts]) self.sync_enabled_formats = [] for fmt in self.fmts: if fmt[1]: self.sync_enabled_formats.append(fmt[0]) # Callbacks when format, title changes self.format.currentIndexChanged.connect(self.format_changed) self.format.currentIndexChanged.connect(self.settings_changed) self.title.editingFinished.connect(self.settings_changed) # Add the installed catalog format list to the format QComboBox self.format.blockSignals(True) self.format.addItems(fmts) pref = dynamic.get('catalog_preferred_format', 'CSV') idx = self.format.findText(pref) if idx > -1: self.format.setCurrentIndex(idx) self.format.blockSignals(False) if self.sync.isEnabled(): self.sync.setChecked(dynamic.get('catalog_sync_to_device', True)) self.add_to_library.setChecked(dynamic.get('catalog_add_to_library', True)) self.format.currentIndexChanged.connect(self.show_plugin_tab) self.buttonBox.button(self.buttonBox.Apply).clicked.connect(self.apply) self.buttonBox.button(self.buttonBox.Help).clicked.connect(self.help) self.show_plugin_tab(None) geom = dynamic.get('catalog_window_geom', None) if geom is not None: self.restoreGeometry(bytes(geom)) else: self.resize(self.sizeHint()) d = QCoreApplication.instance().desktop() g = d.availableGeometry(d.screenNumber(self)) self.setMaximumWidth(g.width() - 50) self.setMaximumHeight(g.height() - 50)
def sizeHint(self): desktop = QCoreApplication.instance().desktop() geom = desktop.availableGeometry(self) nh, nw = max(300, geom.height()-50), max(400, geom.width()-70) return QSize(nw, nh)
def on_message_from_thread(self, msg): if not msg or len(msg) < 2: print("msg is empty!") return msg_name, msg_task_name = msg[:2] if msg_name == 'ESCAPE_TIME': self.escape_time = msg_task_name / 60 elif msg_name == 'HDF5_IMPORT': if msg_task_name == 'INFO': print(msg[2]) elif msg_task_name == 'THREAD': status = msg[2] if status == 'FAILURE': self.details.append(msg[3]) self.hdf5_import_thread.terminate() self.hdf5_import_thread = None self.escape_time_thread.stop() self.escape_time_thread = None print("\n导入完毕, 共耗时 {:>.2f} 分钟".format(self.escape_time)) print('\n=========================================================') print("导入详情:") for info in self.details: print(info) print('=========================================================') self.import_running = False QCoreApplication.quit() elif msg_task_name == 'IMPORT_KDATA': ktype, progress = msg[2:4] if ktype != 'FINISHED': self.print_progress(ktype, progress) else: self.details.append('导入 {} {} 记录数:{}'.format(msg[3], msg[4], msg[5])) elif msg_task_name == 'IMPORT_TRANS': ktype, progress = msg[2:4] if ktype != 'FINISHED': self.print_progress('TRANS', progress) else: self.details.append('导入 {} 分笔记录数:{}'.format(msg[3], msg[5])) elif msg_task_name == 'IMPORT_TIME': ktype, progress = msg[2:4] if ktype != 'FINISHED': self.print_progress('TIME', progress) else: self.details.append('导入 {} 分时记录数:{}'.format(msg[3], msg[5])) elif msg_task_name == 'IMPORT_WEIGHT': if msg[2] == 'INFO': pass elif msg[2] == 'FINISHED': print('导入权息数据完毕!') elif msg[2] == '导入完成!': self.details.append('导入权息记录数:{}'.format(msg[3])) elif msg[2] == '权息数据无变化': self.details.append(msg[3]) else: print('权息{}'.format(msg[2]))
def __init__(self, gui, view, row): QDialog.__init__(self, gui, flags=Qt.Window) Ui_Quickview.__init__(self) self.setupUi(self) self.isClosed = False self.books_table_column_widths = None try: self.books_table_column_widths = \ gprefs.get('quickview_dialog_books_table_widths', None) geom = gprefs.get('quickview_dialog_geometry', bytearray('')) self.restoreGeometry(QByteArray(geom)) except: pass # Remove the help button from the window title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) self.setWindowFlags(self.windowFlags()|Qt.WindowStaysOnTopHint) self.setWindowIcon(icon) self.db = view.model().db self.view = view self.gui = gui self.is_closed = False self.current_book_id = None self.current_key = None self.last_search = None self.current_column = None self.current_item = None self.no_valid_items = False column_positions = self.view.get_state()['column_positions'] column_order = ['title', 'authors', 'series'] column_order.sort(key=lambda col: column_positions[col]) self.title_column = column_order.index('title') self.author_column = column_order.index('authors') self.series_column = column_order.index('series') self.items.setSelectionMode(QAbstractItemView.SingleSelection) self.items.currentTextChanged.connect(self.item_selected) # Set up the books table columns self.books_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.books_table.setSelectionMode(QAbstractItemView.SingleSelection) self.books_table.setColumnCount(3) t = QTableWidgetItem(_('Title')) self.books_table.setHorizontalHeaderItem(self.title_column, t) t = QTableWidgetItem(_('Authors')) self.books_table.setHorizontalHeaderItem(self.author_column, t) t = QTableWidgetItem(ngettext("Series", 'Series', 1)) self.books_table.setHorizontalHeaderItem(self.series_column, t) self.books_table_header_height = self.books_table.height() self.books_table.cellDoubleClicked.connect(self.book_doubleclicked) self.books_table.sortByColumn(self.title_column, Qt.AscendingOrder) # get the standard table row height. Do this here because calling # resizeRowsToContents can word wrap long cell contents, creating # double-high rows self.books_table.setRowCount(1) self.books_table.setItem(0, 0, TableItem('A', '')) self.books_table.resizeRowsToContents() self.books_table_row_height = self.books_table.rowHeight(0) self.books_table.setRowCount(0) # Add the data self.refresh(row) self.view.clicked.connect(self.slave) self.change_quickview_column.connect(self.slave) QCoreApplication.instance().aboutToQuit.connect(self.save_state) self.search_button.clicked.connect(self.do_search) view.model().new_bookdisplay_data.connect(self.book_was_changed) close_button = self.buttonBox.button(QDialogButtonBox.Close) close_button.setAutoDefault(False)
def __init__(self, parent, view, row, link_delegate): QDialog.__init__(self, parent) self.normal_brush = QBrush(Qt.white) self.marked_brush = QBrush(Qt.lightGray) self.marked = None self.gui = parent self.splitter = QSplitter(self) self._l = l = QVBoxLayout(self) self.setLayout(l) l.addWidget(self.splitter) self.cover = CoverView(self) self.cover.resizeEvent = self.cover_view_resized self.cover.cover_changed.connect(self.cover_changed) self.cover_pixmap = None self.cover.sizeHint = self.details_size_hint self.splitter.addWidget(self.cover) self.details = Details(parent.book_details.book_info, self) self.details.page().setLinkDelegationPolicy(self.details.page().DelegateAllLinks) self.details.linkClicked.connect(self.link_clicked) s = self.details.page().settings() s.setAttribute(s.JavascriptEnabled, False) self.css = css() self.link_delegate = link_delegate self.details.setAttribute(Qt.WA_OpaquePaintEvent, False) palette = self.details.palette() self.details.setAcceptDrops(False) palette.setBrush(QPalette.Base, Qt.transparent) self.details.page().setPalette(palette) self.c = QWidget(self) self.c.l = l2 = QGridLayout(self.c) self.c.setLayout(l2) l2.addWidget(self.details, 0, 0, 1, -1) self.splitter.addWidget(self.c) self.fit_cover = QCheckBox(_('Fit &cover within view'), self) self.fit_cover.setChecked(gprefs.get('book_info_dialog_fit_cover', True)) l2.addWidget(self.fit_cover, l2.rowCount(), 0, 1, -1) self.previous_button = QPushButton(QIcon(I('previous.png')), _('&Previous'), self) self.previous_button.clicked.connect(self.previous) l2.addWidget(self.previous_button, l2.rowCount(), 0) self.next_button = QPushButton(QIcon(I('next.png')), _('&Next'), self) self.next_button.clicked.connect(self.next) l2.addWidget(self.next_button, l2.rowCount() - 1, 1) self.view = view self.current_row = None self.refresh(row) self.view.model().new_bookdisplay_data.connect(self.slave) self.fit_cover.stateChanged.connect(self.toggle_cover_fit) self.ns = QShortcut(QKeySequence('Alt+Right'), self) self.ns.activated.connect(self.next) self.ps = QShortcut(QKeySequence('Alt+Left'), self) self.ps.activated.connect(self.previous) self.next_button.setToolTip(_('Next [%s]')% unicode(self.ns.key().toString(QKeySequence.NativeText))) self.previous_button.setToolTip(_('Previous [%s]')% unicode(self.ps.key().toString(QKeySequence.NativeText))) geom = QCoreApplication.instance().desktop().availableGeometry(self) screen_height = geom.height() - 100 screen_width = geom.width() - 100 self.resize(max(int(screen_width/2), 700), screen_height) saved_layout = gprefs.get('book_info_dialog_layout', None) if saved_layout is not None: try: self.restoreGeometry(saved_layout[0]) self.splitter.restoreState(saved_layout[1]) except Exception: pass
def __init__(self, gui, row): self.is_pane = gprefs.get('quickview_is_pane', False) if not self.is_pane: QDialog.__init__(self, gui, flags=Qt.Window) else: QDialog.__init__(self, gui) Ui_Quickview.__init__(self) self.setupUi(self) self.isClosed = False self.books_table_column_widths = None try: self.books_table_column_widths = \ gprefs.get('quickview_dialog_books_table_widths', None) if not self.is_pane: geom = gprefs.get('quickview_dialog_geometry', bytearray('')) self.restoreGeometry(QByteArray(geom)) except: pass if not self.is_pane: # Remove the help button from the window title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) self.setWindowFlags(self.windowFlags()|Qt.WindowStaysOnTopHint) self.setWindowIcon(icon) self.view = gui.library_view self.db = self.view.model().db self.gui = gui self.is_closed = False self.current_book_id = None self.current_key = None self.last_search = None self.current_column = None self.current_item = None self.no_valid_items = False column_positions = self.view.get_state()['column_positions'] column_order = ['title', 'authors', 'series'] column_order.sort(key=lambda col: column_positions[col]) self.title_column = column_order.index('title') self.author_column = column_order.index('authors') self.series_column = column_order.index('series') self.items.setSelectionMode(QAbstractItemView.SingleSelection) self.items.currentTextChanged.connect(self.item_selected) self.items.setProperty('highlight_current_item', 150) focus_filter = WidgetFocusFilter(self.items) focus_filter.focus_entered_signal.connect(self.focus_entered) self.items.installEventFilter(focus_filter) self.tab_pressed_signal.connect(self.tab_pressed) # Set up the books table columns return_filter = BooksTableFilter(self.books_table) return_filter.return_pressed_signal.connect(self.return_pressed) self.books_table.installEventFilter(return_filter) focus_filter = WidgetFocusFilter(self.books_table) focus_filter.focus_entered_signal.connect(self.focus_entered) self.books_table.installEventFilter(focus_filter) self.close_button = self.buttonBox.button(QDialogButtonBox.Close) self.tab_order_widgets = [self.items, self.books_table, self.lock_qv, self.dock_button, self.search_button, self.close_button] for idx,widget in enumerate(self.tab_order_widgets): widget.installEventFilter(WidgetTabFilter(widget, idx, self.tab_pressed_signal)) self.books_table.setSelectionBehavior(QAbstractItemView.SelectRows) self.books_table.setSelectionMode(QAbstractItemView.SingleSelection) self.books_table.setProperty('highlight_current_item', 150) self.books_table.setColumnCount(3) t = QTableWidgetItem(_('Title')) self.books_table.setHorizontalHeaderItem(self.title_column, t) t = QTableWidgetItem(_('Authors')) self.books_table.setHorizontalHeaderItem(self.author_column, t) t = QTableWidgetItem(ngettext("Series", 'Series', 1)) self.books_table.setHorizontalHeaderItem(self.series_column, t) self.books_table_header_height = self.books_table.height() self.books_table.cellDoubleClicked.connect(self.book_doubleclicked) self.books_table.currentCellChanged.connect(self.books_table_cell_changed) self.books_table.cellClicked.connect(self.books_table_set_search_string) self.books_table.cellActivated.connect(self.books_table_set_search_string) self.books_table.sortByColumn(self.title_column, Qt.AscendingOrder) # get the standard table row height. Do this here because calling # resizeRowsToContents can word wrap long cell contents, creating # double-high rows self.books_table.setRowCount(1) self.books_table.setItem(0, 0, TableItem('A', '')) self.books_table.resizeRowsToContents() self.books_table_row_height = self.books_table.rowHeight(0) self.books_table.setRowCount(0) # Add the data self.refresh(row) self.view.clicked.connect(self.slave) self.change_quickview_column.connect(self.slave) QCoreApplication.instance().aboutToQuit.connect(self.save_state) self.search_button.clicked.connect(self.do_search) self.view.model().new_bookdisplay_data.connect(self.book_was_changed) self.close_button.setDefault(False) self.close_button_tooltip = _('The Quickview shortcut ({0}) shows/hides the Quickview pane') self.search_button_tooltip = _('Search in the library view for the currently highlighted selection') self.search_button.setToolTip(self.search_button_tooltip) if self.is_pane: self.dock_button.setText(_('Undock')) self.dock_button.setToolTip(_('Pop up the quickview panel into its own floating window')) self.dock_button.setIcon(QIcon(I('arrow-up.png'))) self.lock_qv.setText(_('Lock Quickview contents')) self.search_button.setText(_('Search')) self.gui.quickview_splitter.add_quickview_dialog(self) else: self.close_button.setText(_('&Close')) self.dock_button.setText(_('&Dock')) self.dock_button.setToolTip(_('Embed the quickview panel into the main calibre window')) self.dock_button.setIcon(QIcon(I('arrow-down.png'))) self.set_focus() self.books_table.horizontalHeader().sectionResized.connect(self.section_resized) self.dock_button.clicked.connect(self.show_as_pane_changed)
def available_width(): desktop = QCoreApplication.instance().desktop() return desktop.availableGeometry().width()
def available_height(): desktop = QCoreApplication.instance().desktop() return desktop.availableGeometry().height()
def available_heights(): desktop = QCoreApplication.instance().desktop() return map(lambda x: x.height(), map(desktop.availableGeometry, range(desktop.screenCount())))
def no_more_jobs(self): if self.is_running: self.stop() QCoreApplication.instance().alert(self, 5000)
def main(): app = QCoreApplication(sys.argv) x = HKUImportDataCMD() x.start_import_data() sys.exit(app.exec())