コード例 #1
0
ファイル: dnd.py プロジェクト: j-howell/calibre
def dnd_get_image(md, image_exts=None):
    '''
    Get the image in the QMimeData object md.

    :return: None, None if no image is found
             QPixmap, None if an image is found, the pixmap is guaranteed not null
             url, filename if a URL that points to an image is found
    '''
    if md.hasImage():
        for x in md.formats():
            x = unicode_type(x)
            if x.startswith('image/'):
                cdata = bytes(md.data(x))
                pmap = QPixmap()
                pmap.loadFromData(cdata)
                if not pmap.isNull():
                    return pmap, None
                break
    if md.hasFormat('application/octet-stream'):
        cdata = bytes(md.data('application/octet-stream'))
        pmap = QPixmap()
        pmap.loadFromData(cdata)
        if not pmap.isNull():
            return pmap, None

    if image_exts is None:
        image_exts = image_extensions()

    # No image, look for an URL pointing to an image
    urls = urls_from_md(md)
    paths = [path_from_qurl(u) for u in urls]
    # First look for a local file
    images = [xi for xi in paths if
            posixpath.splitext(unquote(xi))[1][1:].lower() in
            image_exts]
    images = [xi for xi in images if os.path.exists(xi)]
    p = QPixmap()
    for path in images:
        try:
            with open(path, 'rb') as f:
                p.loadFromData(f.read())
        except Exception:
            continue
        if not p.isNull():
            return p, None

    # No local images, look for remote ones

    # First, see if this is from Firefox
    rurl, fname = get_firefox_rurl(md, image_exts)

    if rurl and fname:
        return rurl, fname
    # Look through all remaining URLs
    for remote_url, filename in remote_urls_from_qurl(urls, image_exts):
        return remote_url, filename

    return None, None
コード例 #2
0
ファイル: widgets.py プロジェクト: GRiker/calibre
class CoverView(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.current_pixmap_size = QSize(0, 0)
        self.pixmap = QPixmap()
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    def set_pixmap(self, data):
        self.pixmap.loadFromData(data)
        self.current_pixmap_size = self.pixmap.size()
        self.update()

    def paintEvent(self, event):
        if self.pixmap.isNull():
            return
        canvas_size = self.rect()
        width = self.current_pixmap_size.width()
        extrax = canvas_size.width() - width
        if extrax < 0:
            extrax = 0
        x = int(extrax / 2.0)
        height = self.current_pixmap_size.height()
        extray = canvas_size.height() - height
        if extray < 0:
            extray = 0
        y = int(extray / 2.0)
        target = QRect(x, y, min(canvas_size.width(), width), min(canvas_size.height(), height))
        p = QPainter(self)
        p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
        p.drawPixmap(target, self.pixmap.scaled(target.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))
        p.end()

    def sizeHint(self):
        return QSize(300, 400)
コード例 #3
0
ファイル: metadata.py プロジェクト: BerZek/calibre
    def initialize_metadata_options(self):
        self.initialize_combos()
        self.author.editTextChanged.connect(self.deduce_author_sort)

        mi = self.db.get_metadata(self.book_id, index_is_id=True)
        self.title.setText(mi.title)
        self.publisher.show_initial_value(mi.publisher if mi.publisher else '')
        self.author_sort.setText(mi.author_sort if mi.author_sort else '')
        self.tags.setText(', '.join(mi.tags if mi.tags else []))
        self.tags.update_items_cache(self.db.all_tags())
        self.comment.html = comments_to_html(mi.comments) if mi.comments else ''
        self.series.show_initial_value(mi.series if mi.series else '')
        if mi.series_index is not None:
            try:
                self.series_index.setValue(mi.series_index)
            except:
                self.series_index.setValue(1.0)

        cover = self.db.cover(self.book_id, index_is_id=True)
        if cover:
            pm = QPixmap()
            pm.loadFromData(cover)
            if not pm.isNull():
                self.cover.setPixmap(pm)
                self.cover_data = cover
                self.set_cover_tooltip(pm)
        else:
            self.cover.setPixmap(QPixmap(I('default_cover.png')))
            self.cover.setToolTip(_('This book has no cover'))
        for x in ('author', 'series', 'publisher'):
            x = getattr(self, x)
            x.lineEdit().deselect()
コード例 #4
0
ファイル: metadata.py プロジェクト: BerZek/calibre
 def select_cover(self):
     files = choose_images(self, 'change cover dialog',
                          _('Choose cover for ') + unicode(self.title.text()))
     if not files:
         return
     _file = files[0]
     if _file:
         _file = os.path.abspath(_file)
         if not os.access(_file, os.R_OK):
             d = error_dialog(self.parent(), _('Cannot read'),
                     _('You do not have permission to read the file: ') + _file)
             d.exec_()
             return
         cf, cover = None, None
         try:
             cf = open(_file, "rb")
             cover = cf.read()
         except IOError as e:
             d = error_dialog(self.parent(), _('Error reading file'),
                     _("<p>There was an error reading from file: <br /><b>") + _file + "</b></p><br />"+str(e))
             d.exec_()
         if cover:
             pix = QPixmap()
             pix.loadFromData(cover)
             if pix.isNull():
                 d = error_dialog(self.parent(), _('Error reading file'),
                                   _file + _(" is not a valid picture"))
                 d.exec_()
             else:
                 self.cover_path.setText(_file)
                 self.set_cover_tooltip(pix)
                 self.cover.setPixmap(pix)
                 self.cover_changed = True
                 self.cpixmap = pix
                 self.cover_data = cover
コード例 #5
0
ファイル: view.py プロジェクト: MarioJC/calibre
 def load(data):
     p = QPixmap()
     p.loadFromData(bytes(data))
     try:
         dpr = self.devicePixelRatioF()
     except AttributeError:
         dpr = self.devicePixelRatio()
     p.setDevicePixelRatio(dpr)
     if data and p.isNull():
         p = self.failed_img
     return p
コード例 #6
0
 def __init__(self, parent, collection, item):
     QWidget.__init__(self, parent)
     self.setupUi(self)
     self.parent = parent
     self.item = item
     self.collection = collection
     self.header.setText(collection.title)
     self.description.setText(collection.description)
     icon = QPixmap(":/gui/pics/%s" % collection.icon)
     if icon.isNull():
         icon = QPixmap(":/gui/pics/systemsettings.png")
     self.icon.setPixmap(icon)
コード例 #7
0
ファイル: open.py プロジェクト: kovidgoyal/vise
 def icon(self):
     if self._icon is None:
         self._icon = QIcon()
         url = places.favicon_url(self.place_id)
         if url is not None:
             f = QApplication.instance().disk_cache.data(QUrl(url))
             if f is not None:
                 with closing(f):
                     raw = f.readAll()
                 p = QPixmap()
                 p.loadFromData(raw)
                 if not p.isNull():
                     self._icon.addPixmap(p)
     return self._icon
コード例 #8
0
ファイル: diff.py プロジェクト: davidfor/calibre
 def from_mi(self, mi):
     p = getattr(mi, 'cover', None)
     if p and os.path.exists(p):
         pmap = QPixmap()
         with open(p, 'rb') as f:
             pmap.loadFromData(f.read())
         if not pmap.isNull():
             self.pixmap = pmap
             self.update()
             self.changed.emit()
             return
     cd = getattr(mi, 'cover_data', (None, None))
     if cd and cd[1]:
         pmap = QPixmap()
         pmap.loadFromData(cd[1])
         if not pmap.isNull():
             self.pixmap = pmap
             self.update()
             self.changed.emit()
             return
     self.pixmap = None
     self.update()
     self.changed.emit()
コード例 #9
0
ファイル: book_details.py プロジェクト: Farb/calibre
 def update_cover(self, pmap=None, cdata=None):
     if pmap is None:
         pmap = QPixmap()
         pmap.loadFromData(cdata)
     if pmap.isNull():
         return
     self.pixmap = pmap
     self.do_layout()
     self.update()
     self.update_tooltip(getattr(self.parent(), 'current_path', ''))
     if not config['disable_animations']:
         self.animation.start()
     id_ = self.data.get('id', None)
     if id_ is not None:
         self.cover_changed.emit(id_, cdata or pixmap_to_data(pmap))
コード例 #10
0
ファイル: windows.py プロジェクト: artbycrunk/calibre
def read_icon(handle, icon):
    must_use_qt()
    resource = win32api.LoadResource(handle, win32con.RT_ICON, icon.id)
    pixmap = QPixmap()
    pixmap.loadFromData(resource)
    hicon = None
    if pixmap.isNull():
        if icon.width > 0 and icon.height > 0:
            hicon = ctypes.windll.user32.CreateIconFromResourceEx(
                resource, len(resource), True, 0x00030000, icon.width, icon.height, win32con.LR_DEFAULTCOLOR)
        else:
            hicon = win32gui.CreateIconFromResource(resource, True)
        pixmap = hicon_to_pixmap(hicon).copy()
        win32gui.DestroyIcon(hicon)
    return pixmap
コード例 #11
0
ファイル: single_download.py プロジェクト: j-howell/calibre
 def update_result(self, plugin_name, width, height, data):
     if plugin_name.endswith("}"):
         # multi cover plugin
         plugin_name = plugin_name.partition("{")[0]
         plugin = [plugin for plugin in self.plugin_map if plugin.name == plugin_name]
         if not plugin:
             return
         plugin = plugin[0]
         last_row = max(self.plugin_map[plugin])
         pmap = QPixmap()
         pmap.loadFromData(data)
         if pmap.isNull():
             return
         self.beginInsertRows(QModelIndex(), last_row, last_row)
         for rows in self.plugin_map.itervalues():
             for i in xrange(len(rows)):
                 if rows[i] >= last_row:
                     rows[i] += 1
         self.plugin_map[plugin].insert(-1, last_row)
         self.covers.insert(last_row, self.get_item(plugin_name, pmap, waiting=False))
         self.endInsertRows()
     else:
         # single cover plugin
         idx = None
         for plugin, rows in self.plugin_map.iteritems():
             if plugin.name == plugin_name:
                 idx = rows[0]
                 break
         if idx is None:
             return
         pmap = QPixmap()
         pmap.loadFromData(data)
         if pmap.isNull():
             return
         self.covers[idx] = self.get_item(plugin_name, pmap, waiting=False)
         self.dataChanged.emit(self.index(idx), self.index(idx))
コード例 #12
0
ファイル: profil_view.py プロジェクト: cyril711/git-MythicWar
 def onSelectionChange (self):
     warrior = self.model.selectedWarrior[self.model.first_selected]
     p = QPixmap(warrior.attribs['picture'])
     diff_V = p.height()/self.picture.height()
     diff_H = p.width()/self.picture.width()
     if not p.isNull():
         if diff_V < diff_H:
             p = p.scaledToHeight(self.picture.height())
         else:
             p = p.scaledToWidth(self.picture.width())
     self.picture.setPixmap(p)
     self.Title.setText(warrior.name)
     self.faction_name.setText(warrior.faction().name)
     self.empire_name.setText(warrior.empire().name)
     self.royaume_name.setText(warrior.kingdom().name)
     self.groupe_name.setText(warrior.groupe().name)
コード例 #13
0
ファイル: writer.py プロジェクト: amorphous1/calibre
 def insert_cover(self):
     if not isinstance(self.cover_data, bytes):
         return
     item_path = os.path.join(self.tmp_path, 'cover.pdf')
     printer = get_pdf_printer(self.opts, output_file_name=item_path,
             for_comic=True)
     self.combine_queue.insert(0, item_path)
     p = QPixmap()
     p.loadFromData(self.cover_data)
     if not p.isNull():
         painter = QPainter(printer)
         draw_image_page(printer, painter, p,
                 preserve_aspect_ratio=self.opts.preserve_cover_aspect_ratio)
         painter.end()
         self.append_doc(item_path)
     printer.abort()
コード例 #14
0
ファイル: alternate_views.py プロジェクト: GRiker/calibre
 def cached_emblem(self, cache, name, raw_icon=None):
     ans = cache.get(name, False)
     if ans is not False:
         return ans
     sz = self.emblem_size
     ans = None
     if raw_icon is not None:
         ans = raw_icon.pixmap(sz, sz)
     elif name == ':ondevice':
         ans = QPixmap(I('ok.png')).scaled(sz, sz, transformMode=Qt.SmoothTransformation)
     elif name:
         pmap = QPixmap(os.path.join(config_dir, 'cc_icons', name))
         if not pmap.isNull():
             ans = pmap.scaled(sz, sz)
     cache[name] = ans
     return ans
コード例 #15
0
ファイル: alternate_views.py プロジェクト: JimmXinu/calibre
 def set_color(self):
     r, g, b = gprefs['cover_grid_color']
     pal = QPalette()
     col = QColor(r, g, b)
     pal.setColor(pal.Base, col)
     tex = gprefs['cover_grid_texture']
     if tex:
         from calibre.gui2.preferences.texture_chooser import texture_path
         path = texture_path(tex)
         if path:
             pm = QPixmap(path)
             if not pm.isNull():
                 val = pm.scaled(1, 1).toImage().pixel(0, 0)
                 r, g, b = qRed(val), qGreen(val), qBlue(val)
                 pal.setBrush(pal.Base, QBrush(pm))
     dark = (r + g + b)/3.0 < 128
     pal.setColor(pal.Text, QColor(Qt.white if dark else Qt.black))
     self.setPalette(pal)
     self.delegate.highlight_color = pal.color(pal.Text)
コード例 #16
0
ファイル: writer.py プロジェクト: amorphous1/calibre
    def render_images(self, outpath, mi, items):
        printer = get_pdf_printer(self.opts, for_comic=True,
                output_file_name=outpath)
        printer.setDocName(mi.title)

        painter = QPainter(printer)
        painter.setRenderHints(QPainter.Antialiasing|QPainter.SmoothPixmapTransform)

        for i, imgpath in enumerate(items):
            self.log('Rendering image:', i)
            p = QPixmap()
            p.load(imgpath)
            if not p.isNull():
                if i > 0:
                    printer.newPage()
                draw_image_page(printer, painter, p)
            else:
                self.log.warn('Failed to load image', i)
        painter.end()
コード例 #17
0
ファイル: model.py プロジェクト: JimmXinu/calibre
 def data(self, role):
     if role == Qt.DisplayRole:
         return (self.title)
     if role == Qt.DecorationRole:
         if self.icon is None:
             icon = '%s.png'%self.urn[8:]
             p = QPixmap()
             if icon in self.favicons:
                 try:
                     with zipfile.ZipFile(self.zf, 'r') as zf:
                         p.loadFromData(zf.read(self.favicons[icon]))
                 except:
                     pass
             if not p.isNull():
                 self.icon = (QIcon(p))
             else:
                 self.icon = self.default_icon
         return self.icon
     return None
コード例 #18
0
ファイル: add.py プロジェクト: MarioJC/calibre
 def files_dropped_on_book(self, event, paths, cid=None, do_confirm=True):
     accept = False
     if self.gui.current_view() is not self.gui.library_view:
         return
     db = self.gui.library_view.model().db
     cover_changed = False
     current_idx = self.gui.library_view.currentIndex()
     if cid is None:
         if not current_idx.isValid():
             return
         cid = db.id(current_idx.row()) if cid is None else cid
     formats = []
     from calibre.gui2.dnd import image_extensions
     image_exts = set(image_extensions()) - set(tweaks['cover_drop_exclude'])
     for path in paths:
         ext = os.path.splitext(path)[1].lower()
         if ext:
             ext = ext[1:]
         if ext in image_exts:
             pmap = QPixmap()
             pmap.load(path)
             if not pmap.isNull():
                 accept = True
                 db.set_cover(cid, pmap)
                 cover_changed = True
         else:
             formats.append((ext, path))
             accept = True
     if accept and event is not None:
         event.accept()
     if do_confirm and formats:
         if not confirm(
             _('You have dropped some files onto the book <b>%s</b>. This will'
               ' add or replace the files for this book. Do you want to proceed?') % db.title(cid, index_is_id=True),
             'confirm_drop_on_book', parent=self.gui):
             formats = []
     for ext, path in formats:
         db.add_format_with_hooks(cid, ext, path, index_is_id=True)
     if current_idx.isValid():
         self.gui.library_view.model().current_changed(current_idx, current_idx)
     if cover_changed:
         self.gui.refresh_cover_browser()
コード例 #19
0
 def data(self, role):
     if role == Qt.DisplayRole:
         return (self.title)
     if role == Qt.DecorationRole:
         if self.icon is None:
             icon = '%s.png'%self.urn[8:]
             p = QPixmap()
             if icon in self.favicons:
                 try:
                     with zipfile.ZipFile(self.zf, 'r') as zf:
                         p.loadFromData(zf.read(self.favicons[icon]))
                 except Exception:
                     pass
             if not p.isNull():
                 self.icon = (QIcon(p))
             else:
                 self.icon = self.default_icon
         return self.icon
     if role == Qt.UserRole:
         return self.urn
コード例 #20
0
class ImagePopup(object):

    def __init__(self, parent):
        self.current_img = QPixmap()
        self.current_url = QUrl()
        self.parent = parent
        self.dialogs = []

    def __call__(self):
        if self.current_img.isNull():
            return
        d = ImageView(self.parent, self.current_img, self.current_url)
        self.dialogs.append(d)
        d.finished.connect(self.cleanup, type=Qt.QueuedConnection)
        d()

    def cleanup(self):
        for d in tuple(self.dialogs):
            if not d.isVisible():
                self.dialogs.remove(d)
コード例 #21
0
ファイル: widgets.py プロジェクト: drxaero/calibre
    def dropEvent(self, event):
        event.setDropAction(Qt.CopyAction)
        md = event.mimeData()

        x, y = dnd_get_image(md)
        if x is not None:
            # We have an image, set cover
            event.accept()
            if y is None:
                # Local image
                self.handle_image_drop(x)
            else:
                # Remote files, use the first file
                d = DownloadDialog(x, y, self)
                d.start_download()
                if d.err is None:
                    pmap = QPixmap()
                    pmap.loadFromData(open(d.fpath, 'rb').read())
                    if not pmap.isNull():
                        self.handle_image_drop(pmap)
コード例 #22
0
ファイル: image_popup.py プロジェクト: pombreda/calibre-1
class ImagePopup(object):

    def __init__(self, parent):
        self.current_img = QPixmap()
        self.current_url = QUrl()
        self.parent = parent
        self.dialogs = []

    def __call__(self):
        if self.current_img.isNull():
            return
        d = ImageView(self.parent, self.current_img, self.current_url)
        self.dialogs.append(d)
        d.finished.connect(self.cleanup, type=Qt.QueuedConnection)
        d()

    def cleanup(self):
        for d in tuple(self.dialogs):
            if not d.isVisible():
                self.dialogs.remove(d)
コード例 #23
0
    def dropEvent(self, event):
        event.setDropAction(Qt.CopyAction)
        md = event.mimeData()

        x, y = dnd_get_image(md)
        if x is not None:
            # We have an image, set cover
            event.accept()
            if y is None:
                # Local image
                self.handle_image_drop(x)
            else:
                # Remote files, use the first file
                d = DownloadDialog(x, y, self)
                d.start_download()
                if d.err is None:
                    pmap = QPixmap()
                    pmap.loadFromData(open(d.fpath, 'rb').read())
                    if not pmap.isNull():
                        self.handle_image_drop(pmap)
コード例 #24
0
ファイル: writer.py プロジェクト: yunfile123/calibre
 def insert_cover(self):
     if not isinstance(self.cover_data, bytes):
         return
     item_path = os.path.join(self.tmp_path, 'cover.pdf')
     printer = get_pdf_printer(self.opts,
                               output_file_name=item_path,
                               for_comic=True)
     self.combine_queue.insert(0, item_path)
     p = QPixmap()
     p.loadFromData(self.cover_data)
     if not p.isNull():
         painter = QPainter(printer)
         draw_image_page(
             printer,
             painter,
             p,
             preserve_aspect_ratio=self.opts.preserve_cover_aspect_ratio)
         painter.end()
         self.append_doc(item_path)
     printer.abort()
コード例 #25
0
ファイル: widgets.py プロジェクト: ziyuyouming/calibre
class CoverView(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.current_pixmap_size = QSize(0, 0)
        self.pixmap = QPixmap()
        self.setSizePolicy(QSizePolicy.Policy.Expanding,
                           QSizePolicy.Policy.Expanding)

    def set_pixmap(self, data):
        self.pixmap.loadFromData(data)
        self.current_pixmap_size = self.pixmap.size()
        self.update()

    def paintEvent(self, event):
        if self.pixmap.isNull():
            return
        canvas_size = self.rect()
        width = self.current_pixmap_size.width()
        extrax = canvas_size.width() - width
        if extrax < 0:
            extrax = 0
        x = int(extrax / 2.)
        height = self.current_pixmap_size.height()
        extray = canvas_size.height() - height
        if extray < 0:
            extray = 0
        y = int(extray / 2.)
        target = QRect(x, y, min(canvas_size.width(), width),
                       min(canvas_size.height(), height))
        p = QPainter(self)
        p.setRenderHints(QPainter.RenderHint.Antialiasing
                         | QPainter.RenderHint.SmoothPixmapTransform)
        p.drawPixmap(
            target,
            self.pixmap.scaled(target.size(),
                               Qt.AspectRatioMode.KeepAspectRatio,
                               Qt.TransformationMode.SmoothTransformation))
        p.end()

    def sizeHint(self):
        return QSize(300, 400)
コード例 #26
0
ファイル: metadata.py プロジェクト: T30rGRB7/calibre-python3
 def select_cover(self):
     files = choose_images(self, 'change cover dialog',
                           _('Choose cover for ') + str(self.title.text()))
     if not files:
         return
     _file = files[0]
     if _file:
         _file = os.path.abspath(_file)
         if not os.access(_file, os.R_OK):
             d = error_dialog(
                 self.parent(), _('Cannot read'),
                 _('You do not have permission to read the file: ') + _file)
             d.exec_()
             return
         cf, cover = None, None
         try:
             cf = open(_file, "rb")
             cover = cf.read()
         except IOError as e:
             d = error_dialog(
                 self.parent(), _('Error reading file'),
                 _("<p>There was an error reading from file: <br /><b>") +
                 _file + "</b></p><br />" + str(e))
             d.exec_()
         if cover:
             pix = QPixmap()
             pix.loadFromData(cover)
             pix.setDevicePixelRatio(
                 getattr(self, 'devicePixelRatioF',
                         self.devicePixelRatio)())
             if pix.isNull():
                 d = error_dialog(self.parent(), _('Error reading file'),
                                  _file + _(" is not a valid picture"))
                 d.exec_()
             else:
                 self.cover_path.setText(_file)
                 self.set_cover_tooltip(pix)
                 self.cover.setPixmap(pix)
                 self.cover_changed = True
                 self.cpixmap = pix
                 self.cover_data = cover
コード例 #27
0
    def render_images(self, outpath, mi, items):
        printer = get_pdf_printer(self.opts,
                                  for_comic=True,
                                  output_file_name=outpath)
        printer.setDocName(mi.title)

        painter = QPainter(printer)
        painter.setRenderHints(QPainter.Antialiasing
                               | QPainter.SmoothPixmapTransform)

        for i, imgpath in enumerate(items):
            self.log('Rendering image:', i)
            p = QPixmap()
            p.load(imgpath)
            if not p.isNull():
                if i > 0:
                    printer.newPage()
                draw_image_page(printer, painter, p)
            else:
                self.log.warn('Failed to load image', i)
        painter.end()
コード例 #28
0
ファイル: metadata.py プロジェクト: T30rGRB7/calibre-python3
    def initialize_metadata_options(self):
        self.initialize_combos()
        self.author.editTextChanged.connect(self.deduce_author_sort)

        mi = self.db.get_metadata(self.book_id, index_is_id=True)
        self.title.setText(mi.title)
        self.publisher.show_initial_value(mi.publisher if mi.publisher else '')
        self.author_sort.setText(mi.author_sort if mi.author_sort else '')
        self.tags.setText(', '.join(mi.tags if mi.tags else []))
        self.tags.update_items_cache(self.db.all_tags())
        self.comment.html = comments_to_html(
            mi.comments) if mi.comments else ''
        self.series.show_initial_value(mi.series if mi.series else '')
        if mi.series_index is not None:
            try:
                self.series_index.setValue(mi.series_index)
            except:
                self.series_index.setValue(1.0)

        cover = self.db.cover(self.book_id, index_is_id=True)
        if cover:
            pm = QPixmap()
            pm.loadFromData(cover)
            if not pm.isNull():
                pm.setDevicePixelRatio(
                    getattr(self, 'devicePixelRatioF',
                            self.devicePixelRatio)())
                self.cover.setPixmap(pm)
                self.cover_data = cover
                self.set_cover_tooltip(pm)
        else:
            pm = QPixmap(I('default_cover.png'))
            pm.setDevicePixelRatio(
                getattr(self, 'devicePixelRatioF', self.devicePixelRatio)())
            self.cover.setPixmap(pm)
            self.cover.setToolTip(_('This book has no cover'))
        for x in ('author', 'series', 'publisher'):
            x = getattr(self, x)
            x.lineEdit().deselect()
        self.series_changed()
コード例 #29
0
 def set_color(self):
     r, g, b = gprefs['cover_grid_color']
     tex = gprefs['cover_grid_texture']
     pal = self.palette()
     pal.setColor(pal.Base, QColor(r, g, b))
     self.setPalette(pal)
     ss = ''
     if tex:
         from calibre.gui2.preferences.texture_chooser import texture_path
         path = texture_path(tex)
         if path:
             path = os.path.abspath(path).replace(os.sep, '/')
             ss += 'background-image: url({});'.format(path)
             ss += 'background-attachment: fixed;'
             pm = QPixmap(path)
             if not pm.isNull():
                 val = pm.scaled(1, 1).toImage().pixel(0, 0)
                 r, g, b = qRed(val), qGreen(val), qBlue(val)
     dark = max(r, g, b) < 115
     ss += 'color: {};'.format('white' if dark else 'black')
     self.delegate.highlight_color = QColor(Qt.white if dark else Qt.black)
     self.setStyleSheet('QListView {{ {} }}'.format(ss))
コード例 #30
0
ファイル: dnd.py プロジェクト: kba/calibre
def dnd_get_image(md, image_exts=IMAGE_EXTENSIONS):
    '''
    Get the image in the QMimeData object md.

    :return: None, None if no image is found
             QPixmap, None if an image is found, the pixmap is guaranteed not
             null
             url, filename if a URL that points to an image is found
    '''
    if dnd_has_image(md):
        for x in md.formats():
            x = unicode(x)
            if x.startswith('image/'):
                cdata = bytes(md.data(x))
                pmap = QPixmap()
                pmap.loadFromData(cdata)
                if not pmap.isNull():
                    return pmap, None
                break

    # No image, look for a URL pointing to an image
    if md.hasUrls():
        urls = [unicode(u.toString(QUrl.None)) for u in
                md.urls()]
コード例 #31
0
    def dump(self, items, out_stream, pdf_metadata):
        opts = self.opts
        page_size = get_page_size(self.opts)
        xdpi, ydpi = self.view.logicalDpiX(), self.view.logicalDpiY()

        def margin(which):
            val = getattr(opts, 'pdf_page_margin_' + which)
            if val == 0.0:
                val = getattr(opts, 'margin_' + which)
            return val

        ml, mr, mt, mb = map(margin, 'left right top bottom'.split())
        # We cannot set the side margins in the webview as there is no right
        # margin for the last page (the margins are implemented with
        # -webkit-column-gap)
        self.doc = PdfDevice(out_stream,
                             page_size=page_size,
                             left_margin=ml,
                             top_margin=0,
                             right_margin=mr,
                             bottom_margin=0,
                             xdpi=xdpi,
                             ydpi=ydpi,
                             errors=self.log.error,
                             debug=self.log.debug,
                             compress=not opts.uncompressed_pdf,
                             opts=opts,
                             mark_links=opts.pdf_mark_links,
                             page_margins=(ml, mr, mt, mb))
        self.footer = opts.pdf_footer_template
        if self.footer:
            self.footer = self.footer.strip()
        if not self.footer and opts.pdf_page_numbers:
            self.footer = '<p style="text-align:center; text-indent: 0">_PAGENUM_</p>'
        self.header = opts.pdf_header_template
        if self.header:
            self.header = self.header.strip()
        min_margin = 1.5 * opts._final_base_font_size
        if self.footer and mb < min_margin:
            self.log.warn(
                'Bottom margin is too small for footer, increasing it to %.1fpts'
                % min_margin)
            mb = min_margin
        if self.header and mt < min_margin:
            self.log.warn(
                'Top margin is too small for header, increasing it to %.1fpts'
                % min_margin)
            mt = min_margin

        self.page.setViewportSize(QSize(self.doc.width(), self.doc.height()))
        self.render_queue = items
        self.total_items = len(items)

        mt, mb = map(self.doc.to_px, (mt, mb))
        self.margin_top, self.margin_bottom = map(lambda x: int(floor(x)),
                                                  (mt, mb))

        self.painter = QPainter(self.doc)
        try:
            self.book_language = pdf_metadata.mi.languages[0]
        except Exception:
            self.book_language = 'eng'
        self.doc.set_metadata(title=pdf_metadata.title,
                              author=pdf_metadata.author,
                              tags=pdf_metadata.tags,
                              mi=pdf_metadata.mi)
        self.doc_title = pdf_metadata.title
        self.doc_author = pdf_metadata.author
        self.painter.save()
        try:
            if self.cover_data is not None:
                p = QPixmap()
                try:
                    p.loadFromData(self.cover_data)
                except TypeError:
                    self.log.warn(
                        'This ebook does not have a raster cover, cannot generate cover for PDF'
                        '. Cover type: %s' % type(self.cover_data))
                if not p.isNull():
                    self.doc.init_page()
                    draw_image_page(QRect(*self.doc.full_page_rect),
                                    self.painter,
                                    p,
                                    preserve_aspect_ratio=self.opts.
                                    preserve_cover_aspect_ratio)
                    self.doc.end_page()
        finally:
            self.painter.restore()

        QTimer.singleShot(0, self.render_book)
        if self.loop.exec_() == 1:
            raise Exception('PDF Output failed, see log for details')

        if self.toc is not None and len(self.toc) > 0:
            self.doc.add_outline(self.toc)

        self.painter.end()

        if self.doc.errors_occurred:
            raise Exception('PDF Output failed, see log for details')
コード例 #32
0
ファイル: widgets.py プロジェクト: drxaero/calibre
class ImageView(QWidget, ImageDropMixin):  # {{{

    BORDER_WIDTH = 1
    cover_changed = pyqtSignal(object)

    def __init__(self, parent=None, show_size_pref_name=None, default_show_size=False):
        QWidget.__init__(self, parent)
        self.show_size_pref_name = ('show_size_on_cover_' + show_size_pref_name) if show_size_pref_name else None
        self._pixmap = QPixmap()
        self.setMinimumSize(QSize(150, 200))
        ImageDropMixin.__init__(self)
        self.draw_border = True
        self.show_size = False
        if self.show_size_pref_name:
            self.show_size = gprefs.get(self.show_size_pref_name, default_show_size)

    def setPixmap(self, pixmap):
        if not isinstance(pixmap, QPixmap):
            raise TypeError('Must use a QPixmap')
        self._pixmap = pixmap
        self.updateGeometry()
        self.update()

    def build_context_menu(self):
        m = ImageDropMixin.build_context_menu(self)
        if self.show_size_pref_name:
            text = _('Hide size in corner') if self.show_size else _('Show size in corner')
            m.addAction(text, self.toggle_show_size)
        return m

    def toggle_show_size(self):
        self.show_size ^= True
        if self.show_size_pref_name:
            gprefs[self.show_size_pref_name] = self.show_size
        self.update()

    def pixmap(self):
        return self._pixmap

    def sizeHint(self):
        if self._pixmap.isNull():
            return self.minimumSize()
        return self._pixmap.size()

    def paintEvent(self, event):
        QWidget.paintEvent(self, event)
        pmap = self._pixmap
        if pmap.isNull():
            return
        w, h = pmap.width(), pmap.height()
        ow, oh = w, h
        cw, ch = self.rect().width(), self.rect().height()
        scaled, nw, nh = fit_image(w, h, cw, ch)
        if scaled:
            pmap = pmap.scaled(nw, nh, Qt.IgnoreAspectRatio,
                    Qt.SmoothTransformation)
        w, h = pmap.width(), pmap.height()
        x = int(abs(cw - w)/2.)
        y = int(abs(ch - h)/2.)
        target = QRect(x, y, w, h)
        p = QPainter(self)
        p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
        p.drawPixmap(target, pmap)
        if self.draw_border:
            pen = QPen()
            pen.setWidth(self.BORDER_WIDTH)
            p.setPen(pen)
            p.drawRect(target)
        if self.show_size:
            sztgt = target.adjusted(0, 0, 0, -4)
            f = p.font()
            f.setBold(True)
            p.setFont(f)
            sz = u'\u00a0%d x %d\u00a0'%(ow, oh)
            flags = Qt.AlignBottom|Qt.AlignRight|Qt.TextSingleLine
            szrect = p.boundingRect(sztgt, flags, sz)
            p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200))
            p.setPen(QPen(QColor(255,255,255)))
            p.drawText(sztgt, flags, sz)
        p.end()
コード例 #33
0
ファイル: reports.py プロジェクト: pombreda/calibre-1
 def pixmap(self, thumbnail_height, entry):
     pmap = QPixmap(current_container().name_to_abspath(entry.name)) if entry.width > 0 and entry.height > 0 else QPixmap()
     scaled, width, height = fit_image(entry.width, entry.height, thumbnail_height, thumbnail_height)
     if scaled and not pmap.isNull():
         pmap = pmap.scaled(width, height, transformMode=Qt.SmoothTransformation)
     return pmap
コード例 #34
0
class DesktopNotification(QWidget):
    def __init__(self, setPosition=False):
        super().__init__(None)
        self._ui = uic.loadUi('mc/notifications/DesktopNotification.ui', self)

        self._settingPosition = setPosition
        self._dragPosition = QPoint()

        self._icon = QPixmap()
        self._heading = ''
        self._text = ''
        self._timeout = 6000
        self._timer = QTimer(self)

        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
                            | Qt.X11BypassWindowManagerHint)

        self._timer.setSingleShot(True)
        self._timer.timeout.connect(self.close)

        if self._settingPosition:
            self.setCursor(Qt.OpenHandCursor)

        self._savedPos = None

    closedSignal = pyqtSignal()

    def setPixmap(self, icon):
        '''
        @param: icon QPixmap
        '''
        self._icon = icon

    def setHeading(self, heading):
        '''
        @param: heading QString
        '''
        self._heading = heading

    def setText(self, text):
        '''
        @param: text QString
        '''
        self._text = text

    def setTimeout(self, timeout):
        '''
        @param: timeout int
        '''
        self._timeout = timeout

    def show(self):
        self._ui.icon.setPixmap(self._icon)
        self._ui.icon.setVisible(not self._icon.isNull())
        self._ui.heading.setText(self._heading)
        self._ui.text.setText(self._text)

        if self._settingPosition:
            self._timer.setInterval(self._timeout)
            self._timer.start()

        super().show()

    # private:
    # override
    def mousePressEvent(self, event):
        '''
        @param: event QMouseEvent
        '''
        if not self._settingPosition:
            self.close()
            return

        if event.buttons() == Qt.LeftButton:
            self._dragPosition = event.globalPos() - self.frameGeometry(
            ).topLeft()
            event.accept()

    def mouseMoveEvent(self, event):
        '''
        @param event QMouseEvent
        '''
        if event.buttons() & Qt.LeftButton:
            self.move(event.globalPos() - self._dragPosition)
            event.accept()

    def closeEvent(self, event):
        self.closedSignal.emit()
        self._savedPos = self.pos()
        super().closeEvent(event)

    def savedPos(self):
        if not self._savedPos:
            self._savedPos = self.pos()
        return self._savedPos
コード例 #35
0
class FancyTabWidget(QWidget):
    # Values are persisted = only add to the end
    # enum Mode
    Mode_None = 0
    Mode_LargeSidebar = 1
    Mode_SmallSidebar = 2
    Mode_Tabs = 3
    Mode_IconOnlyTabs = 4
    Mode_PlainSidebar = 5

    def __init__(self, parent=None):
        super().__init__(parent)
        self._mode = self.Mode_None
        self._items = []  # QList<Item>

        self._tab_bar = None  # QWidget
        self._stack = QStackedLayout()  # QStackedLayout
        self._background_pixmap = QPixmap()
        self._side_widget = QWidget()  # QWidget
        self._side_layout = QVBoxLayout()  # QVBoxLayout
        self._top_layout = QVBoxLayout()  # QVBoxLayout

        self._use_background = False  # bool

        self._menu = None  # QMenu

        self._proxy_style = FancyTabProxyStyle()  # FancyTabProxyStyle

        self._side_layout.setSpacing(0)
        self._side_layout.setContentsMargins(0, 0, 0, 0)
        self._side_layout.addSpacerItem(
            QSpacerItem(0, 0, QSizePolicy.Fixed, QSizePolicy.Expanding))

        self._side_widget.setLayout(self._side_layout)
        self._side_widget.setSizePolicy(QSizePolicy.Fixed,
                                        QSizePolicy.Expanding)

        self._top_layout.setSpacing(0)
        self._top_layout.setContentsMargins(0, 0, 0, 0)
        self._top_layout.addLayout(self._stack)

        main_layout = QHBoxLayout()
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(1)
        main_layout.addWidget(self._side_widget)
        main_layout.addLayout(self._top_layout)
        self.setLayout(main_layout)

    class Item:
        # enum Type
        Type_Tab = 0
        Type_Spacer = 1

        def __init__(self, icon, label):
            '''
            @param: icon QIcon
            @param: label QString
            '''
            self.type = self.Type_Tab  # Type
            self.tab_label = label  # QString
            self.tab_icon = icon  # QIcon
            self.spacer_size = 0

    def AddTab(self, tab, icon, label):
        '''
        @param: tab QWidget
        @param: icon Qicon
        @param: label QString
        '''
        self._stack.addWidget(tab)
        self._items.append(self.Item(icon, label))

    def AddSpacer(self, size=40):
        self._items.append(self.Item(size))

    def SetBackgroundPixmap(self, pixmap):
        '''
        @param: pixmap QPixmap
        '''
        self._background_pixmap = pixmap
        self.update()

    def AddBottomWidget(self, widget):
        '''
        @param: widget QWidget
        '''
        self._top_layout.addWidget(widget)

    def current_index(self):
        '''
        @return: int
        '''
        return self._stack.currentIndex()

    def mode(self):
        '''
        @return: Mode
        '''
        return self._mode

    def bgPixmap(self):
        '''
        @return: QPixmap
        '''
        return self._background_pixmap

    bgPixmap = pyqtProperty(QPixmap, bgPixmap, SetBackgroundPixmap)

    # public Q_SLOTS:
    def SetCurrentIndex(self, index):
        bar = self._tab_bar
        if isinstance(bar, FancyTabBar):
            bar.setCurrentIndex(index)
        elif isinstance(bar, QTabBar):
            bar.setCurrentIndex(index)
        else:
            self._stack.setCurrentIndex(index)

    def SetMode(self, mode):
        # Remove previous tab bar
        del self._tab_bar
        self._tab_bar = None

        self._use_background = False

        # Create new tab bar
        if mode == self.Mode_None:
            pass
        elif mode == self.Mode_LargeSidebar:
            bar = FancyTabBar(self)
            self._side_layout.insertWidget(0, bar)
            self._tab_bar = bar
            for item in self._items:
                if item.type == self.Item.Type_Spacer:
                    bar.addSpacer(item.spacer_size)
                else:
                    bar.addTab(item.tab_icon, item.tab_label)

            bar.setCurrentIndex(self._stack.currentIndex())
            bar.currentChanged.connect(self._ShowWidget)
            self._use_background = True
        elif mode == self.Mode_Tabs:
            self._MakeTabBar(QTabBar.RoundedNorth, True, False, False)
        elif mode == self.Mode_IconOnlyTabs:
            self._MakeTabBar(QTabBar.RoundedNorth, False, True, False)
        elif mode == self.Mode_SmallSidebar:
            self._MakeTabBar(QTabBar.RoundedWest, True, True, True)
            self._use_background = True
        elif mode == self.Mode_PlainSidebar:
            self._MakeTabBar(QTabBar.RoundedWest, True, True, False)
        else:
            print('DEBUG: Unknown fancy tab mode %s' % mode)

        self._tab_bar.setSizePolicy(QSizePolicy.Preferred,
                                    QSizePolicy.Preferred)

        self._mode = mode
        self.ModeChanged.emit(mode)
        self.update()

    # Q_SIGNALS:
    CurrentChanged = pyqtSignal(int)  # index
    ModeChanged = pyqtSignal(int)  # mode FancyTabWidget::Mode

    # protected:
    # override
    def paintEvent(self, event):
        '''
        @param: event QPaintEvent
        '''
        if not self._use_background:
            return

        painter = QPainter(self)

        rect = self._side_widget.rect().adjusted(0, 0, 1, 0)
        rect = self.style().visualRect(self.layoutDirection(), self.geometry(),
                                       rect)
        styleHelper.verticalGradient(painter, rect, rect)

        if not self._background_pixmap.isNull():
            pixmap_rect = QRect(self._background_pixmap.rect())
            pixmap_rect.moveTo(rect.topLeft())

            while pixmap_rect.top() < rect.bottom():
                source_rect = QRect(pixmap_rect.intersected(rect))
                source_rect.moveTo(0, 0)
                painter.drawPixmap(pixmap_rect.topLeft(),
                                   self._background_pixmap, source_rect)
                pixmap_rect.moveTop(pixmap_rect.bottom() - 10)

        painter.setPen(styleHelper.borderColor())
        painter.drawLine(rect.topRight(), rect.bottomRight())

        # QColor
        light = styleHelper.sidebarHighlight()
        painter.setPen(light)
        painter.drawLine(rect.bottomLeft(), rect.bottomRight())

    # override
    def contextMenuEvent(self, event):
        '''
        @param: event QContextMenuEvent
        '''
        pass

    # private Q_SLOTS:
    def _ShowWidget(self, index):
        self._stack.setCurrentIndex(index)
        self.CurrentChanged.emit(index)

    # private:
    def _MakeTabBar(self, shap, text, icons, fancy):
        '''
        @param: shap QTabBar::Shap
        @param: text bool
        @param: icons bool
        @param: fancy bool
        '''
        bar = QTabBar(self)
        bar.setShape(shap)
        bar.setDocumentMode(True)
        bar.setUsesScrollButtons(True)

        if shap == QTabBar.RoundedWest:
            bar.setIconSize(QSize(22, 22))

        if fancy:
            bar.setStyle(self._proxy_style)

        if shap == QTabBar.RoundedNorth:
            self._top_layout.insertWidget(0, bar)
        else:
            self._side_layout.insertWidget(0, bar)

        # Item
        for item in self._items:
            if item.type != self.Item.Type_Tab:
                continue

            label = item.tab_label
            if shap == QTabBar.RoundedWest:
                label = QFontMetrics(self.font()).elidedText(
                    label, Qt.ElideMiddle, 100)

            tab_id = -1
            if icons and text:
                tab_id = bar.addTab(item.tab_icon, label)
            elif icons:
                tab_id = bar.addTab(item.tab_icon, '')
            elif text:
                tab_id = bar.addTab(label)

            bar.setTabToolTip(tab_id, item.tab_label)

        bar.setCurrentIndex(self._stack.currentIndex())
        bar.currentChanged.connect(self._ShowWidget)
        self._tab_bar = bar

    def _AddMenuItem(self, mapper, group, text, mode):
        '''
        @param: mapper QSignalMapper
        @param: group QActionGroup
        @param: text QString
        @param: mode Mode
        '''
        # QAction
        action = group.addAction(text)
        action.setCheckable(True)
        mapper.setMapping(action, mode)
        action.triggered.connect(mapper.map)

        if mode == self._mode:
            action.setChecked(True)
コード例 #36
0
 def load(data):
     p = QPixmap()
     p.loadFromData(bytes(data))
     if data and p.isNull():
         p = self.failed_img
     return p
コード例 #37
0
ファイル: widgets.py プロジェクト: zdndanny/calibre
class ImageView(QWidget, ImageDropMixin):

    BORDER_WIDTH = 1
    cover_changed = pyqtSignal(object)

    def __init__(self,
                 parent=None,
                 show_size_pref_name=None,
                 default_show_size=False):
        QWidget.__init__(self, parent)
        self.show_size_pref_name = (
            'show_size_on_cover_' +
            show_size_pref_name) if show_size_pref_name else None
        self._pixmap = QPixmap()
        self.setMinimumSize(QSize(150, 200))
        ImageDropMixin.__init__(self)
        self.draw_border = True
        self.show_size = False
        if self.show_size_pref_name:
            self.show_size = gprefs.get(self.show_size_pref_name,
                                        default_show_size)

    def setPixmap(self, pixmap):
        if not isinstance(pixmap, QPixmap):
            raise TypeError('Must use a QPixmap')
        self._pixmap = pixmap
        self.updateGeometry()
        self.update()

    def build_context_menu(self):
        m = ImageDropMixin.build_context_menu(self)
        if self.show_size_pref_name:
            text = _('Hide size in corner') if self.show_size else _(
                'Show size in corner')
            m.addAction(text, self.toggle_show_size)
        return m

    def toggle_show_size(self):
        self.show_size ^= True
        if self.show_size_pref_name:
            gprefs[self.show_size_pref_name] = self.show_size
        self.update()

    def pixmap(self):
        return self._pixmap

    def sizeHint(self):
        if self._pixmap.isNull():
            return self.minimumSize()
        return self._pixmap.size()

    def paintEvent(self, event):
        QWidget.paintEvent(self, event)
        pmap = self._pixmap
        if pmap.isNull():
            return
        w, h = pmap.width(), pmap.height()
        ow, oh = w, h
        cw, ch = self.rect().width(), self.rect().height()
        scaled, nw, nh = fit_image(w, h, cw, ch)
        if scaled:
            pmap = pmap.scaled(int(nw * pmap.devicePixelRatio()),
                               int(nh * pmap.devicePixelRatio()),
                               Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
        w, h = int(pmap.width() / pmap.devicePixelRatio()), int(
            pmap.height() / pmap.devicePixelRatio())
        x = int(abs(cw - w) / 2)
        y = int(abs(ch - h) / 2)
        target = QRect(x, y, w, h)
        p = QPainter(self)
        p.setRenderHints(QPainter.Antialiasing
                         | QPainter.SmoothPixmapTransform)
        p.drawPixmap(target, pmap)
        if self.draw_border:
            pen = QPen()
            pen.setWidth(self.BORDER_WIDTH)
            p.setPen(pen)
            p.drawRect(target)
        if self.show_size:
            draw_size(p, target, ow, oh)
        p.end()
コード例 #38
0
ファイル: view.py プロジェクト: AtulKumar2/calibre
 def load(data):
     p = QPixmap()
     p.loadFromData(bytes(data))
     if data and p.isNull():
         p = self.failed_img
     return p
コード例 #39
0
ファイル: reports.py プロジェクト: thuvh/calibre
 def pixmap(self, thumbnail_height, entry):
     pmap = QPixmap(current_container().name_to_abspath(entry.name)) if entry.width > 0 and entry.height > 0 else QPixmap()
     scaled, width, height = fit_image(entry.width, entry.height, thumbnail_height, thumbnail_height)
     if scaled and not pmap.isNull():
         pmap = pmap.scaled(width, height, transformMode=Qt.SmoothTransformation)
     return pmap
コード例 #40
0
class ImageView(QWidget, ImageDropMixin):  # {{{

    BORDER_WIDTH = 1
    cover_changed = pyqtSignal(object)

    def __init__(self,
                 parent=None,
                 show_size_pref_name=None,
                 default_show_size=False):
        QWidget.__init__(self, parent)
        self.show_size_pref_name = (
            'show_size_on_cover_' +
            show_size_pref_name) if show_size_pref_name else None
        self._pixmap = QPixmap()
        self.setMinimumSize(QSize(150, 200))
        ImageDropMixin.__init__(self)
        self.draw_border = True
        self.show_size = False
        if self.show_size_pref_name:
            self.show_size = gprefs.get(self.show_size_pref_name,
                                        default_show_size)

    def setPixmap(self, pixmap):
        if not isinstance(pixmap, QPixmap):
            raise TypeError('Must use a QPixmap')
        self._pixmap = pixmap
        self.updateGeometry()
        self.update()

    def build_context_menu(self):
        m = ImageDropMixin.build_context_menu(self)
        if self.show_size_pref_name:
            text = _('Hide size in corner') if self.show_size else _(
                'Show size in corner')
            m.addAction(text, self.toggle_show_size)
        return m

    def toggle_show_size(self):
        self.show_size ^= True
        if self.show_size_pref_name:
            gprefs[self.show_size_pref_name] = self.show_size
        self.update()

    def pixmap(self):
        return self._pixmap

    def sizeHint(self):
        if self._pixmap.isNull():
            return self.minimumSize()
        return self._pixmap.size()

    def paintEvent(self, event):
        QWidget.paintEvent(self, event)
        pmap = self._pixmap
        if pmap.isNull():
            return
        w, h = pmap.width(), pmap.height()
        ow, oh = w, h
        cw, ch = self.rect().width(), self.rect().height()
        scaled, nw, nh = fit_image(w, h, cw, ch)
        if scaled:
            pmap = pmap.scaled(nw, nh, Qt.IgnoreAspectRatio,
                               Qt.SmoothTransformation)
        w, h = pmap.width(), pmap.height()
        x = int(abs(cw - w) / 2.)
        y = int(abs(ch - h) / 2.)
        target = QRect(x, y, w, h)
        p = QPainter(self)
        p.setRenderHints(QPainter.Antialiasing
                         | QPainter.SmoothPixmapTransform)
        p.drawPixmap(target, pmap)
        if self.draw_border:
            pen = QPen()
            pen.setWidth(self.BORDER_WIDTH)
            p.setPen(pen)
            p.drawRect(target)
        if self.show_size:
            sztgt = target.adjusted(0, 0, 0, -4)
            f = p.font()
            f.setBold(True)
            p.setFont(f)
            sz = u'\u00a0%d x %d\u00a0' % (ow, oh)
            flags = Qt.AlignBottom | Qt.AlignRight | Qt.TextSingleLine
            szrect = p.boundingRect(sztgt, flags, sz)
            p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200))
            p.setPen(QPen(QColor(255, 255, 255)))
            p.drawText(sztgt, flags, sz)
        p.end()
コード例 #41
0
class TabIcon(QWidget):
    class Data:
        def __init__(self):
            self.framesCount = 0
            self.animationInterval = 0
            self.animationPixmap = QPixmap()
            self.audioPlayingPixmap = QPixmap()
            self.audioMutedPixmap = QPixmap()

    def __init__(self, parent):
        '''
        @param parent QWidget
        '''
        super().__init__(parent)
        self._tab = None  # WebTab
        self._updateTimer = None  # QTimer
        self._hideTimer = None  # QTimer
        self._sitePixmap = QPixmap()
        self._currentFrame = 0
        self._animationRunning = False
        self._audioIconDisplayed = False
        self._audioIconRect = QRect()

        self.setObjectName('tab-icon')

        self._updateTimer = QTimer(self)
        self._updateTimer.setInterval(self.data().animationInterval)
        self._updateTimer.timeout.connect(self._updateAnimationFrame)

        self._hideTimer = QTimer(self)
        self._hideTimer.setInterval(250)
        self._hideTimer.timeout.connect(self._hide)

        self.resize(16, 16)

    def setWebTab(self, tab):
        '''
        @param: tab WebTab
        '''
        self._tab = tab

        self._tab.webView().loadStarted.connect(self._showLoadingAnimation)
        #self._tab.webView().loadFinished.connect(self._hideLoadingAnimation)
        self._tab.webView().loadProgress.connect(self._hideLoadingAnimation)
        self._tab.webView().iconChanged.connect(self.updateIcon)
        self._tab.webView().backgroundActivityChanged.connect(
            lambda: self.update())

        def pageChangedCb(page):
            '''
            @param: page WebPage
            '''
            page.recentlyAudibleChanged.connect(self._updateAudioIcon)

        pageChangedCb(self._tab.webView().page())
        self._tab.webView().pageChanged.connect(pageChangedCb)

        self.updateIcon()

    def updateIcon(self):
        self._sitePixmap = self._tab.icon(True).pixmap(16)  # allowNull
        if self._sitePixmap.isNull():
            if self._tab.url().isEmpty() or self._tab.url().scheme(
            ) == const.APP_SCHEME:
                self._hide()
            else:
                self._hideTimer.start()
        else:
            self._show()
        self.update()

    _s_data = None

    def data(self):
        '''
        @return: Data
        '''
        if self._s_data is None:
            self._s_data = data = self.Data()
            data.animationInterval = 70
            data.animationPixmap = QIcon(':/icons/other/loading.png').pixmap(
                288, 16)
            data.framesCount = data.animationPixmap.width(
            ) / data.animationPixmap.height()
            data.audioPlayingPixmap = QIcon.fromTheme(
                'audio-volume-high',
                QIcon(':/icons/other/audioplaying.svg')).pixmap(16)
            data.audioMutedPixmap = QIcon.fromTheme(
                'audio-volume-muted',
                QIcon(':/icons/other/audiomuted.svg')).pixmap(16)
        return self._s_data

    # Q_SIGNALS
    resized = pyqtSignal()

    # private Q_SLOTS:
    def _showLoadingAnimation(self):
        self._currentFrame = 0
        self._updateAnimationFrame()
        self._show()

    def _hideLoadingAnimation(self, progress):
        if progress == 100:
            self._animationRunning = False
            self._updateTimer.stop()
            self.updateIcon()

    def _updateAudioIcon(self, recentlyAudible):
        if self._tab.isMuted() or recentlyAudible:
            self._audioIconDisplayed = True
            self._show()
        else:
            self._audioIconDisplayed = False
            self._hide()

        self.update()

    def _updateAnimationFrame(self):
        if not self._animationRunning:
            self._updateTimer.start()
            self._animationRunning = True

        self.update()
        self._currentFrame = (self._currentFrame + 1) % self.data().framesCount

    # private:
    def _show(self):
        if not self._shouldBeVisible():
            return

        self._hideTimer.stop()

        if self.isVisible() and self.width() == 16:
            return

        self.setFixedSize(16, max(self.minimumHeight(), 16))
        self.resized.emit()
        super().show()

    def _hide(self):
        if self._shouldBeVisible():
            return

        if self.isHidden() and self.width() == 1:
            return

        self.setFixedSize(1, max(self.minimumHeight(), 16))
        self.resized.emit()
        super().hide()

    def _shouldBeVisible(self):
        return not self._sitePixmap.isNull() or self._animationRunning or \
            self._audioIconDisplayed or (self._tab and self._tab.isPinned())

    # override
    def event(self, event):
        '''
        @param: event QEvent
        '''
        if event.type() == QEvent.ToolTip:
            # QHelpEvent
            if self._audioIconDisplayed and self._audioIconRect.contains(
                    event.pos()):
                QToolTip.showText(
                    event.globalPos(),
                    self._tab.isMuted() and _('Unmute Tab') or _('Mute Tab'),
                    self)
                event.accept()
                return True
        return super().event(event)

    # override
    def paintEvent(self, event):
        '''
        @param event QPaintEvent
        '''
        p = QPainter(self)
        p.setRenderHint(QPainter.Antialiasing)

        size = 16
        pixmapSize = round(size *
                           self.data().animationPixmap.devicePixelRatioF())

        # Center the pixmap in rect
        r = QRect(self.rect())
        r.setX((r.width() - size) / 2)
        r.setY((r.height() - size) / 2)
        r.setWidth(size)
        r.setHeight(size)

        if self._animationRunning:
            p.drawPixmap(
                r,
                self.data().animationPixmap,
                QRect(self._currentFrame * pixmapSize, 0, pixmapSize,
                      pixmapSize))
        elif self._audioIconDisplayed and not self._tab.isPinned():
            self._audioIconRect = QRect(r)
            p.drawPixmap(
                r,
                self._tab.isMuted() and self.data().audioMutedPixmap
                or self.data().audioPlayingPixmap)
        elif not self._sitePixmap.isNull():
            p.drawPixmap(r, self._sitePixmap)
        elif self._tab and self._tab.isPinned():
            p.drawPixmap(r, IconProvider.emptyWebIcon().pixmap(size))

        # Draw audio icon on top of site icon for pinned tabs
        if not self._animationRunning and self._audioIconDisplayed and self._tab.isPinned(
        ):
            s = size - 4
            r0 = QRect(self.width() - 4, 0, s, s)
            self._audioIconRect = r0
            c = self.palette().color(QPalette.Window)
            c.setAlpha(180)
            p.setPen(c)
            p.setBrush(c)
            p.drawEllipse(r)
            p.drawPixmap(
                r,
                self._tab.isMuted() and self.data().audioMutedPixmap
                or self.data().audioPlayingPixmap)

        # Draw background activity indicator
        if self._tab and self._tab.isPinned() and self._tab.webView(
        ).backgroundActivity():
            s = 5
            # Background
            r1 = QRect(self.width() - s - 2,
                       self.height() - s - 2, s + 2, s + 2)
            c1 = self.palette().color(QPalette.Window)
            c1.setAlpha(180)
            p.setPen(Qt.transparent)
            p.setBrush(c1)
            p.drawEllipse(r1)
            # Forground
            r2 = QRect(self.width() - s - 1, self.height() - s - 1, s, s)
            c2 = self.palette().color(QPalette.Text)
            p.setPen(Qt.transparent)
            p.setBrush(c2)
            p.drawEllipse(r2)

    # override
    def mousePressEvent(self, event):
        '''
        @param event QMouseEvent
        '''
        if self._audioIconDisplayed and event.button() == Qt.LeftButton and \
                self._audioIconRect.contains(event.pos()):
            self._tab.toggleMuted()
            return

        super().mousePressEvent(event)
コード例 #42
0
ファイル: from_html.py プロジェクト: Mymei2/calibre
    def dump(self, items, out_stream, pdf_metadata):
        opts = self.opts
        page_size = get_page_size(self.opts)
        xdpi, ydpi = self.view.logicalDpiX(), self.view.logicalDpiY()
        # We cannot set the side margins in the webview as there is no right
        # margin for the last page (the margins are implemented with
        # -webkit-column-gap)
        ml, mr = opts.margin_left, opts.margin_right
        self.doc = PdfDevice(out_stream, page_size=page_size, left_margin=ml,
                             top_margin=0, right_margin=mr, bottom_margin=0,
                             xdpi=xdpi, ydpi=ydpi, errors=self.log.error,
                             debug=self.log.debug, compress=not
                             opts.uncompressed_pdf, opts=opts,
                             mark_links=opts.pdf_mark_links)
        self.footer = opts.pdf_footer_template
        if self.footer:
            self.footer = self.footer.strip()
        if not self.footer and opts.pdf_page_numbers:
            self.footer = '<p style="text-align:center; text-indent: 0">_PAGENUM_</p>'
        self.header = opts.pdf_header_template
        if self.header:
            self.header = self.header.strip()
        min_margin = 1.5 * opts._final_base_font_size
        if self.footer and opts.margin_bottom < min_margin:
            self.log.warn('Bottom margin is too small for footer, increasing it to %.1fpts' % min_margin)
            opts.margin_bottom = min_margin
        if self.header and opts.margin_top < min_margin:
            self.log.warn('Top margin is too small for header, increasing it to %.1fpts' % min_margin)
            opts.margin_top = min_margin

        self.page.setViewportSize(QSize(self.doc.width(), self.doc.height()))
        self.render_queue = items
        self.total_items = len(items)

        mt, mb = map(self.doc.to_px, (opts.margin_top, opts.margin_bottom))
        self.margin_top, self.margin_bottom = map(lambda x:int(floor(x)), (mt, mb))

        self.painter = QPainter(self.doc)
        self.doc.set_metadata(title=pdf_metadata.title,
                              author=pdf_metadata.author,
                              tags=pdf_metadata.tags, mi=pdf_metadata.mi)
        self.doc_title = pdf_metadata.title
        self.doc_author = pdf_metadata.author
        self.painter.save()
        try:
            if self.cover_data is not None:
                p = QPixmap()
                try:
                    p.loadFromData(self.cover_data)
                except TypeError:
                    self.log.warn('This ebook does not have a raster cover, cannot generate cover for PDF'
                                  '. Cover type: %s' % type(self.cover_data))
                if not p.isNull():
                    self.doc.init_page()
                    draw_image_page(QRect(*self.doc.full_page_rect),
                            self.painter, p,
                            preserve_aspect_ratio=self.opts.preserve_cover_aspect_ratio)
                    self.doc.end_page()
        finally:
            self.painter.restore()

        QTimer.singleShot(0, self.render_book)
        if self.loop.exec_() == 1:
            raise Exception('PDF Output failed, see log for details')

        if self.toc is not None and len(self.toc) > 0:
            self.doc.add_outline(self.toc)

        self.painter.end()

        if self.doc.errors_occurred:
            raise Exception('PDF Output failed, see log for details')
コード例 #43
0
ファイル: widgets.py プロジェクト: JimmXinu/calibre
class ImageView(QWidget, ImageDropMixin):

    BORDER_WIDTH = 1
    cover_changed = pyqtSignal(object)

    def __init__(self, parent=None, show_size_pref_name=None, default_show_size=False):
        QWidget.__init__(self, parent)
        self.show_size_pref_name = ('show_size_on_cover_' + show_size_pref_name) if show_size_pref_name else None
        self._pixmap = QPixmap()
        self.setMinimumSize(QSize(150, 200))
        ImageDropMixin.__init__(self)
        self.draw_border = True
        self.show_size = False
        if self.show_size_pref_name:
            self.show_size = gprefs.get(self.show_size_pref_name, default_show_size)

    def setPixmap(self, pixmap):
        if not isinstance(pixmap, QPixmap):
            raise TypeError('Must use a QPixmap')
        self._pixmap = pixmap
        self.updateGeometry()
        self.update()

    def build_context_menu(self):
        m = ImageDropMixin.build_context_menu(self)
        if self.show_size_pref_name:
            text = _('Hide size in corner') if self.show_size else _('Show size in corner')
            m.addAction(text, self.toggle_show_size)
        return m

    def toggle_show_size(self):
        self.show_size ^= True
        if self.show_size_pref_name:
            gprefs[self.show_size_pref_name] = self.show_size
        self.update()

    def pixmap(self):
        return self._pixmap

    def sizeHint(self):
        if self._pixmap.isNull():
            return self.minimumSize()
        return self._pixmap.size()

    def paintEvent(self, event):
        QWidget.paintEvent(self, event)
        pmap = self._pixmap
        if pmap.isNull():
            return
        w, h = pmap.width(), pmap.height()
        ow, oh = w, h
        cw, ch = self.rect().width(), self.rect().height()
        scaled, nw, nh = fit_image(w, h, cw, ch)
        if scaled:
            pmap = pmap.scaled(int(nw*pmap.devicePixelRatio()), int(nh*pmap.devicePixelRatio()), Qt.IgnoreAspectRatio,
                    Qt.SmoothTransformation)
        w, h = int(pmap.width()/pmap.devicePixelRatio()), int(pmap.height()/pmap.devicePixelRatio())
        x = int(abs(cw - w)/2.)
        y = int(abs(ch - h)/2.)
        target = QRect(x, y, w, h)
        p = QPainter(self)
        p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform)
        p.drawPixmap(target, pmap)
        if self.draw_border:
            pen = QPen()
            pen.setWidth(self.BORDER_WIDTH)
            p.setPen(pen)
            p.drawRect(target)
        if self.show_size:
            draw_size(p, target, ow, oh)
        p.end()
コード例 #44
0
ファイル: dnd.py プロジェクト: kba/calibre
                md.urls()]
        purls = [urlparse(u) for u in urls]
        # First look for a local file
        images = [u2p(xu) for xu in purls if xu.scheme in ('', 'file')]
        images = [xi for xi in images if
                posixpath.splitext(urllib.unquote(xi))[1][1:].lower() in
                image_exts]
        images = [xi for xi in images if os.path.exists(xi)]
        p = QPixmap()
        for path in images:
            try:
                with open(path, 'rb') as f:
                    p.loadFromData(f.read())
            except:
                continue
            if not p.isNull():
                return p, None

        # No local images, look for remote ones

        # First, see if this is from Firefox
        rurl, fname = get_firefox_rurl(md, image_exts)

        if rurl and fname:
            return rurl, fname
        # Look through all remaining URLs
        remote_urls = [xu for xu in purls if xu.scheme in ('http', 'https',
            'ftp') and posixpath.splitext(xu.path)[1][1:].lower() in image_exts]
        if remote_urls:
            rurl = remote_urls[0]
            fname = posixpath.basename(urllib.unquote(rurl.path))