def __call__(self, ok): from PyQt4.Qt import QImage, QPainter, QByteArray, QBuffer try: if not ok: raise RuntimeError('Rendering of HTML failed.') de = self.page.mainFrame().documentElement() pe = de.findFirst('parsererror') if not pe.isNull(): raise ParserError(pe.toPlainText()) image = QImage(self.page.viewportSize(), QImage.Format_ARGB32) image.setDotsPerMeterX(96*(100/2.54)) image.setDotsPerMeterY(96*(100/2.54)) painter = QPainter(image) self.page.mainFrame().render(painter) painter.end() ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) image.save(buf, 'JPEG') self.data = str(ba.data()) except Exception as e: self.exception = e self.traceback = traceback.format_exc() finally: self.loop.exit(0)
def pixmap_to_data(pixmap, format='JPEG', quality=90): ''' Return the QPixmap pixmap as a string saved in the specified format. ''' ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) pixmap.save(buf, format, quality=quality) return bytes(ba.data())
def image_to_data(image): # {{{ ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) if not image.save(buf, CACHE_FORMAT): raise EncodeError('Failed to encode thumbnail') ret = bytes(ba.data()) buf.close() return ret
def add_image(self, img, cache_key): ref = self.get_image(cache_key) if ref is not None: return ref fmt = img.format() image = QImage(img) if (image.depth() == 1 and img.colorTable().size() == 2 and img.colorTable().at(0) == QColor(Qt.black).rgba() and img.colorTable().at(1) == QColor(Qt.white).rgba()): if fmt == QImage.Format_MonoLSB: image = image.convertToFormat(QImage.Format_Mono) fmt = QImage.Format_Mono else: if (fmt != QImage.Format_RGB32 and fmt != QImage.Format_ARGB32): image = image.convertToFormat(QImage.Format_ARGB32) fmt = QImage.Format_ARGB32 w = image.width() h = image.height() d = image.depth() if fmt == QImage.Format_Mono: bytes_per_line = (w + 7) >> 3 data = image.constBits().asstring(bytes_per_line * h) return self.write_image(data, w, h, d, cache_key=cache_key) has_alpha = False soft_mask = None if fmt == QImage.Format_ARGB32: tmask = image.constBits().asstring(4*w*h)[self.alpha_bit::4] sdata = bytearray(tmask) vals = set(sdata) vals.discard(255) # discard opaque pixels has_alpha = bool(vals) if has_alpha: # Blend image onto a white background as otherwise Qt will render # transparent pixels as black background = QImage(image.size(), QImage.Format_ARGB32_Premultiplied) background.fill(Qt.white) painter = QPainter(background) painter.drawImage(0, 0, image) painter.end() image = background ba = QByteArray() buf = QBuffer(ba) image.save(buf, 'jpeg', 94) data = bytes(ba.data()) if has_alpha: soft_mask = self.write_image(tmask, w, h, 8) return self.write_image(data, w, h, 32, dct=True, soft_mask=soft_mask, cache_key=cache_key)
def restore_state(self): try: geom = gprefs.get('jobs_dialog_geometry', bytearray('')) self.restoreGeometry(QByteArray(geom)) state = gprefs.get('jobs view column layout2', bytearray('')) self.jobs_view.horizontalHeader().restoreState(QByteArray(state)) except: pass idx = self.jobs_view.model().index(0, 0) if idx.isValid(): sm = self.jobs_view.selectionModel() sm.select(idx, sm.ClearAndSelect | sm.Rows)
def load_html(path, view, codec='utf-8', mime_type=None, pre_load_callback=lambda x: None, path_is_html=False): from PyQt4.Qt import QUrl, QByteArray if mime_type is None: mime_type = guess_type(path)[0] if path_is_html: html = path else: with open(path, 'rb') as f: html = f.read().decode(codec, 'replace') html = EntityDeclarationProcessor(html).processed_html has_svg = re.search(r'<[:a-zA-Z]*svg', html) is not None if 'xhtml' in mime_type: self_closing_pat = re.compile(r'<([a-z1-6]+)\s+([^>]+)/>', re.IGNORECASE) html = self_closing_pat.sub(self_closing_sub, html) html = re.sub(ur'<\s*title\s*/\s*>', u'', html, flags=re.IGNORECASE) loading_url = QUrl.fromLocalFile(path) pre_load_callback(loading_url) if has_svg: view.setContent(QByteArray(html.encode(codec)), mime_type, loading_url) else: view.setHtml(html, loading_url)
def load_html(path, view, codec='utf-8', mime_type=None, pre_load_callback=lambda x:None, path_is_html=False, force_as_html=False): from PyQt4.Qt import QUrl, QByteArray if mime_type is None: mime_type = guess_type(path)[0] if not mime_type: mime_type = 'text/html' if path_is_html: html = path else: with open(path, 'rb') as f: html = f.read().decode(codec, 'replace') html = EntityDeclarationProcessor(html).processed_html self_closing_pat = re.compile(r'<\s*([:A-Za-z0-9-]+)([^>]*)/\s*>') html = self_closing_pat.sub(self_closing_sub, html) loading_url = QUrl.fromLocalFile(path) pre_load_callback(loading_url) if force_as_html or re.search(r'<[a-zA-Z0-9-]+:svg', html) is None: view.setHtml(html, loading_url) else: view.setContent(QByteArray(html.encode(codec)), mime_type, loading_url) mf = view.page().mainFrame() elem = mf.findFirstElement('parsererror') if not elem.isNull(): return False return True
def __init__(self, db, book_id, regex, doc=None, parent=None): QDialog.__init__(self, parent) self.setupUi(self) self.regex.setText(regex) self.regex_valid() if not db or not book_id: button = self.button_box.addButton(QDialogButtonBox.Open) button.clicked.connect(self.open_clicked) elif not doc and not self.select_format(db, book_id): self.cancelled = True return if doc: self.preview.setPlainText(doc) self.cancelled = False self.button_box.accepted.connect(self.accept) self.regex.textChanged[str].connect(self.regex_valid) for src, slot in (('test', 'do'), ('previous', 'goto'), ('next', 'goto')): getattr(self, src).clicked.connect(getattr(self, '%s_%s' % (slot, src))) self.test.setDefault(True) self.match_locs = [] geom = gprefs.get('regex_builder_geometry', None) if geom is not None: self.restoreGeometry(QByteArray(geom)) self.finished.connect(self.save_state)
def loadConfig(cls): Config = cls.Config for name in ("window", "shell"): Config["%swidth" % name] = QVariant( QApplication.desktop().availableGeometry().width() / 2).toInt()[0] Config["%sheight" % name] = QVariant( QApplication.desktop().availableGeometry().height() / 2).toInt()[0] Config["%sy" % name] = QVariant(0).toInt()[0] Config["toolbars"] = QByteArray(b'') Config["splitter"] = QByteArray(b'') Config["shellx"] = QVariant(0).toInt()[0] Config["windowx"] = QVariant( QApplication.desktop().availableGeometry().width() / 2).toInt()[0] Config["remembergeometry"] = QVariant(True).toBool() Config["startwithshell"] = QVariant(True).toBool() Config["showwindowinfo"] = QVariant(True).toBool() Config["backupsuffix"] = QVariant(".bak").toString() Config["cwd"] = QVariant(".").toString() Config["tooltipsize"] = QVariant(150).toInt()[0] Config["maxlinestoscan"] = QVariant(5000).toInt()[0] Config["pythondocpath"] = QVariant("http://docs.python.org").toString() Config["autohidefinddialog"] = QVariant(True).toBool() Config["findcasesensitive"] = QVariant(False).toBool() Config["findwholewords"] = QVariant(False).toBool() Config["tabwidth"] = QVariant(4).toInt()[0] Config["fontfamily"] = QVariant("monospace").toString() Config["fontsize"] = QVariant(10).toInt()[0] for name, color, bold, italic in (("normal", "#000000", False, False), ("keyword", "#000080", True, False), ("builtin", "#0000A0", False, False), ("constant", "#0000C0", False, False), ("decorator", "#0000E0", False, False), ("comment", "#007F00", False, True), ("string", "#808000", False, False), ("number", "#924900", False, False), ("error", "#FF0000", False, False), ("pyqt", "#50621A", False, False)): Config["%sfontcolor" % name] = QVariant(color).toString() Config["%sfontbold" % name] = QVariant(bold).toBool() Config["%sfontitalic" % name] = QVariant(italic).toBool()
def to_png(bmp): # ImageMagick does not convert some bmp files correctly, while Qt does, # so try Qt first. See for instance: # https://bugs.launchpad.net/calibre/+bug/934167 # ImageMagick bug report: # http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=20350 from PyQt4.Qt import QImage, QByteArray, QBuffer i = QImage() if i.loadFromData(bmp): ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) i.save(buf, 'png') return bytes(ba.data()) from calibre.utils.magick import Image img = Image() img.load(bmp) return img.export('png')
def to_png(bmp): # ImageMagick does not convert some bmp files correctly, while Qt does, # so try Qt first. See for instance: # https://bugs.launchpad.net/calibre/+bug/934167 # ImageMagick bug report: # http://www.imagemagick.org/discourse-server/viewtopic.php?f=3&t=20350 from PyQt4.Qt import QImage, QByteArray, QBuffer i = QImage() if i.loadFromData(bmp): ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) i.save(buf, "png") return bytes(ba.data()) from calibre.utils.magick import Image img = Image() img.load(bmp) return img.export("png")
def mimeData(self, indices): mimeData = QMimeData() encodedData = QByteArray() stream = QDataStream(encodedData, QIODevice.WriteOnly) for index in indices: if index.column() == 1: d = QVariant(self.data(index, Qt.DecorationRole)) else: d = QVariant(self.data(index, Qt.DisplayRole).toString()) stream << d mimeData.setData('application/target.tableitem.creepy', encodedData) return mimeData
def restore_state(self): state = vprefs.get('viewer_toolbar_state', None) if state is not None: try: state = QByteArray(state) self.restoreState(state, self.STATE_VERSION) except: pass mult = vprefs.get('multiplier', None) if mult: self.view.multiplier = mult # On windows Qt lets the user hide toolbars via a right click in a very # specific location, ensure they are visible. self.tool_bar.setVisible(True) self.tool_bar2.setVisible(True)
def magick_to_qimage(img): fmt = get_pixel_map() # ImageMagick can output only output raw data in some formats that can be # read into QImage directly, if the QImage format is not one of those, use # PNG if fmt in {'RGBA', 'BGRA'}: w, h = img.size img.depth = 8 # QImage expects 8bpp raw = img.export(fmt) i = QImage(raw, w, h, QImage.Format_ARGB32) del raw # According to the documentation, raw is supposed to not be deleted, but it works, so make it explicit return i else: raw = img.export('PNG') return QImage.fromData(QByteArray(raw), 'PNG')
class QtCompressor(object): def __init__(self, fileName): # fileName = os.path.splitext(fileName)[0] + ".qz" self.fileName = fileName self.byteArray = QByteArray() def toHexStr(self, i): s = hex(i) k = 10 - len(s) return s[0:2] + "0"*k + s[2:] def write(self, src, arcName): g = open(src, "rb") data = g.read() g.close() self.byteArray.append(self.toHexStr(len(arcName))) self.byteArray.append(arcName) self.byteArray.append(self.toHexStr(len(data))) self.byteArray.append(data) def close(self): f = open(self.fileName, "wb") # don't use compression, because resource files are compressed by Qt anyway data = self.byteArray.data() #data = qCompress(self.byteArray, 9).data() f.write(data) f.close()
def _save(self): self.checkPrice self.itemName=self.window.le_ItemName.text() if self.itemName=="" or self.itemPrice==0 or self.itemIcon is None: message=u"Не все данные указаны" self._showMessage(u'Ошибка', message) self.window.btn_Save.setEnabled(False) return blobImg=QByteArray() buff=QBuffer(blobImg) buff.open(QBuffer.WriteOnly) self.itemIcon.save(buff, "JPG") if self.typeOperation=='Add': self.addItem(blobImg) elif self.typeOperation=='Edit': self.editItem(blobImg) self.window.close() self.emit(QtCore.SIGNAL("RefreshItemTable"))
def __init__(self, parent, cover_flow): QDialog.__init__(self, parent) self._layout = QStackedLayout() self.setLayout(self._layout) self.setWindowTitle(_('Browse by covers')) self.layout().addWidget(cover_flow) geom = gprefs.get('cover_browser_dialog_geometry', bytearray('')) geom = QByteArray(geom) if not self.restoreGeometry(geom): h, w = available_height() - 60, int(available_width() / 1.5) self.resize(w, h) self.action_fs_toggle = a = QAction(self) self.addAction(a) a.setShortcuts([ QKeySequence('F11', QKeySequence.PortableText), QKeySequence('Ctrl+Shift+F', QKeySequence.PortableText) ]) a.triggered.connect(self.toggle_fullscreen) self.action_esc_fs = a = QAction(self) a.triggered.connect(self.show_normal) self.addAction(a) a.setShortcuts([QKeySequence('Esc', QKeySequence.PortableText)]) self.pre_fs_geom = None cover_flow.setFocus(Qt.OtherFocusReason) self.view_action = a = QAction(self) iactions = parent.iactions self.addAction(a) a.setShortcuts( list(iactions['View'].menuless_qaction.shortcuts()) + [QKeySequence(Qt.Key_Space)]) a.triggered.connect(iactions['View'].menuless_qaction.trigger) self.sd_action = a = QAction(self) self.addAction(a) a.setShortcuts( list(iactions['Send To Device'].menuless_qaction.shortcuts())) a.triggered.connect( iactions['Send To Device'].menuless_qaction.trigger)
def _repr_png_(self): self._widget.hide() QtGui.QApplication.processEvents() try: self.image = QImage(self._widget.viewRect().size().toSize(), QImage.Format_RGB32) except AttributeError: self._widget.updateGL() self.image = self._widget.grabFrameBuffer() painter = QPainter(self.image) self._widget.render(painter) byte_array = QByteArray() buffer = QBuffer(byte_array) buffer.open(QIODevice.ReadWrite) self.image.save(buffer, 'PNG') buffer.close() return bytes(byte_array)
def add_image(self, img, cache_key): ref = self.get_image(cache_key) if ref is not None: return ref fmt = img.format() image = QImage(img) if (image.depth() == 1 and img.colorTable().size() == 2 and img.colorTable().at(0) == QColor(Qt.black).rgba() and img.colorTable().at(1) == QColor(Qt.white).rgba()): if fmt == QImage.Format_MonoLSB: image = image.convertToFormat(QImage.Format_Mono) fmt = QImage.Format_Mono else: if (fmt != QImage.Format_RGB32 and fmt != QImage.Format_ARGB32): image = image.convertToFormat(QImage.Format_ARGB32) fmt = QImage.Format_ARGB32 w = image.width() h = image.height() d = image.depth() if fmt == QImage.Format_Mono: bytes_per_line = (w + 7) >> 3 data = image.constBits().asstring(bytes_per_line * h) return self.write_image(data, w, h, d, cache_key=cache_key) ba = QByteArray() buf = QBuffer(ba) image.save(buf, 'jpeg', 94) data = bytes(ba.data()) has_alpha = has_mask = False soft_mask = mask = None if fmt == QImage.Format_ARGB32: tmask = image.constBits().asstring(4*w*h)[self.alpha_bit::4] sdata = bytearray(tmask) vals = set(sdata) vals.discard(255) has_mask = bool(vals) vals.discard(0) has_alpha = bool(vals) if has_alpha: soft_mask = self.write_image(tmask, w, h, 8) elif has_mask: # dither the soft mask to 1bit and add it. This also helps PDF # viewers without transparency support bytes_per_line = (w + 7) >> 3 mdata = bytearray(0 for i in xrange(bytes_per_line * h)) spos = mpos = 0 for y in xrange(h): for x in xrange(w): if sdata[spos]: mdata[mpos + x>>3] |= (0x80 >> (x&7)) spos += 1 mpos += bytes_per_line mdata = bytes(mdata) mask = self.write_image(mdata, w, h, 1) return self.write_image(data, w, h, 32, mask=mask, dct=True, soft_mask=soft_mask, cache_key=cache_key)
def __init__(self, parent, db, id_to_select, select_sort, select_link): QDialog.__init__(self, parent) Ui_EditAuthorsDialog.__init__(self) self.setupUi(self) # Remove help icon on title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags() & (~Qt.WindowContextHelpButtonHint)) self.setWindowIcon(icon) try: self.table_column_widths = \ gprefs.get('manage_authors_table_widths', None) geom = gprefs.get('manage_authors_dialog_geometry', bytearray('')) self.restoreGeometry(QByteArray(geom)) except: pass self.buttonBox.accepted.connect(self.accepted) # Set up the column headings self.table.setSelectionMode(QAbstractItemView.SingleSelection) self.table.setColumnCount(3) self.down_arrow_icon = QIcon(I('arrow-down.png')) self.up_arrow_icon = QIcon(I('arrow-up.png')) self.blank_icon = QIcon(I('blank.png')) self.auth_col = QTableWidgetItem(_('Author')) self.table.setHorizontalHeaderItem(0, self.auth_col) self.auth_col.setIcon(self.blank_icon) self.aus_col = QTableWidgetItem(_('Author sort')) self.table.setHorizontalHeaderItem(1, self.aus_col) self.aus_col.setIcon(self.up_arrow_icon) self.aul_col = QTableWidgetItem(_('Link')) self.table.setHorizontalHeaderItem(2, self.aul_col) self.aus_col.setIcon(self.blank_icon) # Add the data self.authors = {} auts = db.get_authors_with_ids() self.table.setRowCount(len(auts)) select_item = None for row, (id, author, sort, link) in enumerate(auts): author = author.replace('|', ',') self.authors[id] = (author, sort, link) aut = tableItem(author) aut.setData(Qt.UserRole, id) sort = tableItem(sort) link = tableItem(link) self.table.setItem(row, 0, aut) self.table.setItem(row, 1, sort) self.table.setItem(row, 2, link) if id == id_to_select: if select_sort: select_item = sort elif select_link: select_item = link else: select_item = aut self.table.resizeColumnsToContents() if self.table.columnWidth(2) < 200: self.table.setColumnWidth(2, 200) # set up the cellChanged signal only after the table is filled self.table.cellChanged.connect(self.cell_changed) # set up sort buttons self.sort_by_author.setCheckable(True) self.sort_by_author.setChecked(False) self.sort_by_author.clicked.connect(self.do_sort_by_author) self.author_order = 1 self.table.sortByColumn(1, Qt.AscendingOrder) self.sort_by_author_sort.clicked.connect(self.do_sort_by_author_sort) self.sort_by_author_sort.setCheckable(True) self.sort_by_author_sort.setChecked(True) self.author_sort_order = 1 self.recalc_author_sort.clicked.connect(self.do_recalc_author_sort) self.auth_sort_to_author.clicked.connect(self.do_auth_sort_to_author) # Position on the desired item if select_item is not None: self.table.setCurrentItem(select_item) self.table.editItem(select_item) self.start_find_pos = select_item.row() * 2 + select_item.column() else: self.table.setCurrentCell(0, 0) self.start_find_pos = -1 # set up the search box self.find_box.initialize('manage_authors_search') self.find_box.lineEdit().returnPressed.connect(self.do_find) self.find_box.editTextChanged.connect(self.find_text_changed) self.find_button.clicked.connect(self.do_find) l = QLabel(self.table) self.not_found_label = l l.setFrameStyle(QFrame.StyledPanel) l.setAutoFillBackground(True) l.setText(_('No matches found')) l.setAlignment(Qt.AlignVCenter) l.resize(l.sizeHint()) l.move(10, 20) l.setVisible(False) self.not_found_label.move(40, 40) self.not_found_label_timer = QTimer() self.not_found_label_timer.setSingleShot(True) self.not_found_label_timer.timeout.connect( self.not_found_label_timer_event, type=Qt.QueuedConnection) self.table.setContextMenuPolicy(Qt.CustomContextMenu) self.table.customContextMenuRequested.connect(self.show_context_menu)
def __init__(self, window, cat_name, tag_to_match, data, sorter): QDialog.__init__(self, window) Ui_TagListEditor.__init__(self) self.setupUi(self) # Put the category name into the title bar t = self.windowTitle() self.setWindowTitle(t + ' (' + cat_name + ')') # Remove help icon on title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags()&(~Qt.WindowContextHelpButtonHint)) self.setWindowIcon(icon) # Get saved geometry info try: self.table_column_widths = \ gprefs.get('tag_list_editor_table_widths', None) except: pass # initialization self.to_rename = {} self.to_delete = set([]) self.original_names = {} self.all_tags = {} self.counts = {} for k,v,count in data: self.all_tags[v] = k self.counts[v] = count self.original_names[k] = v # Set up the column headings self.down_arrow_icon = QIcon(I('arrow-down.png')) self.up_arrow_icon = QIcon(I('arrow-up.png')) self.blank_icon = QIcon(I('blank.png')) self.table.setColumnCount(3) self.name_col = QTableWidgetItem(_('Tag')) self.table.setHorizontalHeaderItem(0, self.name_col) self.name_col.setIcon(self.up_arrow_icon) self.count_col = QTableWidgetItem(_('Count')) self.table.setHorizontalHeaderItem(1, self.count_col) self.count_col.setIcon(self.blank_icon) self.was_col = QTableWidgetItem(_('Was')) self.table.setHorizontalHeaderItem(2, self.was_col) self.count_col.setIcon(self.blank_icon) # Capture clicks on the horizontal header to sort the table columns hh = self.table.horizontalHeader(); hh.setClickable(True) hh.sectionClicked.connect(self.header_clicked) hh.sectionResized.connect(self.table_column_resized) self.name_order = 0 self.count_order = 1 self.was_order = 1 # Add the data select_item = None self.table.setRowCount(len(self.all_tags)) for row,tag in enumerate(sorted(self.all_tags.keys(), key=sorter)): item = NameTableWidgetItem(tag) item.setData(Qt.UserRole, self.all_tags[tag]) item.setFlags (item.flags() | Qt.ItemIsSelectable | Qt.ItemIsEditable) self.table.setItem(row, 0, item) if tag == tag_to_match: select_item = item item = CountTableWidgetItem(self.counts[tag]) # only the name column can be selected item.setFlags (item.flags() & ~(Qt.ItemIsSelectable|Qt.ItemIsEditable)) self.table.setItem(row, 1, item) item = QTableWidgetItem('') item.setFlags (item.flags() & ~(Qt.ItemIsSelectable|Qt.ItemIsEditable)) self.table.setItem(row, 2, item) # Scroll to the selected item if there is one if select_item is not None: self.table.setCurrentItem(select_item) self.delete_button.clicked.connect(self.delete_tags) self.rename_button.clicked.connect(self.rename_tag) self.table.itemDoubleClicked.connect(self._rename_tag) self.table.itemChanged.connect(self.finish_editing) self.buttonBox.accepted.connect(self.accepted) self.search_box.initialize('tag_list_search_box_' + cat_name) self.search_button.clicked.connect(self.search_clicked) try: geom = gprefs.get('tag_list_editor_dialog_geometry', None) if geom is not None: self.restoreGeometry(QByteArray(geom)) else: self.resize(self.sizeHint()+QSize(150, 100)) except: pass
def __init__(self, fileName): # fileName = os.path.splitext(fileName)[0] + ".qz" self.fileName = fileName self.byteArray = QByteArray()
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.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 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(0, t) t = QTableWidgetItem(_('Authors')) self.books_table.setHorizontalHeaderItem(1, t) t = QTableWidgetItem(_('Series')) self.books_table.setHorizontalHeaderItem(2, t) self.books_table_header_height = self.books_table.height() self.books_table.cellDoubleClicked.connect(self.book_doubleclicked) 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) 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)
def __init__(self, gui, view, id_): QDialog.__init__(self, gui, flags=Qt.Window) Ui_MatchBooks.__init__(self) self.setupUi(self) self.isClosed = False self.books_table_column_widths = None try: self.books_table_column_widths = \ gprefs.get('match_books_dialog_books_table_widths', None) geom = gprefs.get('match_books_dialog_geometry', bytearray('')) self.restoreGeometry(QByteArray(geom)) except: pass self.search_text.initialize('match_books_dialog') # Remove the help button from the window title bar icon = self.windowIcon() self.setWindowFlags(self.windowFlags() & (~Qt.WindowContextHelpButtonHint)) self.setWindowIcon(icon) self.device_db = view.model().db self.library_db = gui.library_view.model().db self.view = view self.gui = gui self.current_device_book_id = id_ self.current_library_book_id = None # 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(0, t) t = QTableWidgetItem(_('Authors')) self.books_table.setHorizontalHeaderItem(1, t) t = QTableWidgetItem(_('Series')) self.books_table.setHorizontalHeaderItem(2, t) self.books_table_header_height = self.books_table.height() self.books_table.cellDoubleClicked.connect(self.book_doubleclicked) self.books_table.cellClicked.connect(self.book_clicked) 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) self.search_button.clicked.connect(self.do_search) self.search_button.setDefault(False) self.search_text.lineEdit().returnPressed.connect(self.return_pressed) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.ignore_next_key = False self.search_text.setText( self.device_db[self.current_device_book_id].title)
def handle_embedded_fonts(self): ''' Because of QtWebKit's inability to handle embedded fonts correctly, we remove the embedded fonts and make them available system wide instead. If you ever move to Qt WebKit 2.3+ then this will be unnecessary. ''' from calibre.ebooks.oeb.base import urlnormalize from calibre.utils.fonts.utils import remove_embed_restriction from PyQt4.Qt import QFontDatabase, QByteArray, QRawFont, QFont # First find all @font-face rules and remove them, adding the embedded # fonts to Qt family_map = {} for item in list(self.oeb.manifest): if not hasattr(item.data, 'cssRules'): continue remove = set() for i, rule in enumerate(item.data.cssRules): if rule.type == rule.FONT_FACE_RULE: remove.add(i) try: s = rule.style src = s.getProperty('src').propertyValue[0].uri font_family = s.getProperty( 'font-family').propertyValue[0].value except: continue path = item.abshref(src) ff = self.oeb.manifest.hrefs.get(urlnormalize(path), None) if ff is None: continue raw = ff.data self.oeb.manifest.remove(ff) try: raw = remove_embed_restriction(raw) except: continue fid = QFontDatabase.addApplicationFontFromData( QByteArray(raw)) family_name = None if fid > -1: try: family_name = unicode( QFontDatabase.applicationFontFamilies(fid)[0]) except (IndexError, KeyError): pass if family_name: family_map[icu_lower(font_family)] = family_name for i in sorted(remove, reverse=True): item.data.cssRules.pop(i) # Now map the font family name specified in the css to the actual # family name of the embedded font (they may be different in general). font_warnings = set() for item in self.oeb.manifest: if not hasattr(item.data, 'cssRules'): continue for i, rule in enumerate(item.data.cssRules): if rule.type != rule.STYLE_RULE: continue ff = rule.style.getProperty('font-family') if ff is None: continue val = ff.propertyValue for i in xrange(val.length): try: k = icu_lower(val[i].value) except (AttributeError, TypeError): val[i].value = k = 'times' if k in family_map: val[i].value = family_map[k] if iswindows: # On windows, Qt uses GDI which does not support OpenType # (CFF) fonts, so we need to nuke references to OpenType # fonts. Note that you could compile QT with configure # -directwrite, but that requires atleast Vista SP2 for i in xrange(val.length): family = val[i].value if family: f = QRawFont.fromFont(QFont(family)) if len(f.fontTable('head')) == 0: if family not in font_warnings: self.log.warn( 'Ignoring unsupported font: %s' % family) font_warnings.add(family) # Either a bitmap or (more likely) a CFF font val[i].value = 'times'
def add_image(self, img, cache_key): ref = self.get_image(cache_key) if ref is not None: return ref fmt = img.format() image = QImage(img) if (image.depth() == 1 and img.colorTable().size() == 2 and img.colorTable().at(0) == QColor(Qt.black).rgba() and img.colorTable().at(1) == QColor(Qt.white).rgba()): if fmt == QImage.Format_MonoLSB: image = image.convertToFormat(QImage.Format_Mono) fmt = QImage.Format_Mono else: if (fmt != QImage.Format_RGB32 and fmt != QImage.Format_ARGB32): image = image.convertToFormat(QImage.Format_ARGB32) fmt = QImage.Format_ARGB32 w = image.width() h = image.height() d = image.depth() if fmt == QImage.Format_Mono: bytes_per_line = (w + 7) >> 3 data = image.constBits().asstring(bytes_per_line * h) return self.write_image(data, w, h, d, cache_key=cache_key) ba = QByteArray() buf = QBuffer(ba) image.save(buf, 'jpeg', 94) data = bytes(ba.data()) has_alpha = has_mask = False soft_mask = mask = None if fmt == QImage.Format_ARGB32: tmask = image.constBits().asstring(4 * w * h)[self.alpha_bit::4] sdata = bytearray(tmask) vals = set(sdata) vals.discard(255) has_mask = bool(vals) vals.discard(0) has_alpha = bool(vals) if has_alpha: soft_mask = self.write_image(tmask, w, h, 8) elif has_mask: # dither the soft mask to 1bit and add it. This also helps PDF # viewers without transparency support bytes_per_line = (w + 7) >> 3 mdata = bytearray(0 for i in xrange(bytes_per_line * h)) spos = mpos = 0 for y in xrange(h): for x in xrange(w): if sdata[spos]: mdata[mpos + x >> 3] |= (0x80 >> (x & 7)) spos += 1 mpos += bytes_per_line mdata = bytes(mdata) mask = self.write_image(mdata, w, h, 1) return self.write_image(data, w, h, 32, mask=mask, dct=True, soft_mask=soft_mask, cache_key=cache_key)