Esempio n. 1
0
    def __init__(self, parent):
        QWizard.__init__(self, parent)
        self.setWindowTitle(__appname__+' '+_('welcome wizard'))
        p  = QPixmap()
        p.loadFromData(open(P('content_server/calibre.png'), 'rb').read())
        self.setPixmap(self.LogoPixmap, p.scaledToHeight(80,
            Qt.SmoothTransformation))
        self.setPixmap(self.WatermarkPixmap,
            QPixmap(I('welcome_wizard.png')))
        self.setPixmap(self.BackgroundPixmap, QPixmap(I('wizard.png')))
        self.device_page = DevicePage()
        self.library_page = LibraryPage()
        self.library_page.retranslate.connect(self.retranslate)
        self.finish_page = FinishPage()
        self.set_finish_text()
        self.kindle_page = KindlePage()
        self.stanza_page = StanzaPage()
        self.setPage(self.library_page.ID, self.library_page)
        self.setPage(self.device_page.ID, self.device_page)
        self.setPage(self.finish_page.ID, self.finish_page)
        self.setPage(self.kindle_page.ID, self.kindle_page)
        self.setPage(self.stanza_page.ID, self.stanza_page)

        self.device_extra_page = None
        nh, nw = min_available_height()-75, available_width()-30
        if nh < 0:
            nh = 580
        if nw < 0:
            nw = 400
        nh = min(400, nh)
        nw = min(580, nw)
        self.resize(nw, nh)
        self.set_button_texts()
Esempio n. 2
0
 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
Esempio n. 3
0
def get_icons(zfp, name_or_list_of_names):
    '''
    Load icons from the plugin zip file

    :param name_or_list_of_names: List of paths to resources in the zip file using / as
                separator, or a single path

    :return: A dictionary of the form ``{name : QIcon}``. Any names
                that were not found in the zip file will be null QIcons.
                If a single path is passed in the return value will
                be A QIcon.
    '''
    from PyQt4.Qt import QIcon, QPixmap
    names = name_or_list_of_names
    ans = get_resources(zfp, names)
    if isinstance(names, basestring):
        names = [names]
    if ans is None:
        ans = {}
    if isinstance(ans, basestring):
        ans = dict([(names[0], ans)])

    ians = {}
    for name in names:
        p = QPixmap()
        raw = ans.get(name, None)
        if raw:
            p.loadFromData(raw)
        ians[name] = QIcon(p)
    if len(names) == 1:
        ians = ians.pop(names[0])
    return ians
Esempio n. 4
0
    def __init__(self, parent):
        QWizard.__init__(self, parent)
        self.setWindowTitle(__appname__ + ' ' + _('welcome wizard'))
        p = QPixmap()
        p.loadFromData(open(P('content_server/calibre.png'), 'rb').read())
        self.setPixmap(self.LogoPixmap,
                       p.scaledToHeight(80, Qt.SmoothTransformation))
        self.setPixmap(self.WatermarkPixmap, QPixmap(I('welcome_wizard.png')))
        self.setPixmap(self.BackgroundPixmap, QPixmap(I('wizard.png')))
        self.device_page = DevicePage()
        self.library_page = LibraryPage()
        self.library_page.retranslate.connect(self.retranslate)
        self.finish_page = FinishPage()
        self.set_finish_text()
        self.kindle_page = KindlePage()
        self.stanza_page = StanzaPage()
        self.setPage(self.library_page.ID, self.library_page)
        self.setPage(self.device_page.ID, self.device_page)
        self.setPage(self.finish_page.ID, self.finish_page)
        self.setPage(self.kindle_page.ID, self.kindle_page)
        self.setPage(self.stanza_page.ID, self.stanza_page)

        self.device_extra_page = None
        nh, nw = min_available_height() - 75, available_width() - 30
        if nh < 0:
            nh = 580
        if nw < 0:
            nw = 400
        nh = min(400, nh)
        nw = min(580, nw)
        self.resize(nw, nh)
        self.set_button_texts()
Esempio n. 5
0
    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()
Esempio n. 6
0
 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
Esempio n. 7
0
def get_pixmap(icon_name):
    '''
    Retrieve a QPixmap for the named image
    Any icons belonging to the plugin must be prefixed with 'images/'
    '''
    global plugin_icon_resources, plugin_name

    if not icon_name.startswith('images/'):
        # We know this is definitely not an icon belonging to this plugin
        pixmap = QPixmap()
        pixmap.load(I(icon_name))
        return pixmap

    # Check to see whether the icon exists as a Calibre resource
    # This will enable skinning if the user stores icons within a folder like:
    # ...\AppData\Roaming\calibre\resources\images\Plugin Name\
    if plugin_name:
        local_images_dir = get_local_images_dir(plugin_name)
        local_image_path = os.path.join(local_images_dir,
                                        icon_name.replace('images/', ''))
        if os.path.exists(local_image_path):
            pixmap = QPixmap()
            pixmap.load(local_image_path)
            return pixmap

    # As we did not find an icon elsewhere, look within our zip resources
    if icon_name in plugin_icon_resources:
        pixmap = QPixmap()
        pixmap.loadFromData(plugin_icon_resources[icon_name])
        return pixmap
    return None
Esempio n. 8
0
def get_pixmap(icon_name):
    '''
    Retrieve a QPixmap for the named image
    Any icons belonging to the plugin must be prefixed with 'images/'
    '''
    global plugin_icon_resources, plugin_name

    if not icon_name.startswith('images/'):
        # We know this is definitely not an icon belonging to this plugin
        pixmap = QPixmap()
        pixmap.load(I(icon_name))
        return pixmap

    # Check to see whether the icon exists as a Calibre resource
    # This will enable skinning if the user stores icons within a folder like:
    # ...\AppData\Roaming\calibre\resources\images\Plugin Name\
    if plugin_name:
        local_images_dir = get_local_images_dir(plugin_name)
        local_image_path = os.path.join(local_images_dir, icon_name.replace('images/', ''))
        if os.path.exists(local_image_path):
            pixmap = QPixmap()
            pixmap.load(local_image_path)
            return pixmap

    # As we did not find an icon elsewhere, look within our zip resources
    if icon_name in plugin_icon_resources:
        pixmap = QPixmap()
        pixmap.loadFromData(plugin_icon_resources[icon_name])
        return pixmap
    return None
Esempio n. 9
0
def get_icons(zfp, name_or_list_of_names):
    '''
    Load icons from the plugin zip file

    :param name_or_list_of_names: List of paths to resources in the zip file using / as
                separator, or a single path

    :return: A dictionary of the form ``{name : QIcon}``. Any names
                that were not found in the zip file will be null QIcons.
                If a single path is passed in the return value will
                be A QIcon.
    '''
    from PyQt4.Qt import QIcon, QPixmap
    names = name_or_list_of_names
    ans = get_resources(zfp, names)
    if isinstance(names, basestring):
        names = [names]
    if ans is None:
        ans = {}
    if isinstance(ans, basestring):
        ans = dict([(names[0], ans)])

    ians = {}
    for name in names:
        p = QPixmap()
        raw = ans.get(name, None)
        if raw:
            p.loadFromData(raw)
        ians[name] = QIcon(p)
    if len(names) == 1:
        ians = ians.pop(names[0])
    return ians
Esempio n. 10
0
    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()
Esempio n. 11
0
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()) for u in 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))
            return urlunparse(rurl), fname

        return None, None
Esempio n. 12
0
File: dnd.py Progetto: Eksmo/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()) for u in
                md.urls()]
        purls = [urlparse(u) for u in urls]
        # First look for a local file
        images = [u2p(x) for x in purls if x.scheme in ('', 'file')]
        images = [x for x in images if
                posixpath.splitext(urllib.unquote(x))[1][1:].lower() in
                image_exts]
        images = [x for x in images if os.path.exists(x)]
        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 = [x for x in purls if x.scheme in ('http', 'https',
            'ftp') and posixpath.splitext(x.path)[1][1:].lower() in image_exts]
        if remote_urls:
            rurl = remote_urls[0]
            fname = posixpath.basename(urllib.unquote(rurl.path))
            return urlunparse(rurl), fname

        return None, None
Esempio n. 13
0
 def data(self, index, role):
     row, col = index.row(), index.column()
     if row >= len(self.matches):
         return NONE
     result = self.matches[row]
     if role == Qt.DisplayRole:
         if col == 1:
             t = result.title if result.title else _('Unknown')
             a = result.author if result.author else ''
             return QVariant('<b>%s</b><br><i>%s</i>' % (t, a))
         elif col == 2:
             return QVariant(result.price)
         elif col == 4:
             return QVariant('%s<br>%s' % (result.store_name, result.formats))
         return NONE
     elif role == Qt.DecorationRole:
         if col == 0 and result.cover_data:
             p = QPixmap()
             p.loadFromData(result.cover_data)
             return QVariant(p)
         if col == 3:
             if result.drm == SearchResult.DRM_LOCKED:
                 return QVariant(self.DRM_LOCKED_ICON)
             elif result.drm == SearchResult.DRM_UNLOCKED:
                 return QVariant(self.DRM_UNLOCKED_ICON)
             elif result.drm == SearchResult.DRM_UNKNOWN:
                 return QVariant(self.DRM_UNKNOWN_ICON)
         if col == 5:
             if result.downloads:
                 return QVariant(self.DOWNLOAD_ICON)
         if col == 6:
             if result.affiliate:
                 return QVariant(self.DONATE_ICON)
     elif role == Qt.ToolTipRole:
         if col == 1:
             return QVariant('<p>%s</p>' % result.title)
         elif col == 2:
             return QVariant('<p>' + _('Detected price as: %s. Check with the store before making a purchase to verify this price is correct. This price often does not include promotions the store may be running.') % result.price + '</p>')  # noqa
         elif col == 3:
             if result.drm == SearchResult.DRM_LOCKED:
                 return QVariant('<p>' + _('This book as been detected as having DRM restrictions. This book may not work with your reader and you will have limitations placed upon you as to what you can do with this book. Check with the store before making any purchases to ensure you can actually read this book.') + '</p>')  # noqa
             elif result.drm == SearchResult.DRM_UNLOCKED:
                 return QVariant('<p>' + _('This book has been detected as being DRM Free. You should be able to use this book on any device provided it is in a format calibre supports for conversion. However, before making a purchase double check the DRM status with the store. The store may not be disclosing the use of DRM.') + '</p>')  # noqa
             else:
                 return QVariant('<p>' + _('The DRM status of this book could not be determined. There is a very high likelihood that this book is actually DRM restricted.') + '</p>')  # noqa
         elif col == 4:
             return QVariant('<p>%s</p>' % result.formats)
         elif col == 5:
             if result.downloads:
                 return QVariant('<p>' + _('The following formats can be downloaded directly: %s.') % ', '.join(result.downloads.keys()) + '</p>')
         elif col == 6:
             if result.affiliate:
                 return QVariant('<p>' + _('Buying from this store supports the calibre developer: %s.') % result.plugin_author + '</p>')
     elif role == Qt.SizeHintRole:
         return QSize(64, 64)
     return NONE
Esempio n. 14
0
 def data(self, index, role):
     row, col = index.row(), index.column()
     if row >= len(self.matches):
         return NONE
     result = self.matches[row]
     if role == Qt.DisplayRole:
         if col == 1:
             t = result.title if result.title else _('Unknown')
             a = result.author if result.author else ''
             return QVariant('<b>%s</b><br><i>%s</i>' % (t, a))
         elif col == 2:
             return QVariant(result.price)
         elif col == 4:
             return QVariant('%s<br>%s' % (result.store_name, result.formats))
         return NONE
     elif role == Qt.DecorationRole:
         if col == 0 and result.cover_data:
             p = QPixmap()
             p.loadFromData(result.cover_data)
             return QVariant(p)
         if col == 3:
             if result.drm == SearchResult.DRM_LOCKED:
                 return QVariant(self.DRM_LOCKED_ICON)
             elif result.drm == SearchResult.DRM_UNLOCKED:
                 return QVariant(self.DRM_UNLOCKED_ICON)
             elif result.drm == SearchResult.DRM_UNKNOWN:
                 return QVariant(self.DRM_UNKNOWN_ICON)
         if col == 5:
             if result.downloads:
                 return QVariant(self.DOWNLOAD_ICON)
         if col == 6:
             if result.affiliate:
                 return QVariant(self.DONATE_ICON)
     elif role == Qt.ToolTipRole:
         if col == 1:
             return QVariant('<p>%s</p>' % result.title)
         elif col == 2:
             return QVariant('<p>' + _('Detected price as: %s. Check with the store before making a purchase to verify this price is correct. This price often does not include promotions the store may be running.') % result.price + '</p>')
         elif col == 3:
             if result.drm == SearchResult.DRM_LOCKED:
                 return QVariant('<p>' + _('This book as been detected as having DRM restrictions. This book may not work with your reader and you will have limitations placed upon you as to what you can do with this book. Check with the store before making any purchases to ensure you can actually read this book.') + '</p>')
             elif result.drm == SearchResult.DRM_UNLOCKED:
                 return QVariant('<p>' + _('This book has been detected as being DRM Free. You should be able to use this book on any device provided it is in a format calibre supports for conversion. However, before making a purchase double check the DRM status with the store. The store may not be disclosing the use of DRM.') + '</p>')
             else:
                 return QVariant('<p>' + _('The DRM status of this book could not be determined. There is a very high likelihood that this book is actually DRM restricted.') + '</p>')
         elif col == 4:
             return QVariant('<p>%s</p>' % result.formats)
         elif col == 5:
             if result.downloads:
                 return QVariant('<p>' + _('The following formats can be downloaded directly: %s.') % ', '.join(result.downloads.keys()) + '</p>')
         elif col == 6:
             if result.affiliate:
                 return QVariant('<p>' + _('Buying from this store supports the calibre developer: %s.') % result.plugin_author + '</p>')
     elif role == Qt.SizeHintRole:
         return QSize(64, 64)
     return NONE
Esempio n. 15
0
 def update_result(self, plugin_name, width, height, data):
     idx = None
     for plugin, i in self.plugin_map.iteritems():
         if plugin.name == plugin_name:
             idx = i
             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))
Esempio n. 16
0
 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()
 def update_result(self, plugin_name, width, height, data):
     idx = None
     for plugin, i in self.plugin_map.iteritems():
         if plugin.name == plugin_name:
             idx = i
             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))
Esempio n. 18
0
 def insert_cover(self):
     if self.cover_data is None:
         return
     item_path = os.path.join(self.tmp_path, 'cover.pdf')
     printer = get_pdf_printer(self.opts, output_file_name=item_path)
     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()
     printer.abort()
Esempio n. 19
0
    def dump(self, items, out_stream, pdf_metadata):
        opts = self.opts
        self.outline = Outline(self.toc, items)
        page_size = get_page_size(self.opts)
        xdpi, ydpi = self.view.logicalDpiX(), self.view.logicalDpiY()
        ml, mr = opts.margin_left, opts.margin_right
        margin_side = min(ml, mr)
        ml, mr = ml - margin_side, mr - margin_side
        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)

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

        # TODO: Test margins
        mt, mb = map(self.doc.to_px, (opts.margin_top, opts.margin_bottom))
        ms = self.doc.to_px(margin_side, vertical=False)
        self.margin_top, self.margin_size, self.margin_bottom = map(
            lambda x:int(floor(x)), (mt, ms, mb))

        self.painter = QPainter(self.doc)
        self.doc.set_metadata(title=pdf_metadata.title,
                              author=pdf_metadata.author,
                              tags=pdf_metadata.tags)
        self.painter.save()
        try:
            if self.cover_data is not None:
                p = QPixmap()
                p.loadFromData(self.cover_data)
                if not p.isNull():
                    draw_image_page(QRect(0, 0, self.doc.width(), self.doc.height()),
                            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)
        self.loop.exec_()

        # TODO: Outline and links
        self.painter.end()

        if self.doc.errors_occurred:
            raise Exception('PDF Output failed, see log for details')
Esempio n. 20
0
 def fset(self, cdata):
     self._cdata = None
     pm = QPixmap()
     if cdata:
         pm.loadFromData(cdata)
     if pm.isNull():
         pm = QPixmap(I('default_cover.png'))
     else:
         self._cdata = cdata
     self.setPixmap(pm)
     tt = _('This book has no cover')
     if self._cdata:
         tt = _('Cover size: %(width)d x %(height)d pixels') % \
         dict(width=pm.width(), height=pm.height())
     self.setToolTip(tt)
Esempio n. 21
0
 def fset(self, cdata):
     self._cdata = None
     pm = QPixmap()
     if cdata:
         pm.loadFromData(cdata)
     if pm.isNull():
         pm = QPixmap(I('default_cover.png'))
     else:
         self._cdata = cdata
     self.setPixmap(pm)
     tt = _('This book has no cover')
     if self._cdata:
         tt = _('Cover size: %(width)d x %(height)d pixels') % \
         dict(width=pm.width(), height=pm.height())
     self.setToolTip(tt)
Esempio n. 22
0
 def insert_cover(self):
     if self.cover_data is None:
         return
     item_path = os.path.join(self.tmp_path, 'cover.pdf')
     printer = get_pdf_printer(self.opts, output_file_name=item_path)
     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()
     printer.abort()
Esempio n. 23
0
 def data(self, role):
     if role == Qt.DisplayRole:
         return QVariant(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 = QVariant(QIcon(p))
             else:
                 self.icon = self.default_icon
         return self.icon
     return NONE
Esempio n. 24
0
def get_pixmap(icon_name):
    '''
    Retrieve a QPixmap for the named image
    Any zipped icons belonging to the plugin must be prefixed with 'images/'
    '''
    global plugin_icon_resources

    if not icon_name.startswith('images/'):
        # We know this is definitely not an icon belonging to this plugin
        pixmap = QPixmap()
        pixmap.load(I(icon_name))
        return pixmap

    # As we did not find an icon elsewhere, look within our zip resources
    if icon_name in plugin_icon_resources:
        pixmap = QPixmap()
        pixmap.loadFromData(plugin_icon_resources[icon_name])
        return pixmap
    return None
Esempio n. 25
0
def get_pixmap(icon_name):
    """
    Retrieve a QPixmap for the named image
    Any zipped icons belonging to the plugin must be prefixed with 'images/'
    """
    global plugin_icon_resources

    if not icon_name.startswith("images/"):
        # We know this is definitely not an icon belonging to this plugin
        pixmap = QPixmap()
        pixmap.load(I(icon_name))
        return pixmap

    # As we did not find an icon elsewhere, look within our zip resources
    if icon_name in plugin_icon_resources:
        pixmap = QPixmap()
        pixmap.loadFromData(plugin_icon_resources[icon_name])
        return pixmap
    return None
Esempio n. 26
0
 def data(self, role):
     if role == Qt.DisplayRole:
         return QVariant(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 = QVariant(QIcon(p))
             else:
                 self.icon = self.default_icon
         return self.icon
     return NONE
Esempio n. 27
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)
Esempio n. 28
0
 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))
Esempio n. 29
0
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.)
        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.Antialiasing
                         | QPainter.SmoothPixmapTransform)
        p.drawPixmap(
            target,
            self.pixmap.scaled(target.size(), Qt.KeepAspectRatio,
                               Qt.SmoothTransformation))
        p.end()

    def sizeHint(self):
        return QSize(300, 400)
Esempio n. 30
0
File: diff.py Progetto: sss/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()
Esempio n. 31
0
 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()
Esempio n. 32
0
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.)
        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.Antialiasing | QPainter.SmoothPixmapTransform)
        p.drawPixmap(target, self.pixmap.scaled(target.size(),
            Qt.KeepAspectRatio, Qt.SmoothTransformation))
        p.end()

    def sizeHint(self):
        return QSize(300, 400)
Esempio n. 33
0
 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))
Esempio n. 34
0
 def initialize():
     _up_arrow = QPixmap()
     _up_arrow.loadFromData(_up_arrow_data)
     _down_arrow = QPixmap()
     _down_arrow.loadFromData(_down_arrow_data)
Esempio n. 35
0
class parameter_dialog_or_frame:
    """
    use as a pre-mixin before QDialog or QFrame
    """

    ####@@@@
    def __init__(self,
                 parent=None,
                 desc=None,
                 name=None,
                 modal=0,
                 fl=0,
                 env=None,
                 type="QDialog"):
        if env is None:
            import foundation.env as env  # this is a little weird... probably it'll be ok, and logically it seems correct.

        self.desc = desc

        self.typ = type
        if type == "QDialog":
            QDialog.__init__(self, parent, name, modal, fl)
        elif type == "QTextEdit":
            QTextEdit.__init__(self, parent, name)
        elif type == "QFrame":
            QFrame.__init__(self, parent, name)
        else:
            print "don't know about type == %r" % (type, )

        self.image1 = QPixmap()
        self.image1.loadFromData(image1_data,
                                 "PNG")  # should be: title_icon ####
        self.image3 = QPixmap()
        self.image3.loadFromData(image3_data, "PNG")
        self.image4 = QPixmap()
        self.image4.loadFromData(image4_data, "PNG")
        self.image5 = QPixmap()
        self.image5.loadFromData(image5_data, "PNG")
        self.image6 = QPixmap()
        self.image6.loadFromData(image6_data, "PNG")
        self.image7 = QPixmap()
        self.image7.loadFromData(image7_data, "PNG")
        self.image0 = QPixmap(image0_data)  # should be: border_icon ####
        self.image2 = QPixmap(image2_data)  # should be: sponsor_pixmap ####

        try:
            ####@@@@
            title_icon_name = self.desc.options.get('title_icon')
            border_icon_name = self.desc.options.get('border_icon')
            if title_icon_name:
                self.image1 = imagename_to_pixmap(
                    title_icon_name)  ###@@@ pass icon_path
                ###@@@ import imagename_to_pixmap or use env function
                # or let that func itself be an arg, or have an env arg for it
                ###e rename it icon_name_to_pixmap, or find_icon? (the latter only if it's ok if it returns an iconset)
                ###e use iconset instead?
            if border_icon_name:
                self.image0 = imagename_to_pixmap(border_icon_name)
        except:
            print_compact_traceback(
                "bug in icon-setting code, using fallback icons: ")
            pass

        if not name:
            self.setName("parameter_dialog_or_frame")  ###

        ###k guess this will need: if type == 'QDialog'
        self.setIcon(self.image0)  # should be: border_icon ####

        nanotube_dialogLayout = QVBoxLayout(self, 0, 0,
                                            "nanotube_dialogLayout")

        self.heading_frame = QFrame(self, "heading_frame")
        self.heading_frame.setPaletteBackgroundColor(QColor(122, 122, 122))
        self.heading_frame.setFrameShape(QFrame.NoFrame)
        self.heading_frame.setFrameShadow(QFrame.Plain)
        heading_frameLayout = QHBoxLayout(self.heading_frame, 0, 3,
                                          "heading_frameLayout")

        self.heading_pixmap = QLabel(self.heading_frame, "heading_pixmap")
        self.heading_pixmap.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed, 0, 0,
                        self.heading_pixmap.sizePolicy().hasHeightForWidth()))
        self.heading_pixmap.setPixmap(
            self.image1)  # should be: title_icon ####
        self.heading_pixmap.setScaledContents(1)
        heading_frameLayout.addWidget(self.heading_pixmap)

        self.heading_label = QLabel(self.heading_frame, "heading_label")
        self.heading_label.setPaletteForegroundColor(QColor(255, 255, 255))
        heading_label_font = QFont(self.heading_label.font())
        heading_label_font.setPointSize(12)
        heading_label_font.setBold(1)
        self.heading_label.setFont(heading_label_font)
        heading_frameLayout.addWidget(self.heading_label)
        nanotube_dialogLayout.addWidget(self.heading_frame)

        self.body_frame = QFrame(self, "body_frame")
        self.body_frame.setFrameShape(QFrame.StyledPanel)
        self.body_frame.setFrameShadow(QFrame.Raised)
        body_frameLayout = QVBoxLayout(self.body_frame, 3, 3,
                                       "body_frameLayout")

        self.sponsor_frame = QFrame(self.body_frame, "sponsor_frame")
        self.sponsor_frame.setPaletteBackgroundColor(QColor(255, 255, 255))
        self.sponsor_frame.setFrameShape(QFrame.StyledPanel)
        self.sponsor_frame.setFrameShadow(QFrame.Raised)
        sponsor_frameLayout = QHBoxLayout(self.sponsor_frame, 0, 0,
                                          "sponsor_frameLayout")

        self.sponsor_btn = QPushButton(self.sponsor_frame, "sponsor_btn")
        self.sponsor_btn.setAutoDefault(0)  #bruce 060703 bugfix
        self.sponsor_btn.setSizePolicy(
            QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred, 0, 0,
                        self.sponsor_btn.sizePolicy().hasHeightForWidth()))
        self.sponsor_btn.setPaletteBackgroundColor(QColor(255, 255, 255))
        self.sponsor_btn.setPixmap(
            self.image2
        )  # should be: sponsor_pixmap #### [also we'll need to support >1 sponsor]
        self.sponsor_btn.setFlat(1)
        sponsor_frameLayout.addWidget(self.sponsor_btn)
        body_frameLayout.addWidget(self.sponsor_frame)

        layout59 = QHBoxLayout(None, 0, 6, "layout59")
        left_spacer = QSpacerItem(20, 20, QSizePolicy.Expanding,
                                  QSizePolicy.Minimum)
        layout59.addItem(left_spacer)

        self.done_btn = QToolButton(self.body_frame, "done_btn")
        self.done_btn.setIcon(QIcon(self.image3))
        layout59.addWidget(self.done_btn)

        self.abort_btn = QToolButton(self.body_frame, "abort_btn")
        self.abort_btn.setIcon(QIcon(self.image4))
        layout59.addWidget(self.abort_btn)

        self.preview_btn = QToolButton(self.body_frame, "preview_btn")
        self.preview_btn.setIcon(QIcon(self.image5))
        layout59.addWidget(self.preview_btn)

        self.whatsthis_btn = QToolButton(self.body_frame, "whatsthis_btn")
        self.whatsthis_btn.setIcon(QIcon(self.image6))
        layout59.addWidget(self.whatsthis_btn)
        right_spacer = QSpacerItem(20, 20, QSizePolicy.Expanding,
                                   QSizePolicy.Minimum)
        layout59.addItem(right_spacer)
        body_frameLayout.addLayout(layout59)

        self.groups = []
        self.param_getters = {
        }  # map from param name to get-function (which gets current value out of its widget or controller)

        for group_desc in self.desc.kids('group'):

            # == start parameters_grpbox ### this will differ for Windows style

            header_refs = [
            ]  # keep python refcounted refs to all objects we make (at least the ones pyuic stored in self attrs)

            self.parameters_grpbox = QGroupBox(self.body_frame,
                                               "parameters_grpbox")
            self.parameters_grpbox.setFrameShape(QGroupBox.StyledPanel)
            self.parameters_grpbox.setFrameShadow(QGroupBox.Sunken)
            self.parameters_grpbox.setMargin(0)
            self.parameters_grpbox.setColumnLayout(0, Qt.Vertical)
            self.parameters_grpbox.layout().setSpacing(1)
            self.parameters_grpbox.layout().setMargin(4)
            parameters_grpboxLayout = QVBoxLayout(
                self.parameters_grpbox.layout())
            parameters_grpboxLayout.setAlignment(Qt.AlignTop)

            layout20 = QHBoxLayout(None, 0, 6, "layout20")

            self.nt_parameters_grpbtn = QPushButton(self.parameters_grpbox,
                                                    "nt_parameters_grpbtn")
            self.nt_parameters_grpbtn.setSizePolicy(
                QSizePolicy(
                    QSizePolicy.Minimum, QSizePolicy.Fixed, 0, 0,
                    self.nt_parameters_grpbtn.sizePolicy().hasHeightForWidth())
            )
            self.nt_parameters_grpbtn.setMaximumSize(QSize(16, 16))
            self.nt_parameters_grpbtn.setAutoDefault(0)
            self.nt_parameters_grpbtn.setIcon(QIcon(
                self.image7))  ### not always right, but doesn't matter
            self.nt_parameters_grpbtn.setFlat(1)
            layout20.addWidget(self.nt_parameters_grpbtn)

            self.parameters_grpbox_label = QLabel(self.parameters_grpbox,
                                                  "parameters_grpbox_label")
            self.parameters_grpbox_label.setSizePolicy(
                QSizePolicy(
                    QSizePolicy.Preferred, QSizePolicy.Minimum, 0, 0,
                    self.parameters_grpbox_label.sizePolicy().
                    hasHeightForWidth()))
            self.parameters_grpbox_label.setAlignment(QLabel.AlignVCenter)
            layout20.addWidget(self.parameters_grpbox_label)
            gbx_spacer1 = QSpacerItem(67, 16, QSizePolicy.Expanding,
                                      QSizePolicy.Minimum)
            layout20.addItem(gbx_spacer1)
            parameters_grpboxLayout.addLayout(layout20)

            nt_parameters_body_layout = QGridLayout(
                None, 1, 1, 0, 6, "nt_parameters_body_layout"
            )  ### what is 6 -- is it related to number of items???
            # is it 6 in all the ones we got, but that could be a designer error so i better look it up sometime.

            # == start its kids

            # will use from above: self.parameters_grpbox, nt_parameters_body_layout

            nextrow = 0  # which row of the QGridLayout to start filling next (loop variable)
            hidethese = [
            ]  # set of objects to hide or show, when this group is closed or opened

            for param in group_desc.kids('parameter'):
                # param (a group subobj desc) is always a parameter, but we already plan to extend this beyond that,
                # so we redundantly test for this here.
                getter = None
                paramname = None
                # set these for use by uniform code at the end (e.g. for tooltips)
                editfield = None
                label = None
                if param.isa('parameter'):
                    label = QLabel(self.parameters_grpbox, "members_label")
                    label.setAlignment(QLabel.AlignVCenter | QLabel.AlignRight)
                    nt_parameters_body_layout.addWidget(label, nextrow, 0)
                    hidethese.append(label)
                    thisrow = nextrow
                    nextrow += 1
                    #e following should be known in a place that knows the input language, not here
                    paramname = param.options.get('name') or (
                        param.args and param.args[0]) or "?"
                    paramlabel = param.options.get(
                        'label'
                    ) or paramname  ##e wrong, label "" or none ought to be possible
                    # QtGui.QApplication.translate(self.__class__.__name__, "xyz")
                    label.setText(
                        QtGui.QApplication.translate(self.__class__.__name__,
                                                     paramlabel))

                if param.isa('parameter',
                             widget='combobox',
                             type=('str', None)):
                    self.members_combox = QComboBox(
                        0, self.parameters_grpbox,
                        "members_combox")  ###k  what's 0?
                    editfield = self.members_combox
                    #### it probably needs a handler class, and then that could do this setup
                    self.members_combox.clear()
                    default = param.options.get(
                        'default', None)  # None is not equal to any string
                    thewidgetkid = param.kids(
                        'widget'
                    )[-1]  # kluge; need to think what the desc method for this should be
                    for item in thewidgetkid.kids('item'):
                        itemval = item.args[0]
                        itemtext = itemval
                        self.members_combox.insertItem(
                            QtGui.QApplication.translate(
                                self.__class__.__name__,
                                itemtext))  #k __tr ok??
                        if itemval == default:  #k or itemtext?
                            pass  ##k i find no setItem in our py code, so not sure yet what to do for this.
                    nt_parameters_body_layout.addWidget(
                        self.members_combox, thisrow, 1)
                    hidethese.append(self.members_combox)
                    getter = (lambda combobox=self.members_combox: str(
                        combobox.currentText()))
                    ##e due to __tr or non-str values, it might be better to use currentIndex and look it up in a table
                    # (though whether __tr is good here might depend on what it's used for)

                elif param.isa('parameter',
                               widget=('lineedit', None),
                               type=('str', None)):
                    # this covers explicit str|lineedit, and 3 default cases str, lineedit, neither.
                    # (i.e. if you say parameter and nothing else, it's str lineedit by default.)
                    self.length_linedit = QLineEdit(self.parameters_grpbox,
                                                    "length_linedit")
                    editfield = self.length_linedit
                    nt_parameters_body_layout.addWidget(
                        self.length_linedit, thisrow, 1)
                    hidethese.append(self.length_linedit)
                    default = str(param.options.get('default', ""))
                    self.length_linedit.setText(
                        QtGui.QApplication.translate(self.__class__.__name__,
                                                     default))  # __tr ok?
                    getter = (lambda lineedit=self.length_linedit: str(
                        lineedit.text()))

                elif param.isa('parameter',
                               widget=('lineedit', None),
                               type='float'):
                    self.length_linedit = QLineEdit(self.parameters_grpbox,
                                                    "length_linedit")
                    editfield = self.length_linedit
                    nt_parameters_body_layout.addWidget(
                        self.length_linedit, thisrow, 1)
                    hidethese.append(self.length_linedit)
                    controller = FloatLineeditController_Qt(
                        self, param, self.length_linedit)
                    header_refs.append(controller)
                    getter = controller.get_value

                elif param.isa('parameter', widget = ('spinbox', None), type = 'int') or \
                     param.isa('parameter', widget = ('spinbox'), type = None):
                    self.chirality_N_spinbox = QSpinBox(
                        self.parameters_grpbox, "chirality_N_spinbox"
                    )  # was chirality_m_spinbox, now chirality_N_spinbox
                    editfield = self.chirality_N_spinbox
                    ### seems like Qt defaults for min and max are 0,100 -- way too small a range!
                    if param.options.has_key('min') or 1:
                        self.chirality_N_spinbox.setMinimum(
                            param.options.get('min', -999999999))  # was 0
                    if param.options.has_key('max') or 1:
                        self.chirality_N_spinbox.setMaximum(
                            param.options.get(
                                'max',
                                +999999999))  # wasn't in egcode, but needed
                    self.chirality_N_spinbox.setValue(
                        param.options.get('default', 0))  # was 5
                    ##e note: i suspect this default 0 should come from something that knows this desc grammar.
                    suffix = param.options.get('suffix', '')
                    if suffix:
                        self.chirality_N_spinbox.setSuffix(
                            QtGui.QApplication.translate(
                                self.__class__.__name__, suffix))
                    else:
                        self.chirality_N_spinbox.setSuffix(
                            QString.null)  # probably not needed
                    nt_parameters_body_layout.addWidget(
                        self.chirality_N_spinbox, thisrow, 1)
                    hidethese.append(self.chirality_N_spinbox)
                    getter = self.chirality_N_spinbox.value  # note: it also has .text, which includes suffix

                else:
                    print "didn't match:", param  ###e improve this

                # things done the same way for all kinds of param-editing widgets
                if 1:  #bruce 060703 moved this down here, as bugfix
                    # set tooltip (same one for editfield and label)
                    tooltip = param.options.get('tooltip', '')
                    ###e do it for more kinds of params; share the code somehow; do it in controller, or setup-aid?
                    ###k QToolTip appropriateness; tooltip option might be entirely untested
                    if tooltip and label:
                        QToolTip.add(
                            label,
                            QtGui.QApplication.translate(
                                self.__class__.__name__, tooltip))
                    if tooltip and editfield:
                        QToolTip.add(
                            editfield,
                            QtGui.QApplication.translate(
                                self.__class__.__name__, tooltip)
                        )  ##k ok?? review once not all params have same-row labels.

                if getter and paramname and paramname != '?':
                    self.param_getters[paramname] = getter
                ### also bind these params to actions...
                continue  # next param

            header_refs.extend([
                self.parameters_grpbox, self.nt_parameters_grpbtn,
                self.parameters_grpbox_label
            ])

            # now create the logic/control object for the group
            group = CollapsibleGroupController_Qt(self, group_desc,
                                                  header_refs, hidethese,
                                                  self.nt_parameters_grpbtn)
            ### maybe ask env for the class to use for this?
            self.groups.append(
                group
            )  ### needed?? only for scanning the params, AFAIK -- oh, and to maintain a python refcount.

            # from languageChange:
            if 1:  # i don't know if these are needed:
                self.parameters_grpbox.setTitle(QString.null)
                self.nt_parameters_grpbtn.setText(QString.null)
            self.parameters_grpbox_label.setText(
                QtGui.QApplication.translate(
                    self.__class__.__name__,
                    group_desc.args[0]))  # was "Nanotube Parameters"
            ##e note that it's questionable in the syntax design for this property of a group (overall group label)
            # to be in that position (desc arg 0).

            # == end its kids

            parameters_grpboxLayout.addLayout(nt_parameters_body_layout)
            body_frameLayout.addWidget(self.parameters_grpbox)

            # == end parameters groupbox

            continue  # next group

        nanotube_dialogLayout.addWidget(self.body_frame)
        spacer14 = QSpacerItem(20, 20, QSizePolicy.Minimum,
                               QSizePolicy.Expanding)
        nanotube_dialogLayout.addItem(spacer14)

        layout42 = QHBoxLayout(None, 4, 6, "layout42")
        btm_spacer = QSpacerItem(59, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        layout42.addItem(btm_spacer)

        self.cancel_btn = QPushButton(self, "cancel_btn")
        self.cancel_btn.setAutoDefault(0)  #bruce 060703 bugfix
        layout42.addWidget(self.cancel_btn)

        self.ok_btn = QPushButton(self, "ok_btn")
        self.ok_btn.setAutoDefault(0)  #bruce 060703 bugfix
        layout42.addWidget(self.ok_btn)
        nanotube_dialogLayout.addLayout(layout42)

        self.languageChange()

        self.resize(
            QSize(246, 618).expandedTo(self.minimumSizeHint())
        )  ### this size will need to be adjusted (guess -- it's only place overall size is set)
        qt4todo('self.clearWState(Qt.WState_Polished)')

        ## self.connect(self.nt_parameters_grpbtn,SIGNAL("clicked()"),self.toggle_nt_parameters_grpbtn) ####

        # new:
        for button, methodname in (
            (self.sponsor_btn,
             'do_sponsor_btn'),  #e generalize to more than one sponsor button
            (self.done_btn, 'do_done_btn'),
            (self.abort_btn, 'do_abort_btn'),
            (self.preview_btn, 'do_preview_btn'),
            (self.whatsthis_btn, 'do_whatsthis_btn'),
            (self.cancel_btn, 'do_cancel_btn'),
            (self.ok_btn, 'do_ok_btn')):
            if hasattr(self, methodname):
                self.connect(button, SIGNAL("clicked()"),
                             getattr(self, methodname))
        return

    def languageChange(self):
        opts = self.desc.option_attrs

        self.setCaption(
            QtGui.QApplication.translate(self.__class__.__name__,
                                         opts.caption))  # was "Nanotube"
        self.heading_label.setText(
            QtGui.QApplication.translate(self.__class__.__name__,
                                         opts.title))  # was "Nanotube"
        self.sponsor_btn.setText(QString.null)

        self.done_btn.setText(QString.null)
        QToolTip.add(
            self.done_btn,
            QtGui.QApplication.translate(self.__class__.__name__, "Done"))

        self.abort_btn.setText(QString.null)
        QToolTip.add(
            self.abort_btn,
            QtGui.QApplication.translate(self.__class__.__name__, "Cancel"))

        self.preview_btn.setText(QString.null)
        QToolTip.add(
            self.preview_btn,
            QtGui.QApplication.translate(self.__class__.__name__, "Preview"))

        self.whatsthis_btn.setText(QString.null)
        QToolTip.add(
            self.whatsthis_btn,
            QtGui.QApplication.translate(self.__class__.__name__,
                                         "What's This Help"))

        ### move these up:
        ##        if 0:
        ##            self.parameters_grpbox.setTitle(QString.null)
        ##            self.nt_parameters_grpbtn.setText(QString.null)
        ##            self.parameters_grpbox_label.setText(QtGui.QApplication.translate(self.__class__.__name__, "Nanotube Parameters"))

        ##        if 0:
        ##            self.members_label.setText(QtGui.QApplication.translate(self.__class__.__name__, "Members :"))
        ##            self.length_label.setText(QtGui.QApplication.translate(self.__class__.__name__, "Length :"))
        ##            self.chirality_n_label.setText(QtGui.QApplication.translate(self.__class__.__name__, "Chirality (n) :"))
        ##            self.members_combox.clear()
        ##            self.members_combox.insertItem(QtGui.QApplication.translate(self.__class__.__name__, "C - C"))
        ##            self.members_combox.insertItem(QtGui.QApplication.translate(self.__class__.__name__, "B - N"))
        ##            self.length_linedit.setText(QtGui.QApplication.translate(self.__class__.__name__, "20.0 A"))
        ##            self.chirality_N_spinbox.setSuffix(QString.null)

        self.cancel_btn.setText(
            QtGui.QApplication.translate(self.__class__.__name__, "Cancel"))
        self.ok_btn.setText(
            QtGui.QApplication.translate(self.__class__.__name__, "OK"))
        return

    pass  # end of class parameter_dialog_or_frame -- maybe it should be renamed
Esempio n. 36
0
 def initialize():
     _up_arrow = QPixmap()
     _up_arrow.loadFromData(_up_arrow_data)
     _down_arrow = QPixmap()
     _down_arrow.loadFromData(_down_arrow_data)
Esempio n. 37
0
 def load(data):
     p = QPixmap()
     p.loadFromData(bytes(data))
     if data and p.isNull():
         p = self.failed_img
     return p
Esempio n. 38
0
class BookInfo(QDialog):

    closed = pyqtSignal(object)

    def __init__(self, parent, view, row, link_delegate):
        QDialog.__init__(self, parent)
        self.normal_brush = QBrush(Qt.white)
        self.marked_brush = QBrush(Qt.lightGray)
        self.marked = None
        self.gui = parent
        self.splitter = QSplitter(self)
        self._l = l = QVBoxLayout(self)
        self.setLayout(l)
        l.addWidget(self.splitter)

        self.cover = CoverView(self)
        self.cover.resizeEvent = self.cover_view_resized
        self.cover.cover_changed.connect(self.cover_changed)
        self.cover_pixmap = None
        self.cover.sizeHint = self.details_size_hint
        self.splitter.addWidget(self.cover)

        self.details = QWebView(self)
        self.details.sizeHint = self.details_size_hint
        self.details.page().setLinkDelegationPolicy(
            self.details.page().DelegateAllLinks)
        self.details.linkClicked.connect(self.link_clicked)
        self.css = css()
        self.link_delegate = link_delegate
        self.details.setAttribute(Qt.WA_OpaquePaintEvent, False)
        palette = self.details.palette()
        self.details.setAcceptDrops(False)
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.details.page().setPalette(palette)

        self.c = QWidget(self)
        self.c.l = l2 = QGridLayout(self.c)
        self.c.setLayout(l2)
        l2.addWidget(self.details, 0, 0, 1, -1)
        self.splitter.addWidget(self.c)

        self.fit_cover = QCheckBox(_('Fit &cover within view'), self)
        self.fit_cover.setChecked(
            gprefs.get('book_info_dialog_fit_cover', True))
        l2.addWidget(self.fit_cover, l2.rowCount(), 0, 1, -1)
        self.previous_button = QPushButton(QIcon(I('previous.png')),
                                           _('&Previous'), self)
        self.previous_button.clicked.connect(self.previous)
        l2.addWidget(self.previous_button, l2.rowCount(), 0)
        self.next_button = QPushButton(QIcon(I('next.png')), _('&Next'), self)
        self.next_button.clicked.connect(self.next)
        l2.addWidget(self.next_button, l2.rowCount() - 1, 1)

        self.view = view
        self.current_row = None
        self.refresh(row)
        self.view.selectionModel().currentChanged.connect(self.slave)
        self.fit_cover.stateChanged.connect(self.toggle_cover_fit)
        self.ns = QShortcut(QKeySequence('Alt+Right'), self)
        self.ns.activated.connect(self.next)
        self.ps = QShortcut(QKeySequence('Alt+Left'), self)
        self.ps.activated.connect(self.previous)
        self.next_button.setToolTip(
            _('Next [%s]') %
            unicode(self.ns.key().toString(QKeySequence.NativeText)))
        self.previous_button.setToolTip(
            _('Previous [%s]') %
            unicode(self.ps.key().toString(QKeySequence.NativeText)))

        geom = QCoreApplication.instance().desktop().availableGeometry(self)
        screen_height = geom.height() - 100
        screen_width = geom.width() - 100
        self.resize(max(int(screen_width / 2), 700), screen_height)
        saved_layout = gprefs.get('book_info_dialog_layout', None)
        if saved_layout is not None:
            try:
                self.restoreGeometry(saved_layout[0])
                self.splitter.restoreState(saved_layout[1])
            except Exception:
                pass

    def link_clicked(self, qurl):
        link = unicode(qurl.toString())
        self.link_delegate(link)

    def done(self, r):
        saved_layout = (bytearray(self.saveGeometry()),
                        bytearray(self.splitter.saveState()))
        gprefs.set('book_info_dialog_layout', saved_layout)
        ret = QDialog.done(self, r)
        self.view.selectionModel().currentChanged.disconnect(self.slave)
        self.view = self.link_delegate = self.gui = None
        self.closed.emit(self)
        return ret

    def cover_changed(self, data):
        if self.current_row is not None:
            id_ = self.view.model().id(self.current_row)
            self.view.model().db.set_cover(id_, data)
        if self.gui.cover_flow:
            self.gui.cover_flow.dataChanged()
        ci = self.view.currentIndex()
        if ci.isValid():
            self.view.model().current_changed(ci, ci)
        self.cover_pixmap = QPixmap()
        self.cover_pixmap.loadFromData(data)
        if self.fit_cover.isChecked():
            self.resize_cover()

    def details_size_hint(self):
        return QSize(350, 550)

    def toggle_cover_fit(self, state):
        gprefs.set('book_info_dialog_fit_cover', self.fit_cover.isChecked())
        self.resize_cover()

    def cover_view_resized(self, event):
        QTimer.singleShot(1, self.resize_cover)

    def slave(self, current, previous):
        if current.row() != previous.row():
            row = current.row()
            self.refresh(row)

    def move(self, delta=1):
        self.view.selectionModel().currentChanged.disconnect(self.slave)
        try:
            idx = self.view.currentIndex()
            if idx.isValid():
                m = self.view.model()
                ni = m.index(idx.row() + delta, idx.column())
                if ni.isValid():
                    self.view.setCurrentIndex(ni)
                    self.refresh(ni.row())
                    if self.view.isVisible():
                        self.view.scrollTo(ni)
        finally:
            self.view.selectionModel().currentChanged.connect(self.slave)

    def next(self):
        self.move()

    def previous(self):
        self.move(-1)

    def resize_cover(self):
        if self.cover_pixmap is None:
            return
        pixmap = self.cover_pixmap
        if self.fit_cover.isChecked():
            scaled, new_width, new_height = fit_image(
                pixmap.width(), pixmap.height(),
                self.cover.size().width() - 10,
                self.cover.size().height() - 10)
            if scaled:
                pixmap = pixmap.scaled(new_width, new_height,
                                       Qt.KeepAspectRatio,
                                       Qt.SmoothTransformation)
        self.cover.set_pixmap(pixmap)
        self.update_cover_tooltip()

    def update_cover_tooltip(self):
        tt = ''
        if self.marked:
            tt = _('This book is marked') if self.marked in {
                True, 'true'
            } else _('This book is marked as: %s') % self.marked
            tt += '\n\n'
        if self.cover_pixmap is not None:
            sz = self.cover_pixmap.size()
            tt += _('Cover size: %(width)d x %(height)d') % dict(
                width=sz.width(), height=sz.height())
        self.cover.setToolTip(tt)

    def refresh(self, row):
        if isinstance(row, QModelIndex):
            row = row.row()
        if row == self.current_row:
            return
        mi = self.view.model().get_book_display_info(row)
        if mi is None:
            # Indicates books was deleted from library, or row numbers have
            # changed
            return

        self.previous_button.setEnabled(False if row == 0 else True)
        self.next_button.setEnabled(False if row ==
                                    self.view.model().rowCount(QModelIndex()) -
                                    1 else True)
        self.current_row = row
        self.setWindowTitle(mi.title)
        self.cover_pixmap = QPixmap.fromImage(mi.cover_data[1])
        self.resize_cover()
        html = render_html(mi, self.css, True, self, all_fields=True)
        self.details.setHtml(html)
        self.marked = mi.marked
        self.cover.setBackgroundBrush(
            self.marked_brush if mi.marked else self.normal_brush)
        self.update_cover_tooltip()
Esempio n. 39
0
class parameter_dialog_or_frame:
    """
    use as a pre-mixin before QDialog or QFrame
    """
    ####@@@@
    def __init__(self, parent = None, desc = None, name = None, modal = 0, fl = 0, env = None, type = "QDialog"):
        if env is None:
            import foundation.env as env # this is a little weird... probably it'll be ok, and logically it seems correct.
        
        self.desc = desc

        self.typ = type
        if type == "QDialog":
            QDialog.__init__(self,parent,name,modal,fl)
        elif type == "QTextEdit":
            QTextEdit.__init__(self, parent, name)
        elif type == "QFrame":
            QFrame.__init__(self,parent,name)
        else:
            print "don't know about type == %r" % (type,)
        
        self.image1 = QPixmap()
        self.image1.loadFromData(image1_data,"PNG") # should be: title_icon ####
        self.image3 = QPixmap()
        self.image3.loadFromData(image3_data,"PNG")
        self.image4 = QPixmap()
        self.image4.loadFromData(image4_data,"PNG")
        self.image5 = QPixmap()
        self.image5.loadFromData(image5_data,"PNG")
        self.image6 = QPixmap()
        self.image6.loadFromData(image6_data,"PNG")
        self.image7 = QPixmap()
        self.image7.loadFromData(image7_data,"PNG")
        self.image0 = QPixmap(image0_data) # should be: border_icon ####
        self.image2 = QPixmap(image2_data) # should be: sponsor_pixmap ####

        try:
            ####@@@@
            title_icon_name = self.desc.options.get('title_icon')
            border_icon_name = self.desc.options.get('border_icon')
            if title_icon_name:
                self.image1 = imagename_to_pixmap(title_icon_name) ###@@@ pass icon_path
                    ###@@@ import imagename_to_pixmap or use env function
                    # or let that func itself be an arg, or have an env arg for it
                    ###e rename it icon_name_to_pixmap, or find_icon? (the latter only if it's ok if it returns an iconset)
                    ###e use iconset instead?
            if border_icon_name:
                self.image0 = imagename_to_pixmap(border_icon_name)
        except:
            print_compact_traceback("bug in icon-setting code, using fallback icons: ")
            pass

        if not name:
            self.setName("parameter_dialog_or_frame") ###

        ###k guess this will need: if type == 'QDialog'
        self.setIcon(self.image0) # should be: border_icon ####

        nanotube_dialogLayout = QVBoxLayout(self,0,0,"nanotube_dialogLayout")

        self.heading_frame = QFrame(self,"heading_frame")
        self.heading_frame.setPaletteBackgroundColor(QColor(122,122,122))
        self.heading_frame.setFrameShape(QFrame.NoFrame)
        self.heading_frame.setFrameShadow(QFrame.Plain)
        heading_frameLayout = QHBoxLayout(self.heading_frame,0,3,"heading_frameLayout")

        self.heading_pixmap = QLabel(self.heading_frame,"heading_pixmap")
        self.heading_pixmap.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed,0,0,self.heading_pixmap.sizePolicy().hasHeightForWidth()))
        self.heading_pixmap.setPixmap(self.image1) # should be: title_icon ####
        self.heading_pixmap.setScaledContents(1)
        heading_frameLayout.addWidget(self.heading_pixmap)

        self.heading_label = QLabel(self.heading_frame,"heading_label")
        self.heading_label.setPaletteForegroundColor(QColor(255,255,255))
        heading_label_font = QFont(self.heading_label.font())
        heading_label_font.setPointSize(12)
        heading_label_font.setBold(1)
        self.heading_label.setFont(heading_label_font)
        heading_frameLayout.addWidget(self.heading_label)
        nanotube_dialogLayout.addWidget(self.heading_frame)

        self.body_frame = QFrame(self,"body_frame")
        self.body_frame.setFrameShape(QFrame.StyledPanel)
        self.body_frame.setFrameShadow(QFrame.Raised)
        body_frameLayout = QVBoxLayout(self.body_frame,3,3,"body_frameLayout")

        self.sponsor_frame = QFrame(self.body_frame,"sponsor_frame")
        self.sponsor_frame.setPaletteBackgroundColor(QColor(255,255,255))
        self.sponsor_frame.setFrameShape(QFrame.StyledPanel)
        self.sponsor_frame.setFrameShadow(QFrame.Raised)
        sponsor_frameLayout = QHBoxLayout(self.sponsor_frame,0,0,"sponsor_frameLayout")

        self.sponsor_btn = QPushButton(self.sponsor_frame,"sponsor_btn")
        self.sponsor_btn.setAutoDefault(0) #bruce 060703 bugfix
        self.sponsor_btn.setSizePolicy(QSizePolicy(QSizePolicy.Preferred,QSizePolicy.Preferred,0,0,self.sponsor_btn.sizePolicy().hasHeightForWidth()))
        self.sponsor_btn.setPaletteBackgroundColor(QColor(255,255,255))
        self.sponsor_btn.setPixmap(self.image2) # should be: sponsor_pixmap #### [also we'll need to support >1 sponsor]
        self.sponsor_btn.setFlat(1)
        sponsor_frameLayout.addWidget(self.sponsor_btn)
        body_frameLayout.addWidget(self.sponsor_frame)

        layout59 = QHBoxLayout(None,0,6,"layout59")
        left_spacer = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
        layout59.addItem(left_spacer)

        self.done_btn = QToolButton(self.body_frame,"done_btn")
        self.done_btn.setIcon(QIcon(self.image3))
        layout59.addWidget(self.done_btn)

        self.abort_btn = QToolButton(self.body_frame,"abort_btn")
        self.abort_btn.setIcon(QIcon(self.image4))
        layout59.addWidget(self.abort_btn)

        self.preview_btn = QToolButton(self.body_frame,"preview_btn")
        self.preview_btn.setIcon(QIcon(self.image5))
        layout59.addWidget(self.preview_btn)

        self.whatsthis_btn = QToolButton(self.body_frame,"whatsthis_btn")
        self.whatsthis_btn.setIcon(QIcon(self.image6))
        layout59.addWidget(self.whatsthis_btn)
        right_spacer = QSpacerItem(20,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
        layout59.addItem(right_spacer)
        body_frameLayout.addLayout(layout59)

        self.groups = []
        self.param_getters = {} # map from param name to get-function (which gets current value out of its widget or controller)

        for group_desc in self.desc.kids('group'):
            
            # == start parameters_grpbox ### this will differ for Windows style

            header_refs = [] # keep python refcounted refs to all objects we make (at least the ones pyuic stored in self attrs)
            
            self.parameters_grpbox = QGroupBox(self.body_frame,"parameters_grpbox")
            self.parameters_grpbox.setFrameShape(QGroupBox.StyledPanel)
            self.parameters_grpbox.setFrameShadow(QGroupBox.Sunken)
            self.parameters_grpbox.setMargin(0)
            self.parameters_grpbox.setColumnLayout(0,Qt.Vertical)
            self.parameters_grpbox.layout().setSpacing(1)
            self.parameters_grpbox.layout().setMargin(4)
            parameters_grpboxLayout = QVBoxLayout(self.parameters_grpbox.layout())
            parameters_grpboxLayout.setAlignment(Qt.AlignTop)

            layout20 = QHBoxLayout(None,0,6,"layout20")

            self.nt_parameters_grpbtn = QPushButton(self.parameters_grpbox,"nt_parameters_grpbtn")
            self.nt_parameters_grpbtn.setSizePolicy(QSizePolicy(QSizePolicy.Minimum,QSizePolicy.Fixed,0,0,self.nt_parameters_grpbtn.sizePolicy().hasHeightForWidth()))
            self.nt_parameters_grpbtn.setMaximumSize(QSize(16,16))
            self.nt_parameters_grpbtn.setAutoDefault(0)
            self.nt_parameters_grpbtn.setIcon(QIcon(self.image7)) ### not always right, but doesn't matter
            self.nt_parameters_grpbtn.setFlat(1)
            layout20.addWidget(self.nt_parameters_grpbtn)

            self.parameters_grpbox_label = QLabel(self.parameters_grpbox,"parameters_grpbox_label")
            self.parameters_grpbox_label.setSizePolicy(QSizePolicy(QSizePolicy.Preferred,QSizePolicy.Minimum,0,0,self.parameters_grpbox_label.sizePolicy().hasHeightForWidth()))
            self.parameters_grpbox_label.setAlignment(QLabel.AlignVCenter)
            layout20.addWidget(self.parameters_grpbox_label)
            gbx_spacer1 = QSpacerItem(67,16,QSizePolicy.Expanding,QSizePolicy.Minimum)
            layout20.addItem(gbx_spacer1)
            parameters_grpboxLayout.addLayout(layout20)

            nt_parameters_body_layout = QGridLayout(None,1,1,0,6,"nt_parameters_body_layout") ### what is 6 -- is it related to number of items???
                # is it 6 in all the ones we got, but that could be a designer error so i better look it up sometime.

            # == start its kids

            # will use from above: self.parameters_grpbox, nt_parameters_body_layout
            
            nextrow = 0 # which row of the QGridLayout to start filling next (loop variable)
            hidethese = [] # set of objects to hide or show, when this group is closed or opened
            
            for param in group_desc.kids('parameter'):
                # param (a group subobj desc) is always a parameter, but we already plan to extend this beyond that,
                # so we redundantly test for this here.
                getter = None
                paramname = None
                # set these for use by uniform code at the end (e.g. for tooltips)
                editfield = None
                label = None
                if param.isa('parameter'):
                    label = QLabel(self.parameters_grpbox,"members_label")
                    label.setAlignment(QLabel.AlignVCenter | QLabel.AlignRight)
                    nt_parameters_body_layout.addWidget(label,nextrow,0)
                    hidethese.append(label)
                    thisrow = nextrow
                    nextrow += 1
                    #e following should be known in a place that knows the input language, not here
                    paramname = param.options.get('name') or (param.args and param.args[0]) or "?"
                    paramlabel = param.options.get('label') or paramname ##e wrong, label "" or none ought to be possible
                    # QtGui.QApplication.translate(self.__class__.__name__, "xyz")
                    label.setText(QtGui.QApplication.translate(self.__class__.__name__, paramlabel))
                    
                if param.isa('parameter', widget = 'combobox', type = ('str',None)):
                    self.members_combox = QComboBox(0,self.parameters_grpbox,"members_combox") ###k  what's 0?
                    editfield = self.members_combox
                    #### it probably needs a handler class, and then that could do this setup
                    self.members_combox.clear()
                    default = param.options.get('default', None) # None is not equal to any string
                    thewidgetkid = param.kids('widget')[-1] # kluge; need to think what the desc method for this should be
                    for item in thewidgetkid.kids('item'):
                        itemval = item.args[0]
                        itemtext = itemval
                        self.members_combox.insertItem(QtGui.QApplication.translate(self.__class__.__name__, itemtext)) #k __tr ok??
                        if itemval == default: #k or itemtext?
                            pass ##k i find no setItem in our py code, so not sure yet what to do for this.
                    nt_parameters_body_layout.addWidget(self.members_combox,thisrow,1)
                    hidethese.append(self.members_combox)
                    getter = (lambda combobox = self.members_combox: str(combobox.currentText()))
                        ##e due to __tr or non-str values, it might be better to use currentIndex and look it up in a table
                        # (though whether __tr is good here might depend on what it's used for)
                                    
                elif param.isa('parameter', widget = ('lineedit', None), type = ('str',None)):
                    # this covers explicit str|lineedit, and 3 default cases str, lineedit, neither.
                    # (i.e. if you say parameter and nothing else, it's str lineedit by default.)
                    self.length_linedit = QLineEdit(self.parameters_grpbox,"length_linedit")
                    editfield = self.length_linedit
                    nt_parameters_body_layout.addWidget(self.length_linedit,thisrow,1)
                    hidethese.append(self.length_linedit)
                    default = str(param.options.get('default', ""))
                    self.length_linedit.setText(QtGui.QApplication.translate(self.__class__.__name__, default)) # __tr ok?
                    getter = (lambda lineedit = self.length_linedit: str(lineedit.text()))
                    
                elif param.isa('parameter', widget = ('lineedit', None), type = 'float'):
                    self.length_linedit = QLineEdit(self.parameters_grpbox,"length_linedit")
                    editfield = self.length_linedit
                    nt_parameters_body_layout.addWidget(self.length_linedit,thisrow,1)
                    hidethese.append(self.length_linedit)
                    controller = FloatLineeditController_Qt(self, param, self.length_linedit)
                    header_refs.append(controller)
                    getter = controller.get_value
                    
                elif param.isa('parameter', widget = ('spinbox', None), type = 'int') or \
                     param.isa('parameter', widget = ('spinbox'), type = None):
                    self.chirality_N_spinbox = QSpinBox(self.parameters_grpbox,"chirality_N_spinbox") # was chirality_m_spinbox, now chirality_N_spinbox
                    editfield = self.chirality_N_spinbox
                    ### seems like Qt defaults for min and max are 0,100 -- way too small a range!
                    if param.options.has_key('min') or 1:
                        self.chirality_N_spinbox.setMinimum(param.options.get('min', -999999999)) # was 0
                    if param.options.has_key('max') or 1:
                        self.chirality_N_spinbox.setMaximum(param.options.get('max', +999999999)) # wasn't in egcode, but needed
                    self.chirality_N_spinbox.setValue(param.options.get('default', 0)) # was 5
                        ##e note: i suspect this default 0 should come from something that knows this desc grammar.
                    suffix = param.options.get('suffix', '')
                    if suffix:
                        self.chirality_N_spinbox.setSuffix(QtGui.QApplication.translate(self.__class__.__name__, suffix))
                    else:
                        self.chirality_N_spinbox.setSuffix(QString.null) # probably not needed
                    nt_parameters_body_layout.addWidget(self.chirality_N_spinbox,thisrow,1)
                    hidethese.append(self.chirality_N_spinbox)
                    getter = self.chirality_N_spinbox.value # note: it also has .text, which includes suffix
                    
                else:
                    print "didn't match:",param ###e improve this

                # things done the same way for all kinds of param-editing widgets
                if 1: #bruce 060703 moved this down here, as bugfix
                    # set tooltip (same one for editfield and label)
                    tooltip = param.options.get('tooltip', '')
                    ###e do it for more kinds of params; share the code somehow; do it in controller, or setup-aid?
                    ###k QToolTip appropriateness; tooltip option might be entirely untested
                    if tooltip and label:
                        QToolTip.add(label, QtGui.QApplication.translate(self.__class__.__name__, tooltip))
                    if tooltip and editfield:
                        QToolTip.add(editfield, QtGui.QApplication.translate(self.__class__.__name__, tooltip)) ##k ok?? review once not all params have same-row labels.
                
                if getter and paramname and paramname != '?':
                    self.param_getters[paramname] = getter
                ### also bind these params to actions...
                continue # next param

            header_refs.extend( [self.parameters_grpbox, self.nt_parameters_grpbtn, self.parameters_grpbox_label] )
            
            # now create the logic/control object for the group
            group = CollapsibleGroupController_Qt(self, group_desc, header_refs, hidethese, self.nt_parameters_grpbtn)
                ### maybe ask env for the class to use for this?
            self.groups.append(group) ### needed?? only for scanning the params, AFAIK -- oh, and to maintain a python refcount.

            # from languageChange:
            if 1: # i don't know if these are needed:
                self.parameters_grpbox.setTitle(QString.null)
                self.nt_parameters_grpbtn.setText(QString.null)
            self.parameters_grpbox_label.setText(QtGui.QApplication.translate(self.__class__.__name__, group_desc.args[0])) # was "Nanotube Parameters"
                ##e note that it's questionable in the syntax design for this property of a group (overall group label)
                # to be in that position (desc arg 0).
        
            # == end its kids
            
            parameters_grpboxLayout.addLayout(nt_parameters_body_layout)
            body_frameLayout.addWidget(self.parameters_grpbox)

            # == end parameters groupbox
            
            continue # next group

        nanotube_dialogLayout.addWidget(self.body_frame)
        spacer14 = QSpacerItem(20,20,QSizePolicy.Minimum,QSizePolicy.Expanding)
        nanotube_dialogLayout.addItem(spacer14)

        layout42 = QHBoxLayout(None,4,6,"layout42")
        btm_spacer = QSpacerItem(59,20,QSizePolicy.Expanding,QSizePolicy.Minimum)
        layout42.addItem(btm_spacer)

        self.cancel_btn = QPushButton(self,"cancel_btn")
        self.cancel_btn.setAutoDefault(0) #bruce 060703 bugfix
        layout42.addWidget(self.cancel_btn)

        self.ok_btn = QPushButton(self,"ok_btn")
        self.ok_btn.setAutoDefault(0) #bruce 060703 bugfix
        layout42.addWidget(self.ok_btn)
        nanotube_dialogLayout.addLayout(layout42)

        self.languageChange()

        self.resize(QSize(246,618).expandedTo(self.minimumSizeHint())) ### this size will need to be adjusted (guess -- it's only place overall size is set)
        qt4todo('self.clearWState(Qt.WState_Polished)')

        ## self.connect(self.nt_parameters_grpbtn,SIGNAL("clicked()"),self.toggle_nt_parameters_grpbtn) ####

        # new:
        for button, methodname in ((self.sponsor_btn, 'do_sponsor_btn'),  #e generalize to more than one sponsor button
                                   (self.done_btn, 'do_done_btn'),
                                   (self.abort_btn, 'do_abort_btn'),
                                   (self.preview_btn, 'do_preview_btn'),
                                   (self.whatsthis_btn, 'do_whatsthis_btn'),
                                   (self.cancel_btn, 'do_cancel_btn'),
                                   (self.ok_btn, 'do_ok_btn')):
            if hasattr(self, methodname):
                self.connect(button, SIGNAL("clicked()"), getattr(self, methodname))
        return


    def languageChange(self):
        opts = self.desc.option_attrs
        
        self.setCaption(QtGui.QApplication.translate(self.__class__.__name__, opts.caption)) # was "Nanotube"
        self.heading_label.setText(QtGui.QApplication.translate(self.__class__.__name__, opts.title)) # was "Nanotube"
        self.sponsor_btn.setText(QString.null)
        
        self.done_btn.setText(QString.null)
        QToolTip.add(self.done_btn,QtGui.QApplication.translate(self.__class__.__name__, "Done"))
        
        self.abort_btn.setText(QString.null)
        QToolTip.add(self.abort_btn,QtGui.QApplication.translate(self.__class__.__name__, "Cancel"))
        
        self.preview_btn.setText(QString.null)
        QToolTip.add(self.preview_btn,QtGui.QApplication.translate(self.__class__.__name__, "Preview"))
        
        self.whatsthis_btn.setText(QString.null)
        QToolTip.add(self.whatsthis_btn,QtGui.QApplication.translate(self.__class__.__name__, "What's This Help"))

        ### move these up:
##        if 0:
##            self.parameters_grpbox.setTitle(QString.null)
##            self.nt_parameters_grpbtn.setText(QString.null)
##            self.parameters_grpbox_label.setText(QtGui.QApplication.translate(self.__class__.__name__, "Nanotube Parameters"))

##        if 0:
##            self.members_label.setText(QtGui.QApplication.translate(self.__class__.__name__, "Members :"))
##            self.length_label.setText(QtGui.QApplication.translate(self.__class__.__name__, "Length :"))
##            self.chirality_n_label.setText(QtGui.QApplication.translate(self.__class__.__name__, "Chirality (n) :"))
##            self.members_combox.clear()
##            self.members_combox.insertItem(QtGui.QApplication.translate(self.__class__.__name__, "C - C"))
##            self.members_combox.insertItem(QtGui.QApplication.translate(self.__class__.__name__, "B - N"))
##            self.length_linedit.setText(QtGui.QApplication.translate(self.__class__.__name__, "20.0 A"))
##            self.chirality_N_spinbox.setSuffix(QString.null)

        self.cancel_btn.setText(QtGui.QApplication.translate(self.__class__.__name__, "Cancel"))
        self.ok_btn.setText(QtGui.QApplication.translate(self.__class__.__name__, "OK"))
        return
    
    pass # end of class parameter_dialog_or_frame -- maybe it should be renamed
Esempio n. 40
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()
        # 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,
                             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 = 36
        if self.footer and opts.margin_bottom < min_margin:
            self.log.warn('Bottom margin is too small for footer, increasing it.')
            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.')
            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)
        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()
                p.loadFromData(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')
Esempio n. 41
0
class BookInfo(QDialog, Ui_BookInfo):

    closed = pyqtSignal(object)

    def __init__(self, parent, view, row, link_delegate):
        QDialog.__init__(self, parent)
        Ui_BookInfo.__init__(self)
        self.setupUi(self)
        self.gui = parent
        self.cover_pixmap = None
        self.details.sizeHint = self.details_size_hint
        self.details.page().setLinkDelegationPolicy(self.details.page().DelegateAllLinks)
        self.details.linkClicked.connect(self.link_clicked)
        self.css = P('templates/book_details.css', data=True).decode('utf-8')
        self.link_delegate = link_delegate
        self.details.setAttribute(Qt.WA_OpaquePaintEvent, False)
        palette = self.details.palette()
        self.details.setAcceptDrops(False)
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.details.page().setPalette(palette)

        self.view = view
        self.current_row = None
        self.fit_cover.setChecked(dynamic.get('book_info_dialog_fit_cover',
            True))
        self.refresh(row)
        self.view.selectionModel().currentChanged.connect(self.slave)
        self.next_button.clicked.connect(self.next)
        self.previous_button.clicked.connect(self.previous)
        self.fit_cover.stateChanged.connect(self.toggle_cover_fit)
        self.cover.resizeEvent = self.cover_view_resized
        self.cover.cover_changed.connect(self.cover_changed)
        self.ns = QShortcut(QKeySequence('Alt+Right'), self)
        self.ns.activated.connect(self.next)
        self.ps = QShortcut(QKeySequence('Alt+Left'), self)
        self.ps.activated.connect(self.previous)
        self.next_button.setToolTip(_('Next [%s]')%
                unicode(self.ns.key().toString(QKeySequence.NativeText)))
        self.previous_button.setToolTip(_('Previous [%s]')%
                unicode(self.ps.key().toString(QKeySequence.NativeText)))

        desktop = QCoreApplication.instance().desktop()
        screen_height = desktop.availableGeometry().height() - 100
        self.resize(self.size().width(), screen_height)

    def link_clicked(self, qurl):
        link = unicode(qurl.toString())
        self.link_delegate(link)

    def done(self, r):
        ret = QDialog.done(self, r)
        self.view.selectionModel().currentChanged.disconnect(self.slave)
        self.view = self.link_delegate = self.gui = None
        self.closed.emit(self)
        return ret

    def cover_changed(self, data):
        if self.current_row is not None:
            id_ = self.view.model().id(self.current_row)
            self.view.model().db.set_cover(id_, data)
        if self.gui.cover_flow:
            self.gui.cover_flow.dataChanged()
        ci = self.view.currentIndex()
        if ci.isValid():
            self.view.model().current_changed(ci, ci)
        self.cover_pixmap = QPixmap()
        self.cover_pixmap.loadFromData(data)
        if self.fit_cover.isChecked():
            self.resize_cover()

    def details_size_hint(self):
        return QSize(350, 550)

    def toggle_cover_fit(self, state):
        dynamic.set('book_info_dialog_fit_cover', self.fit_cover.isChecked())
        self.resize_cover()

    def cover_view_resized(self, event):
        QTimer.singleShot(1, self.resize_cover)

    def slave(self, current, previous):
        if current.row() != previous.row():
            row = current.row()
            self.refresh(row)

    def move(self, delta=1):
        self.view.selectionModel().currentChanged.disconnect(self.slave)
        try:
            idx = self.view.currentIndex()
            if idx.isValid():
                m = self.view.model()
                ni = m.index(idx.row() + delta, idx.column())
                if ni.isValid():
                    self.view.setCurrentIndex(ni)
                    self.refresh(ni.row())
                    if self.view.isVisible():
                        self.view.scrollTo(ni)
        finally:
            self.view.selectionModel().currentChanged.connect(self.slave)

    def next(self):
        self.move()

    def previous(self):
        self.move(-1)

    def resize_cover(self):
        if self.cover_pixmap is None:
            return
        self.setWindowIcon(QIcon(self.cover_pixmap))
        pixmap = self.cover_pixmap
        if self.fit_cover.isChecked():
            scaled, new_width, new_height = fit_image(pixmap.width(),
                    pixmap.height(), self.cover.size().width()-10,
                    self.cover.size().height()-10)
            if scaled:
                pixmap = pixmap.scaled(new_width, new_height,
                        Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.cover.set_pixmap(pixmap)
        sz = pixmap.size()
        self.cover.setToolTip(_('Cover size: %(width)d x %(height)d')%dict(
            width=sz.width(), height=sz.height()))

    def refresh(self, row):
        if isinstance(row, QModelIndex):
            row = row.row()
        if row == self.current_row:
            return
        mi = self.view.model().get_book_display_info(row)
        if mi is None:
            # Indicates books was deleted from library, or row numbers have
            # changed
            return

        self.previous_button.setEnabled(False if row == 0 else True)
        self.next_button.setEnabled(False if row == self.view.model().rowCount(QModelIndex())-1 else True)
        self.current_row = row
        self.setWindowTitle(mi.title)
        self.title.setText('<b>'+mi.title)
        mi.title = _('Unknown')
        self.cover_pixmap = QPixmap.fromImage(mi.cover_data[1])
        self.resize_cover()
        html = render_html(mi, self.css, True, self, all_fields=True)
        self.details.setHtml(html)
Esempio n. 42
0
class BookInfo(QDialog, Ui_BookInfo):

    def __init__(self, parent, view, row, link_delegate):
        QDialog.__init__(self, parent)
        Ui_BookInfo.__init__(self)
        self.setupUi(self)
        self.gui = parent
        self.cover_pixmap = None
        self.details.sizeHint = self.details_size_hint
        self.details.page().setLinkDelegationPolicy(self.details.page().DelegateAllLinks)
        self.details.linkClicked.connect(self.link_clicked)
        self.css = P('templates/book_details.css', data=True).decode('utf-8')
        self.link_delegate = link_delegate
        self.details.setAttribute(Qt.WA_OpaquePaintEvent, False)
        palette = self.details.palette()
        self.details.setAcceptDrops(False)
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.details.page().setPalette(palette)


        self.view = view
        self.current_row = None
        self.fit_cover.setChecked(dynamic.get('book_info_dialog_fit_cover',
            True))
        self.refresh(row)
        self.connect(self.view.selectionModel(), SIGNAL('currentChanged(QModelIndex,QModelIndex)'), self.slave)
        self.connect(self.next_button, SIGNAL('clicked()'), self.next)
        self.connect(self.previous_button, SIGNAL('clicked()'), self.previous)
        self.fit_cover.stateChanged.connect(self.toggle_cover_fit)
        self.cover.resizeEvent = self.cover_view_resized
        self.cover.cover_changed.connect(self.cover_changed)
        self.ns = QShortcut(QKeySequence('Alt+Right'), self)
        self.ns.activated.connect(self.next)
        self.ps = QShortcut(QKeySequence('Alt+Left'), self)
        self.ps.activated.connect(self.previous)
        self.next_button.setToolTip(_('Next [%s]')%
                unicode(self.ns.key().toString(QKeySequence.NativeText)))
        self.previous_button.setToolTip(_('Previous [%s]')%
                unicode(self.ps.key().toString(QKeySequence.NativeText)))

        desktop = QCoreApplication.instance().desktop()
        screen_height = desktop.availableGeometry().height() - 100
        self.resize(self.size().width(), screen_height)

    def link_clicked(self, qurl):
        link = unicode(qurl.toString())
        self.link_delegate(link)

    def cover_changed(self, data):
        if self.current_row is not None:
            id_ = self.view.model().id(self.current_row)
            self.view.model().db.set_cover(id_, data)
        if self.gui.cover_flow:
            self.gui.cover_flow.dataChanged()
        ci = self.view.currentIndex()
        if ci.isValid():
            self.view.model().current_changed(ci, ci)
        self.cover_pixmap = QPixmap()
        self.cover_pixmap.loadFromData(data)
        if self.fit_cover.isChecked():
            self.resize_cover()

    def details_size_hint(self):
        return QSize(350, 550)

    def toggle_cover_fit(self, state):
        dynamic.set('book_info_dialog_fit_cover', self.fit_cover.isChecked())
        self.resize_cover()

    def cover_view_resized(self, event):
        QTimer.singleShot(1, self.resize_cover)

    def slave(self, current, previous):
        row = current.row()
        self.refresh(row)

    def next(self):
        row = self.view.currentIndex().row()
        ni = self.view.model().index(row+1, 0)
        if ni.isValid():
            self.view.setCurrentIndex(ni)

    def previous(self):
        row = self.view.currentIndex().row()
        ni = self.view.model().index(row-1, 0)
        if ni.isValid():
            self.view.setCurrentIndex(ni)

    def resize_cover(self):
        if self.cover_pixmap is None:
            return
        self.setWindowIcon(QIcon(self.cover_pixmap))
        pixmap = self.cover_pixmap
        if self.fit_cover.isChecked():
            scaled, new_width, new_height = fit_image(pixmap.width(),
                    pixmap.height(), self.cover.size().width()-10,
                    self.cover.size().height()-10)
            if scaled:
                pixmap = pixmap.scaled(new_width, new_height,
                        Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.cover.set_pixmap(pixmap)
        sz = pixmap.size()
        self.cover.setToolTip(_('Cover size: %(width)d x %(height)d')%dict(
            width=sz.width(), height=sz.height()))

    def refresh(self, row):
        if isinstance(row, QModelIndex):
            row = row.row()
        if row == self.current_row:
            return
        mi = self.view.model().get_book_display_info(row)
        if mi is None:
            # Indicates books was deleted from library, or row numbers have
            # changed
            return

        self.previous_button.setEnabled(False if row == 0 else True)
        self.next_button.setEnabled(False if row == self.view.model().rowCount(QModelIndex())-1 else True)
        self.current_row = row
        self.setWindowTitle(mi.title)
        self.title.setText('<b>'+mi.title)
        mi.title = _('Unknown')
        self.cover_pixmap = QPixmap.fromImage(mi.cover_data[1])
        self.resize_cover()
        html = render_html(mi, self.css, True, self, all_fields=True)
        self.details.setHtml(html)
Esempio n. 43
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()
        # 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,
                             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 = 36
        if self.footer and opts.margin_bottom < min_margin:
            self.log.warn(
                'Bottom margin is too small for footer, increasing it.')
            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.')
            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)
        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()
                p.loadFromData(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')
Esempio n. 44
0
class BookInfo(QDialog):

    closed = pyqtSignal(object)

    def __init__(self, parent, view, row, link_delegate):
        QDialog.__init__(self, parent)
        self.normal_brush = QBrush(Qt.white)
        self.marked_brush = QBrush(Qt.lightGray)
        self.marked = None
        self.gui = parent
        self.splitter = QSplitter(self)
        self._l = l = QVBoxLayout(self)
        self.setLayout(l)
        l.addWidget(self.splitter)

        self.cover = CoverView(self)
        self.cover.resizeEvent = self.cover_view_resized
        self.cover.cover_changed.connect(self.cover_changed)
        self.cover_pixmap = None
        self.cover.sizeHint = self.details_size_hint
        self.splitter.addWidget(self.cover)

        self.details = QWebView(self)
        self.details.sizeHint = self.details_size_hint
        self.details.page().setLinkDelegationPolicy(self.details.page().DelegateAllLinks)
        self.details.linkClicked.connect(self.link_clicked)
        s = self.details.page().settings()
        s.setAttribute(s.JavascriptEnabled, False)
        self.css = css()
        self.link_delegate = link_delegate
        self.details.setAttribute(Qt.WA_OpaquePaintEvent, False)
        palette = self.details.palette()
        self.details.setAcceptDrops(False)
        palette.setBrush(QPalette.Base, Qt.transparent)
        self.details.page().setPalette(palette)

        self.c = QWidget(self)
        self.c.l = l2 = QGridLayout(self.c)
        self.c.setLayout(l2)
        l2.addWidget(self.details, 0, 0, 1, -1)
        self.splitter.addWidget(self.c)

        self.fit_cover = QCheckBox(_('Fit &cover within view'), self)
        self.fit_cover.setChecked(gprefs.get('book_info_dialog_fit_cover', True))
        l2.addWidget(self.fit_cover, l2.rowCount(), 0, 1, -1)
        self.previous_button = QPushButton(QIcon(I('previous.png')), _('&Previous'), self)
        self.previous_button.clicked.connect(self.previous)
        l2.addWidget(self.previous_button, l2.rowCount(), 0)
        self.next_button = QPushButton(QIcon(I('next.png')), _('&Next'), self)
        self.next_button.clicked.connect(self.next)
        l2.addWidget(self.next_button, l2.rowCount() - 1, 1)

        self.view = view
        self.current_row = None
        self.refresh(row)
        self.view.selectionModel().currentChanged.connect(self.slave)
        self.fit_cover.stateChanged.connect(self.toggle_cover_fit)
        self.ns = QShortcut(QKeySequence('Alt+Right'), self)
        self.ns.activated.connect(self.next)
        self.ps = QShortcut(QKeySequence('Alt+Left'), self)
        self.ps.activated.connect(self.previous)
        self.next_button.setToolTip(_('Next [%s]')%
                unicode(self.ns.key().toString(QKeySequence.NativeText)))
        self.previous_button.setToolTip(_('Previous [%s]')%
                unicode(self.ps.key().toString(QKeySequence.NativeText)))

        geom = QCoreApplication.instance().desktop().availableGeometry(self)
        screen_height = geom.height() - 100
        screen_width = geom.width() - 100
        self.resize(max(int(screen_width/2), 700), screen_height)
        saved_layout = gprefs.get('book_info_dialog_layout', None)
        if saved_layout is not None:
            try:
                self.restoreGeometry(saved_layout[0])
                self.splitter.restoreState(saved_layout[1])
            except Exception:
                pass

    def link_clicked(self, qurl):
        link = unicode(qurl.toString())
        self.link_delegate(link)

    def done(self, r):
        saved_layout = (bytearray(self.saveGeometry()), bytearray(self.splitter.saveState()))
        gprefs.set('book_info_dialog_layout', saved_layout)
        ret = QDialog.done(self, r)
        self.view.selectionModel().currentChanged.disconnect(self.slave)
        self.view = self.link_delegate = self.gui = None
        self.closed.emit(self)
        return ret

    def cover_changed(self, data):
        if self.current_row is not None:
            id_ = self.view.model().id(self.current_row)
            self.view.model().db.set_cover(id_, data)
        if self.gui.cover_flow:
            self.gui.cover_flow.dataChanged()
        ci = self.view.currentIndex()
        if ci.isValid():
            self.view.model().current_changed(ci, ci)
        self.cover_pixmap = QPixmap()
        self.cover_pixmap.loadFromData(data)
        if self.fit_cover.isChecked():
            self.resize_cover()

    def details_size_hint(self):
        return QSize(350, 550)

    def toggle_cover_fit(self, state):
        gprefs.set('book_info_dialog_fit_cover', self.fit_cover.isChecked())
        self.resize_cover()

    def cover_view_resized(self, event):
        QTimer.singleShot(1, self.resize_cover)

    def slave(self, current, previous):
        if current.row() != previous.row():
            row = current.row()
            self.refresh(row)

    def move(self, delta=1):
        self.view.selectionModel().currentChanged.disconnect(self.slave)
        try:
            idx = self.view.currentIndex()
            if idx.isValid():
                m = self.view.model()
                ni = m.index(idx.row() + delta, idx.column())
                if ni.isValid():
                    self.view.setCurrentIndex(ni)
                    self.refresh(ni.row())
                    if self.view.isVisible():
                        self.view.scrollTo(ni)
        finally:
            self.view.selectionModel().currentChanged.connect(self.slave)

    def next(self):
        self.move()

    def previous(self):
        self.move(-1)

    def resize_cover(self):
        if self.cover_pixmap is None:
            return
        pixmap = self.cover_pixmap
        if self.fit_cover.isChecked():
            scaled, new_width, new_height = fit_image(pixmap.width(),
                    pixmap.height(), self.cover.size().width()-10,
                    self.cover.size().height()-10)
            if scaled:
                pixmap = pixmap.scaled(new_width, new_height,
                        Qt.KeepAspectRatio, Qt.SmoothTransformation)
        self.cover.set_pixmap(pixmap)
        self.update_cover_tooltip()

    def update_cover_tooltip(self):
        tt = ''
        if self.marked:
            tt = _('This book is marked') if self.marked in {True, 'true'} else _(
                'This book is marked as: %s') % self.marked
            tt += '\n\n'
        if self.cover_pixmap is not None:
            sz = self.cover_pixmap.size()
            tt += _('Cover size: %(width)d x %(height)d')%dict(width=sz.width(), height=sz.height())
        self.cover.setToolTip(tt)

    def refresh(self, row):
        if isinstance(row, QModelIndex):
            row = row.row()
        if row == self.current_row:
            return
        mi = self.view.model().get_book_display_info(row)
        if mi is None:
            # Indicates books was deleted from library, or row numbers have
            # changed
            return

        self.previous_button.setEnabled(False if row == 0 else True)
        self.next_button.setEnabled(False if row == self.view.model().rowCount(QModelIndex())-1 else True)
        self.current_row = row
        self.setWindowTitle(mi.title)
        self.cover_pixmap = QPixmap.fromImage(mi.cover_data[1])
        self.resize_cover()
        html = render_html(mi, self.css, True, self, all_fields=True)
        self.details.setHtml(html)
        self.marked = mi.marked
        self.cover.setBackgroundBrush(self.marked_brush if mi.marked else self.normal_brush)
        self.update_cover_tooltip()
Esempio n. 45
0
 def load(data):
     p = QPixmap()
     p.loadFromData(bytes(data))
     if data and p.isNull():
         p = self.failed_img
     return p