示例#1
0
    def build(self, container, preserve_state=True):
        if preserve_state:
            state = self.get_state()
        self.clear()
        self.root = self.invisibleRootItem()
        self.root.setFlags(Qt.ItemIsDragEnabled)
        self.categories = {}
        for category, text in (
            ('text', _('Text')),
            ('styles', _('Styles')),
            ('images', _('Images')),
            ('fonts', _('Fonts')),
            ('misc', _('Miscellaneous')),
        ):
            self.categories[category] = i = QTreeWidgetItem(self.root, 0)
            i.setText(0, text)
            i.setData(0, Qt.DecorationRole,
                      self.top_level_pixmap_cache[category])
            f = i.font(0)
            f.setBold(True)
            i.setFont(0, f)
            i.setData(0, NAME_ROLE, category)
            flags = Qt.ItemIsEnabled
            if category == 'text':
                flags |= Qt.ItemIsDropEnabled
            i.setFlags(flags)

        processed, seen = {}, {}

        cover_page_name = get_cover_page_name(container)
        cover_image_name = get_raster_cover_name(container)
        manifested_names = set()
        for names in container.manifest_type_map.itervalues():
            manifested_names |= set(names)

        def get_category(name, mt):
            category = 'misc'
            if mt.startswith('image/'):
                category = 'images'
            elif mt in OEB_FONTS:
                category = 'fonts'
            elif mt in OEB_STYLES:
                category = 'styles'
            elif mt in OEB_DOCS:
                category = 'text'
            ext = name.rpartition('.')[-1].lower()
            if ext in {'ttf', 'otf', 'woff'}:
                # Probably wrong mimetype in the OPF
                category = 'fonts'
            return category

        def set_display_name(name, item):
            if name in processed:
                # We have an exact duplicate (can happen if there are
                # duplicates in the spine)
                item.setText(0, processed[name].text(0))
                item.setText(1, processed[name].text(1))
                return

            parts = name.split('/')
            text = parts[-1]
            while text in seen and parts:
                text = parts.pop() + '/' + text
            seen[text] = item
            item.setText(0, text)
            item.setText(1, hexlify(sort_key(text)))

        def render_emblems(item, emblems):
            emblems = tuple(emblems)
            if not emblems:
                return
            icon = self.rendered_emblem_cache.get(emblems, None)
            if icon is None:
                pixmaps = []
                for emblem in emblems:
                    pm = self.emblem_cache.get(emblem, None)
                    if pm is None:
                        pm = self.emblem_cache[emblem] = QPixmap(
                            I(emblem)).scaled(
                                self.iconSize(),
                                transformMode=Qt.SmoothTransformation)
                    pixmaps.append(pm)
                num = len(pixmaps)
                w, h = pixmaps[0].width(), pixmaps[0].height()
                if num == 1:
                    icon = self.rendered_emblem_cache[emblems] = QIcon(
                        pixmaps[0])
                else:
                    canvas = QPixmap((num * w) + ((num - 1) * 2), h)
                    canvas.fill(Qt.transparent)
                    painter = QPainter(canvas)
                    for i, pm in enumerate(pixmaps):
                        painter.drawPixmap(i * (w + 2), 0, pm)
                    painter.end()
                    icon = self.rendered_emblem_cache[emblems] = canvas
            item.setData(0, Qt.DecorationRole, icon)

        cannot_be_renamed = container.names_that_must_not_be_changed
        ncx_mime = guess_type('a.ncx')

        def create_item(name, linear=None):
            imt = container.mime_map.get(name, guess_type(name))
            icat = get_category(name, imt)
            category = 'text' if linear is not None else ({
                'text': 'misc'
            }.get(icat, icat))
            item = QTreeWidgetItem(
                self.categories['text' if linear is not None else category], 1)
            flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
            if category == 'text':
                flags |= Qt.ItemIsDragEnabled
            if name not in cannot_be_renamed:
                flags |= Qt.ItemIsEditable
            item.setFlags(flags)
            item.setStatusTip(0, _('Full path: ') + name)
            item.setData(0, NAME_ROLE, name)
            item.setData(0, CATEGORY_ROLE, category)
            item.setData(0, LINEAR_ROLE, bool(linear))
            item.setData(0, MIME_ROLE, imt)
            set_display_name(name, item)
            tooltips = []
            emblems = []
            if name in {cover_page_name, cover_image_name}:
                emblems.append('default_cover.png')
                tooltips.append(
                    _('This file is the cover %s for this book') %
                    (_('image') if name == cover_image_name else _('page')))
            if name in container.opf_name:
                emblems.append('metadata.png')
                tooltips.append(
                    _('This file contains all the metadata and book structure information'
                      ))
            if imt == ncx_mime:
                emblems.append('toc.png')
                tooltips.append(
                    _('This file contains the metadata table of contents'))
            if name not in manifested_names and not container.ok_to_be_unmanifested(
                    name):
                emblems.append('dialog_question.png')
                tooltips.append(
                    _('This file is not listed in the book manifest'))
            if linear is False:
                emblems.append('arrow-down.png')
                tooltips.append(
                    _('This file is marked as non-linear in the spine\nDrag it to the top to make it linear'
                      ))
            if linear is None and icat == 'text':
                # Text item outside spine
                emblems.append('dialog_warning.png')
                tooltips.append(
                    _('This file is a text file that is not referenced in the spine'
                      ))
            if category == 'text' and name in processed:
                # Duplicate entry in spine
                emblems.append('dialog_error.png')
                tooltips.append(
                    _('This file occurs more than once in the spine'))

            render_emblems(item, emblems)
            if tooltips:
                item.setData(0, Qt.ToolTipRole, '\n'.join(tooltips))
            return item

        for name, linear in container.spine_names:
            processed[name] = create_item(name, linear=linear)

        for name in container.name_path_map:
            if name in processed:
                continue
            processed[name] = create_item(name)

        for name, c in self.categories.iteritems():
            c.setExpanded(True)
            if name != 'text':
                c.sortChildren(1, Qt.AscendingOrder)

        if preserve_state:
            self.set_state(state)

        if self.current_edited_name:
            item = self.item_from_name(self.current_edited_name)
            if item is not None:
                self.mark_item_as_current(item)
示例#2
0
    def build(self, container, preserve_state=True):
        if preserve_state:
            state = self.get_state()
        self.clear()
        self.root = self.invisibleRootItem()
        self.root.setFlags(Qt.ItemIsDragEnabled)
        self.categories = {}
        for category, text in (
            ("text", _("Text")),
            ("styles", _("Styles")),
            ("images", _("Images")),
            ("fonts", _("Fonts")),
            ("misc", _("Miscellaneous")),
        ):
            self.categories[category] = i = QTreeWidgetItem(self.root, 0)
            i.setText(0, text)
            i.setData(0, Qt.DecorationRole, self.top_level_pixmap_cache[category])
            f = i.font(0)
            f.setBold(True)
            i.setFont(0, f)
            i.setData(0, NAME_ROLE, category)
            flags = Qt.ItemIsEnabled
            if category == "text":
                flags |= Qt.ItemIsDropEnabled
            i.setFlags(flags)

        processed, seen = {}, {}

        cover_page_name = get_cover_page_name(container)
        cover_image_name = get_raster_cover_name(container)
        manifested_names = set()
        for names in container.manifest_type_map.itervalues():
            manifested_names |= set(names)

        font_types = {guess_type("a." + x) for x in ("ttf", "otf", "woff")}

        def get_category(name, mt):
            category = "misc"
            if mt.startswith("image/"):
                category = "images"
            elif mt in font_types:
                category = "fonts"
            elif mt in OEB_STYLES:
                category = "styles"
            elif mt in OEB_DOCS:
                category = "text"
            ext = name.rpartition(".")[-1].lower()
            if ext in {"ttf", "otf", "woff"}:
                # Probably wrong mimetype in the OPF
                category = "fonts"
            return category

        def set_display_name(name, item):
            if name in processed:
                # We have an exact duplicate (can happen if there are
                # duplicates in the spine)
                item.setText(0, processed[name].text(0))
                item.setText(1, processed[name].text(1))
                return

            parts = name.split("/")
            text = parts[-1]
            while text in seen and parts:
                text = parts.pop() + "/" + text
            seen[text] = item
            item.setText(0, text)
            item.setText(1, hexlify(sort_key(text)))

        def render_emblems(item, emblems):
            emblems = tuple(emblems)
            if not emblems:
                return
            icon = self.rendered_emblem_cache.get(emblems, None)
            if icon is None:
                pixmaps = []
                for emblem in emblems:
                    pm = self.emblem_cache.get(emblem, None)
                    if pm is None:
                        pm = self.emblem_cache[emblem] = QPixmap(I(emblem)).scaled(
                            self.iconSize(), transformMode=Qt.SmoothTransformation
                        )
                    pixmaps.append(pm)
                num = len(pixmaps)
                w, h = pixmaps[0].width(), pixmaps[0].height()
                if num == 1:
                    icon = self.rendered_emblem_cache[emblems] = QIcon(pixmaps[0])
                else:
                    canvas = QPixmap((num * w) + ((num - 1) * 2), h)
                    canvas.fill(Qt.transparent)
                    painter = QPainter(canvas)
                    for i, pm in enumerate(pixmaps):
                        painter.drawPixmap(i * (w + 2), 0, pm)
                    painter.end()
                    icon = self.rendered_emblem_cache[emblems] = canvas
            item.setData(0, Qt.DecorationRole, icon)

        ok_to_be_unmanifested = container.names_that_need_not_be_manifested
        cannot_be_renamed = container.names_that_must_not_be_changed

        def create_item(name, linear=None):
            imt = container.mime_map.get(name, guess_type(name))
            icat = get_category(name, imt)
            category = "text" if linear is not None else ({"text": "misc"}.get(icat, icat))
            item = QTreeWidgetItem(self.categories["text" if linear is not None else category], 1)
            flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
            if category == "text":
                flags |= Qt.ItemIsDragEnabled
            if name not in cannot_be_renamed:
                flags |= Qt.ItemIsEditable
            item.setFlags(flags)
            item.setStatusTip(0, _("Full path: ") + name)
            item.setData(0, NAME_ROLE, name)
            item.setData(0, CATEGORY_ROLE, category)
            item.setData(0, LINEAR_ROLE, bool(linear))
            item.setData(0, MIME_ROLE, imt)
            set_display_name(name, item)
            # TODO: Add appropriate tooltips based on the emblems
            emblems = []
            if name in {cover_page_name, cover_image_name}:
                emblems.append("default_cover.png")
            if name not in manifested_names and name not in ok_to_be_unmanifested:
                emblems.append("dialog_question.png")
            if linear is False:
                emblems.append("arrow-down.png")
            if linear is None and icat == "text":
                # Text item outside spine
                emblems.append("dialog_warning.png")
            if category == "text" and name in processed:
                # Duplicate entry in spine
                emblems.append("dialog_warning.png")

            render_emblems(item, emblems)
            return item

        for name, linear in container.spine_names:
            processed[name] = create_item(name, linear=linear)

        all_files = list(container.manifest_type_map.iteritems())
        all_files.append((guess_type("a.opf"), [container.opf_name]))

        for name in container.name_path_map:
            if name in processed:
                continue
            processed[name] = create_item(name)

        for name, c in self.categories.iteritems():
            c.setExpanded(True)
            if name != "text":
                c.sortChildren(1, Qt.AscendingOrder)

        if preserve_state:
            self.set_state(state)
示例#3
0
    def build(self, container, preserve_state=True):
        if container is None:
            return
        if preserve_state:
            state = self.get_state()
        self.clear()
        self.root = self.invisibleRootItem()
        self.root.setFlags(Qt.ItemIsDragEnabled)
        self.categories = {}
        for category, text, __ in CATEGORIES:
            self.categories[category] = i = QTreeWidgetItem(self.root, 0)
            i.setText(0, text)
            i.setData(0, Qt.DecorationRole, self.top_level_pixmap_cache[category])
            f = i.font(0)
            f.setBold(True)
            i.setFont(0, f)
            i.setData(0, NAME_ROLE, category)
            flags = Qt.ItemIsEnabled
            if category == 'text':
                flags |= Qt.ItemIsDropEnabled
            i.setFlags(flags)

        processed, seen = {}, {}

        cover_page_name = get_cover_page_name(container)
        cover_image_name = get_raster_cover_name(container)
        manifested_names = set()
        for names in container.manifest_type_map.itervalues():
            manifested_names |= set(names)

        def get_category(name, mt):
            category = 'misc'
            if mt.startswith('image/'):
                category = 'images'
            elif mt in OEB_FONTS:
                category = 'fonts'
            elif mt in OEB_STYLES:
                category = 'styles'
            elif mt in OEB_DOCS:
                category = 'text'
            ext = name.rpartition('.')[-1].lower()
            if ext in {'ttf', 'otf', 'woff'}:
                # Probably wrong mimetype in the OPF
                category = 'fonts'
            return category

        def set_display_name(name, item):
            if tprefs['file_list_shows_full_pathname']:
                text = name
            else:
                if name in processed:
                    # We have an exact duplicate (can happen if there are
                    # duplicates in the spine)
                    item.setText(0, processed[name].text(0))
                    item.setText(1, processed[name].text(1))
                    return

                parts = name.split('/')
                text = parts.pop()
                while text in seen and parts:
                    text = parts.pop() + '/' + text

            seen[text] = item
            item.setText(0, text)
            item.setText(1, hexlify(sort_key(text)))

        def render_emblems(item, emblems):
            emblems = tuple(emblems)
            if not emblems:
                return
            icon = self.rendered_emblem_cache.get(emblems, None)
            if icon is None:
                pixmaps = []
                for emblem in emblems:
                    pm = self.emblem_cache.get(emblem, None)
                    if pm is None:
                        pm = self.emblem_cache[emblem] = QIcon(I(emblem)).pixmap(self.iconSize())
                    pixmaps.append(pm)
                num = len(pixmaps)
                w, h = pixmaps[0].width(), pixmaps[0].height()
                if num == 1:
                    icon = self.rendered_emblem_cache[emblems] = QIcon(pixmaps[0])
                else:
                    canvas = QPixmap((num * w) + ((num-1)*2), h)
                    canvas.setDevicePixelRatio(pixmaps[0].devicePixelRatio())
                    canvas.fill(Qt.transparent)
                    painter = QPainter(canvas)
                    for i, pm in enumerate(pixmaps):
                        painter.drawPixmap(int(i * (w + 2)/canvas.devicePixelRatio()), 0, pm)
                    painter.end()
                    icon = self.rendered_emblem_cache[emblems] = canvas
            item.setData(0, Qt.DecorationRole, icon)

        cannot_be_renamed = container.names_that_must_not_be_changed
        ncx_mime = guess_type('a.ncx')
        nav_items = frozenset(container.manifest_items_with_property('nav'))

        def create_item(name, linear=None):
            imt = container.mime_map.get(name, guess_type(name))
            icat = get_category(name, imt)
            category = 'text' if linear is not None else ({'text':'misc'}.get(icat, icat))
            item = QTreeWidgetItem(self.categories['text' if linear is not None else category], 1)
            flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
            if category == 'text':
                flags |= Qt.ItemIsDragEnabled
            if name not in cannot_be_renamed:
                flags |= Qt.ItemIsEditable
            item.setFlags(flags)
            item.setStatusTip(0, _('Full path: ') + name)
            item.setData(0, NAME_ROLE, name)
            item.setData(0, CATEGORY_ROLE, category)
            item.setData(0, LINEAR_ROLE, bool(linear))
            item.setData(0, MIME_ROLE, imt)
            set_display_name(name, item)
            tooltips = []
            emblems = []
            if name in {cover_page_name, cover_image_name}:
                emblems.append('default_cover.png')
                tooltips.append(_('This file is the cover %s for this book') % (_('image') if name == cover_image_name else _('page')))
            if name in container.opf_name:
                emblems.append('metadata.png')
                tooltips.append(_('This file contains all the metadata and book structure information'))
            if imt == ncx_mime or name in nav_items:
                emblems.append('toc.png')
                tooltips.append(_('This file contains the metadata table of contents'))
            if name not in manifested_names and not container.ok_to_be_unmanifested(name):
                emblems.append('dialog_question.png')
                tooltips.append(_('This file is not listed in the book manifest'))
            if linear is False:
                emblems.append('arrow-down.png')
                tooltips.append(_('This file is marked as non-linear in the spine\nDrag it to the top to make it linear'))
            if linear is None and icat == 'text':
                # Text item outside spine
                emblems.append('dialog_warning.png')
                tooltips.append(_('This file is a text file that is not referenced in the spine'))
            if category == 'text' and name in processed:
                # Duplicate entry in spine
                emblems.append('dialog_error.png')
                tooltips.append(_('This file occurs more than once in the spine'))

            render_emblems(item, emblems)
            if tooltips:
                item.setData(0, Qt.ToolTipRole, '\n'.join(tooltips))
            return item

        for name, linear in container.spine_names:
            processed[name] = create_item(name, linear=linear)

        for name in container.name_path_map:
            if name in processed:
                continue
            processed[name] = create_item(name)

        for name, c in self.categories.iteritems():
            c.setExpanded(True)
            if name != 'text':
                c.sortChildren(1, Qt.AscendingOrder)

        if preserve_state:
            self.set_state(state)

        if self.current_edited_name:
            item = self.item_from_name(self.current_edited_name)
            if item is not None:
                self.mark_item_as_current(item)
示例#4
0
    def build(self, container, preserve_state=True):
        if preserve_state:
            state = self.get_state()
        self.clear()
        self.root = self.invisibleRootItem()
        self.root.setFlags(Qt.ItemIsDragEnabled)
        self.categories = {}
        for category, text in (
            ('text', _('Text')),
            ('styles', _('Styles')),
            ('images', _('Images')),
            ('fonts', _('Fonts')),
            ('misc', _('Miscellaneous')),
        ):
            self.categories[category] = i = QTreeWidgetItem(self.root, 0)
            i.setText(0, text)
            i.setData(0, Qt.DecorationRole, self.top_level_pixmap_cache[category])
            f = i.font(0)
            f.setBold(True)
            i.setFont(0, f)
            i.setData(0, NAME_ROLE, category)
            flags = Qt.ItemIsEnabled
            if category == 'text':
                flags |= Qt.ItemIsDropEnabled
            i.setFlags(flags)

        processed, seen = {}, {}

        cover_page_name = get_cover_page_name(container)
        cover_image_name = get_raster_cover_name(container)
        manifested_names = set()
        for names in container.manifest_type_map.itervalues():
            manifested_names |= set(names)

        font_types = {guess_type('a.'+x) for x in ('ttf', 'otf', 'woff')}

        def get_category(mt):
            category = 'misc'
            if mt.startswith('image/'):
                category = 'images'
            elif mt in font_types:
                category = 'fonts'
            elif mt in OEB_STYLES:
                category = 'styles'
            elif mt in OEB_DOCS:
                category = 'text'
            return category

        def set_display_name(name, item):
            if name in processed:
                # We have an exact duplicate (can happen if there are
                # duplicates in the spine)
                item.setText(0, processed[name].text(0))
                return

            parts = name.split('/')
            text = parts[-1]
            while text in seen and parts:
                text = parts.pop() + '/' + text
            seen[text] = item
            item.setText(0, text)

        def render_emblems(item, emblems):
            emblems = tuple(emblems)
            if not emblems:
                return
            icon = self.rendered_emblem_cache.get(emblems, None)
            if icon is None:
                pixmaps = []
                for emblem in emblems:
                    pm = self.emblem_cache.get(emblem, None)
                    if pm is None:
                        pm = self.emblem_cache[emblem] = QPixmap(
                            I(emblem)).scaled(self.iconSize(), transformMode=Qt.SmoothTransformation)
                    pixmaps.append(pm)
                num = len(pixmaps)
                w, h = pixmaps[0].width(), pixmaps[0].height()
                if num == 1:
                    icon = self.rendered_emblem_cache[emblems] = QIcon(pixmaps[0])
                else:
                    canvas = QPixmap((num * w) + ((num-1)*2), h)
                    canvas.fill(Qt.transparent)
                    painter = QPainter(canvas)
                    for i, pm in enumerate(pixmaps):
                        painter.drawPixmap(i * (w + 2), 0, pm)
                    painter.end()
                    icon = self.rendered_emblem_cache[emblems] = canvas
            item.setData(0, Qt.DecorationRole, icon)

        ok_to_be_unmanifested = container.names_that_need_not_be_manifested

        def create_item(name, linear=None):
            imt = container.mime_map.get(name, guess_type(name))
            icat = get_category(imt)
            category = 'text' if linear is not None else ({'text':'misc'}.get(icat, icat))
            item = QTreeWidgetItem(self.categories['text' if linear is not None else category], 1)
            flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
            if category == 'text':
                flags |= Qt.ItemIsDragEnabled
            item.setFlags(flags)
            item.setStatusTip(0, _('Full path: ') + name)
            item.setData(0, NAME_ROLE, name)
            item.setData(0, CATEGORY_ROLE, category)
            set_display_name(name, item)
            # TODO: Add appropriate tooltips based on the emblems
            emblems = []
            if name in {cover_page_name, cover_image_name}:
                emblems.append('default_cover.png')
            if name not in manifested_names and name not in ok_to_be_unmanifested:
                emblems.append('dialog_question.png')
            if linear is False:
                emblems.append('arrow-down.png')
            if linear is None and icat == 'text':
                # Text item outside spine
                emblems.append('dialog_warning.png')
            if category == 'text' and name in processed:
                # Duplicate entry in spine
                emblems.append('dialog_warning.png')

            render_emblems(item, emblems)
            return item

        for name, linear in container.spine_names:
            processed[name] = create_item(name, linear=linear)

        all_files = list(container.manifest_type_map.iteritems())
        all_files.append((guess_type('a.opf'), [container.opf_name]))

        for name in container.name_path_map:
            if name in processed:
                continue
            processed[name] = create_item(name)

        for c in self.categories.itervalues():
            c.setExpanded(True)

        if preserve_state:
            self.set_state(state)