Esempio n. 1
0
    def show_context_menu(self, point):
        item = self.itemAt(point)
        if item is None or item in set(self.categories.itervalues()):
            return
        m = QMenu(self)
        sel = self.selectedItems()
        num = len(sel)
        if num > 0:
            m.addAction(QIcon(I('trash.png')), _('&Delete selected files'), self.request_delete)
        ci = self.currentItem()
        if ci is not None:
            cn = unicode(ci.data(0, NAME_ROLE).toString())
            mt = unicode(ci.data(0, MIME_ROLE).toString())
            cat = unicode(ci.data(0, CATEGORY_ROLE).toString())
            m.addAction(QIcon(I('modified.png')), _('&Rename %s') % (elided_text(self.font(), cn)), self.edit_current_item)
            if is_raster_image(mt):
                m.addAction(QIcon(I('default_cover.png')), _('Mark %s as cover image') % elided_text(self.font(), cn), partial(self.mark_as_cover, cn))
            elif current_container().SUPPORTS_TITLEPAGES and mt in OEB_DOCS and cat == 'text':
                m.addAction(QIcon(I('default_cover.png')), _('Mark %s as title/cover page') % elided_text(self.font(), cn), partial(self.mark_as_titlepage, cn))

        selected_map = defaultdict(list)
        for item in sel:
            selected_map[unicode(item.data(0, CATEGORY_ROLE).toString())].append(unicode(item.data(0, NAME_ROLE).toString()))

        for items in selected_map.itervalues():
            items.sort(key=self.index_of_name)

        if len(selected_map['text']) > 1:
            m.addAction(QIcon(I('merge.png')), _('&Merge selected text files'), partial(self.start_merge, 'text', selected_map['text']))
        if len(selected_map['styles']) > 1:
            m.addAction(QIcon(I('merge.png')), _('&Merge selected style files'), partial(self.start_merge, 'styles', selected_map['styles']))

        if len(list(m.actions())) > 0:
            m.popup(self.mapToGlobal(point))
Esempio n. 2
0
 def replace(self, name):
     c = current_container()
     mt = c.mime_map[name]
     oext = name.rpartition(".")[-1].lower()
     filters = [oext]
     fname = _("Files")
     if mt in OEB_DOCS:
         fname = _("HTML Files")
         filters = "html htm xhtm xhtml shtml".split()
     elif is_raster_image(mt):
         fname = _("Images")
         filters = "jpeg jpg gif png".split()
     path = choose_files(
         self, "tweak_book_import_file", _("Choose file"), filters=[(fname, filters)], select_only_single_file=True
     )
     if not path:
         return
     path = path[0]
     ext = path.rpartition(".")[-1].lower()
     force_mt = None
     if mt in OEB_DOCS:
         force_mt = c.guess_type("a.html")
     nname = os.path.basename(path)
     nname, ext = nname.rpartition(".")[0::2]
     nname = nname + "." + ext.lower()
     self.replace_requested.emit(name, path, nname, force_mt)
Esempio n. 3
0
def run_checks(container):

    errors = []

    # Check parsing
    xml_items, html_items, raster_images, stylesheets = [], [], [], []
    for name, mt in container.mime_map.iteritems():
        items = None
        if mt in XML_TYPES:
            items = xml_items
        elif mt in OEB_DOCS:
            items = html_items
        elif mt in OEB_STYLES:
            items = stylesheets
        elif is_raster_image(mt):
            items = raster_images
        if items is not None:
            items.append((name, mt, container.open(name, "rb").read()))
    errors.extend(run_checkers(check_html_size, html_items))
    errors.extend(run_checkers(check_xml_parsing, xml_items))
    errors.extend(run_checkers(check_xml_parsing, html_items))
    errors.extend(run_checkers(check_raster_images, raster_images))

    for err in errors:
        if err.level > WARN:
            return errors

    # cssutils is not thread safe
    for name, mt, raw in stylesheets:
        if not raw:
            errors.append(EmptyFile(name))
            continue
        errors.extend(check_css_parsing(name, raw))

    for name, mt, raw in html_items + xml_items:
        errors.extend(check_encoding_declarations(name, container))

    for name, mt, raw in html_items:
        if not raw:
            continue
        root = container.parsed(name)
        for style in root.xpath('//*[local-name()="style"]'):
            if style.get("type", "text/css") == "text/css" and style.text:
                errors.extend(check_css_parsing(name, style.text, line_offset=style.sourceline - 1))
        for elem in root.xpath("//*[@style]"):
            raw = elem.get("style")
            if raw:
                errors.extend(check_css_parsing(name, raw, line_offset=elem.sourceline - 1, is_declaration=True))

    errors += check_mimetypes(container)
    errors += check_links(container) + check_link_destinations(container)
    errors += check_fonts(container)
    errors += check_filenames(container)
    errors += check_ids(container)
    errors += check_markup(container)
    errors += check_opf(container)

    return errors
Esempio n. 4
0
    def show_context_menu(self, point):
        item = self.itemAt(point)
        if item is None or item in set(self.categories.itervalues()):
            return
        m = QMenu(self)
        sel = self.selectedItems()
        num = len(sel)
        container = current_container()
        ci = self.currentItem()
        if ci is not None:
            cn = unicode(ci.data(0, NAME_ROLE) or '')
            mt = unicode(ci.data(0, MIME_ROLE) or '')
            cat = unicode(ci.data(0, CATEGORY_ROLE) or '')
            n = elided_text(cn.rpartition('/')[-1])
            m.addAction(QIcon(I('save.png')), _('Export %s') % n, partial(self.export, cn))
            if cn not in container.names_that_must_not_be_changed and cn not in container.names_that_must_not_be_removed and mt not in OEB_FONTS:
                m.addAction(_('Replace %s with file...') % n, partial(self.replace, cn))
            if num > 1:
                m.addAction(QIcon(I('save.png')), _('Export all %d selected files') % num, self.export_selected)

            m.addSeparator()

            m.addAction(QIcon(I('modified.png')), _('&Rename %s') % n, self.edit_current_item)
            if is_raster_image(mt):
                m.addAction(QIcon(I('default_cover.png')), _('Mark %s as cover image') % n, partial(self.mark_as_cover, cn))
            elif current_container().SUPPORTS_TITLEPAGES and mt in OEB_DOCS and cat == 'text':
                m.addAction(QIcon(I('default_cover.png')), _('Mark %s as cover page') % n, partial(self.mark_as_titlepage, cn))
            m.addSeparator()

        if num > 0:
            m.addSeparator()
            if num > 1:
                m.addAction(QIcon(I('modified.png')), _('&Bulk rename the selected files'), self.request_bulk_rename)
            m.addAction(QIcon(I('modified.png')), _('Change the file extension for the selected files'), self.request_change_ext)
            m.addAction(QIcon(I('trash.png')), ngettext(
                '&Delete the selected file', '&Delete the {} selected files', num).format(num), self.request_delete)
            m.addAction(QIcon(I('edit-copy.png')), ngettext(
                '&Copy the selected file to another editor instance',
                '&Copy the {} selected files to another editor instance', num).format(num), self.copy_selected_files)
            m.addSeparator()

        selected_map = defaultdict(list)
        for item in sel:
            selected_map[unicode(item.data(0, CATEGORY_ROLE) or '')].append(unicode(item.data(0, NAME_ROLE) or ''))

        for items in selected_map.itervalues():
            items.sort(key=self.index_of_name)

        if selected_map['text']:
            m.addAction(QIcon(I('format-text-color.png')), _('Link &stylesheets...'), partial(self.link_stylesheets, selected_map['text']))

        if len(selected_map['text']) > 1:
            m.addAction(QIcon(I('merge.png')), _('&Merge selected text files'), partial(self.start_merge, 'text', selected_map['text']))
        if len(selected_map['styles']) > 1:
            m.addAction(QIcon(I('merge.png')), _('&Merge selected style files'), partial(self.start_merge, 'styles', selected_map['styles']))

        if len(list(m.actions())) > 0:
            m.popup(self.mapToGlobal(point))
Esempio n. 5
0
def run_checks(container):

    errors = []

    # Check parsing
    xml_items, html_items, raster_images, stylesheets = [], [], [], []
    for name, mt in container.mime_map.iteritems():
        items = None
        if mt in XML_TYPES:
            items = xml_items
        elif mt in OEB_DOCS:
            items = html_items
        elif mt in OEB_STYLES:
            items = stylesheets
        elif is_raster_image(mt):
            items = raster_images
        if items is not None:
            items.append((name, mt, container.open(name, 'rb').read()))
    errors.extend(run_checkers(check_html_size, html_items))
    errors.extend(run_checkers(check_xml_parsing, xml_items))
    errors.extend(run_checkers(check_xml_parsing, html_items))
    errors.extend(run_checkers(check_raster_images, raster_images))

    # cssutils is not thread safe
    for name, mt, raw in stylesheets:
        errors.extend(check_css_parsing(name, raw))
    for name, mt, raw in html_items:
        root = container.parsed(name)
        for style in root.xpath('//*[local-name()="style"]'):
            if style.get('type', 'text/css') == 'text/css' and style.text:
                errors.extend(check_css_parsing(name, style.text, line_offset=style.sourceline - 1))
        for elem in root.xpath('//*[@style]'):
            raw = elem.get('style')
            if raw:
                errors.extend(check_css_parsing(name, raw, line_offset=elem.sourceline - 1, is_declaration=True))

    errors += check_mimetypes(container)
    errors += check_links(container) + check_link_destinations(container)
    errors += check_fonts(container)
    errors += check_filenames(container)
    errors += check_ids(container)
    errors += check_opf(container)

    return errors
Esempio n. 6
0
 def replace(self, name):
     c = current_container()
     mt = c.mime_map[name]
     oext = name.rpartition('.')[-1].lower()
     filters = [oext]
     fname = _('Files')
     if mt in OEB_DOCS:
         fname = _('HTML Files')
         filters = 'html htm xhtm xhtml shtml'.split()
     elif is_raster_image(mt):
         fname = _('Images')
         filters = 'jpeg jpg gif png'.split()
     path = choose_files(self, 'tweak_book_import_file', _('Choose file'), filters=[(fname, filters)], select_only_single_file=True)
     if not path:
         return
     path = path[0]
     ext = path.rpartition('.')[-1].lower()
     force_mt = None
     if mt in OEB_DOCS:
         force_mt = c.guess_type('a.html')
     nname = os.path.basename(path)
     nname, ext = nname.rpartition('.')[0::2]
     nname = nname + '.' + ext.lower()
     self.replace_requested.emit(name, path, nname, force_mt)
Esempio n. 7
0
    def show_context_menu(self, point):
        item = self.itemAt(point)
        if item is None or item in set(self.categories.itervalues()):
            return
        m = QMenu(self)
        sel = self.selectedItems()
        num = len(sel)
        container = current_container()
        ci = self.currentItem()
        if ci is not None:
            cn = unicode(ci.data(0, NAME_ROLE) or "")
            mt = unicode(ci.data(0, MIME_ROLE) or "")
            cat = unicode(ci.data(0, CATEGORY_ROLE) or "")
            n = elided_text(cn.rpartition("/")[-1])
            m.addAction(QIcon(I("save.png")), _("Export %s") % n, partial(self.export, cn))
            if (
                cn not in container.names_that_must_not_be_changed
                and cn not in container.names_that_must_not_be_removed
                and mt not in OEB_FONTS
            ):
                m.addAction(_("Replace %s with file...") % n, partial(self.replace, cn))
            m.addSeparator()

            m.addAction(QIcon(I("modified.png")), _("&Rename %s") % n, self.edit_current_item)
            if is_raster_image(mt):
                m.addAction(
                    QIcon(I("default_cover.png")), _("Mark %s as cover image") % n, partial(self.mark_as_cover, cn)
                )
            elif current_container().SUPPORTS_TITLEPAGES and mt in OEB_DOCS and cat == "text":
                m.addAction(
                    QIcon(I("default_cover.png")), _("Mark %s as cover page") % n, partial(self.mark_as_titlepage, cn)
                )
            m.addSeparator()

        if num > 0:
            m.addSeparator()
            if num > 1:
                m.addAction(QIcon(I("modified.png")), _("&Bulk rename selected files"), self.request_bulk_rename)
            m.addAction(QIcon(I("trash.png")), _("&Delete the %d selected file(s)") % num, self.request_delete)
            m.addSeparator()

        selected_map = defaultdict(list)
        for item in sel:
            selected_map[unicode(item.data(0, CATEGORY_ROLE) or "")].append(unicode(item.data(0, NAME_ROLE) or ""))

        for items in selected_map.itervalues():
            items.sort(key=self.index_of_name)

        if selected_map["text"]:
            m.addAction(
                QIcon(I("format-text-color.png")),
                _("Link &stylesheets..."),
                partial(self.link_stylesheets, selected_map["text"]),
            )

        if len(selected_map["text"]) > 1:
            m.addAction(
                QIcon(I("merge.png")),
                _("&Merge selected text files"),
                partial(self.start_merge, "text", selected_map["text"]),
            )
        if len(selected_map["styles"]) > 1:
            m.addAction(
                QIcon(I("merge.png")),
                _("&Merge selected style files"),
                partial(self.start_merge, "styles", selected_map["styles"]),
            )

        if len(list(m.actions())) > 0:
            m.popup(self.mapToGlobal(point))
Esempio n. 8
0
    def show_context_menu(self, point):
        item = self.itemAt(point)
        if item is None or item in tuple(itervalues(self.categories)):
            return
        m = QMenu(self)
        sel = self.selectedItems()
        num = len(sel)
        container = current_container()
        ci = self.currentItem()
        if ci is not None:
            cn = unicode_type(ci.data(0, NAME_ROLE) or '')
            mt = unicode_type(ci.data(0, MIME_ROLE) or '')
            cat = unicode_type(ci.data(0, CATEGORY_ROLE) or '')
            n = elided_text(cn.rpartition('/')[-1])
            m.addAction(QIcon(I('save.png')),
                        _('Export %s') % n, partial(self.export, cn))
            if cn not in container.names_that_must_not_be_changed and cn not in container.names_that_must_not_be_removed and mt not in OEB_FONTS:
                m.addAction(
                    _('Replace %s with file...') % n,
                    partial(self.replace, cn))
            if num > 1:
                m.addAction(QIcon(I('save.png')),
                            _('Export all %d selected files') % num,
                            self.export_selected)

            m.addSeparator()

            m.addAction(QIcon(I('modified.png')),
                        _('&Rename %s') % n, self.edit_current_item)
            if is_raster_image(mt):
                m.addAction(QIcon(I('default_cover.png')),
                            _('Mark %s as cover image') % n,
                            partial(self.mark_as_cover, cn))
            elif current_container(
            ).SUPPORTS_TITLEPAGES and mt in OEB_DOCS and cat == 'text':
                m.addAction(QIcon(I('default_cover.png')),
                            _('Mark %s as cover page') % n,
                            partial(self.mark_as_titlepage, cn))
            m.addSeparator()

        if num > 0:
            m.addSeparator()
            if num > 1:
                m.addAction(QIcon(I('modified.png')),
                            _('&Bulk rename the selected files'),
                            self.request_bulk_rename)
            m.addAction(QIcon(I('modified.png')),
                        _('Change the file extension for the selected files'),
                        self.request_change_ext)
            m.addAction(
                QIcon(I('trash.png')),
                ngettext('&Delete the selected file',
                         '&Delete the {} selected files', num).format(num),
                self.request_delete)
            m.addAction(
                QIcon(I('edit-copy.png')),
                ngettext(
                    '&Copy the selected file to another editor instance',
                    '&Copy the {} selected files to another editor instance',
                    num).format(num), self.copy_selected_files)
            m.addSeparator()
        md = QApplication.instance().clipboard().mimeData()
        if md.hasUrls() and md.hasFormat(FILE_COPY_MIME):
            m.addAction(_('Paste files from other editor instance'),
                        self.paste_from_other_instance)

        selected_map = defaultdict(list)
        for item in sel:
            selected_map[unicode_type(
                item.data(0, CATEGORY_ROLE)
                or '')].append(unicode_type(item.data(0, NAME_ROLE) or ''))

        for items in itervalues(selected_map):
            items.sort(key=self.index_of_name)

        if selected_map['text']:
            m.addAction(QIcon(I('format-text-color.png')),
                        _('Link &stylesheets...'),
                        partial(self.link_stylesheets, selected_map['text']))

        if len(selected_map['text']) > 1:
            m.addAction(
                QIcon(I('merge.png')), _('&Merge selected text files'),
                partial(self.start_merge, 'text', selected_map['text']))
        if len(selected_map['styles']) > 1:
            m.addAction(
                QIcon(I('merge.png')), _('&Merge selected style files'),
                partial(self.start_merge, 'styles', selected_map['styles']))

        if len(list(m.actions())) > 0:
            m.popup(self.mapToGlobal(point))
Esempio n. 9
0
def run_checks(container):

    errors = []

    # Check parsing
    xml_items, html_items, raster_images, stylesheets = [], [], [], []
    for name, mt in iteritems(container.mime_map):
        items = None
        decode = False
        if mt in XML_TYPES:
            items = xml_items
        elif mt in OEB_DOCS:
            items = html_items
        elif mt in OEB_STYLES:
            decode = True
            items = stylesheets
        elif is_raster_image(mt):
            items = raster_images
        if items is not None:
            items.append((name, mt, container.raw_data(name, decode=decode)))
    errors.extend(run_checkers(check_html_size, html_items))
    errors.extend(run_checkers(check_xml_parsing, xml_items))
    errors.extend(run_checkers(check_xml_parsing, html_items))
    errors.extend(run_checkers(check_raster_images, raster_images))

    for err in errors:
        if err.level > WARN:
            return errors

    # css uses its own worker pool
    css_checker = CSSChecker()
    for name, mt, raw in stylesheets:
        if not raw:
            errors.append(EmptyFile(name))
            continue
        css_checker.create_job(name, raw)
    errors.extend(css_checker())

    for name, mt, raw in html_items + xml_items:
        errors.extend(check_encoding_declarations(name, container))

    css_checker = CSSChecker()
    for name, mt, raw in html_items:
        if not raw:
            continue
        root = container.parsed(name)
        for style in root.xpath('//*[local-name()="style"]'):
            if style.get('type', 'text/css') == 'text/css' and style.text:
                css_checker.create_job(name,
                                       style.text,
                                       line_offset=style.sourceline - 1)
        for elem in root.xpath('//*[@style]'):
            raw = elem.get('style')
            if raw:
                css_checker.create_job(name,
                                       raw,
                                       line_offset=elem.sourceline - 1,
                                       is_declaration=True)

    errors.extend(css_checker())
    errors += check_mimetypes(container)
    errors += check_links(container) + check_link_destinations(container)
    errors += check_fonts(container)
    errors += check_ids(container)
    errors += check_filenames(container)
    errors += check_markup(container)
    errors += check_opf(container)

    return errors
Esempio n. 10
0
    def show_context_menu(self, point):
        item = self.itemAt(point)
        if item is None or item in set(self.categories.itervalues()):
            return
        m = QMenu(self)
        sel = self.selectedItems()
        num = len(sel)
        container = current_container()
        ci = self.currentItem()
        if ci is not None:
            cn = unicode(ci.data(0, NAME_ROLE) or '')
            mt = unicode(ci.data(0, MIME_ROLE) or '')
            cat = unicode(ci.data(0, CATEGORY_ROLE) or '')
            n = elided_text(cn.rpartition('/')[-1])
            m.addAction(QIcon(I('save.png')),
                        _('Export %s') % n, partial(self.export, cn))
            if cn not in container.names_that_must_not_be_changed and cn not in container.names_that_must_not_be_removed and mt not in OEB_FONTS:
                m.addAction(
                    _('Replace %s with file...') % n,
                    partial(self.replace, cn))
            m.addSeparator()

            m.addAction(QIcon(I('modified.png')),
                        _('&Rename %s') % n, self.edit_current_item)
            if is_raster_image(mt):
                m.addAction(QIcon(I('default_cover.png')),
                            _('Mark %s as cover image') % n,
                            partial(self.mark_as_cover, cn))
            elif current_container(
            ).SUPPORTS_TITLEPAGES and mt in OEB_DOCS and cat == 'text':
                m.addAction(QIcon(I('default_cover.png')),
                            _('Mark %s as cover page') % n,
                            partial(self.mark_as_titlepage, cn))
            m.addSeparator()

        if num > 0:
            m.addSeparator()
            if num > 1:
                m.addAction(QIcon(I('modified.png')),
                            _('&Bulk rename selected files'),
                            self.request_bulk_rename)
            m.addAction(QIcon(I('trash.png')),
                        _('&Delete the %d selected file(s)') % num,
                        self.request_delete)
            m.addSeparator()

        selected_map = defaultdict(list)
        for item in sel:
            selected_map[unicode(item.data(0, CATEGORY_ROLE) or '')].append(
                unicode(item.data(0, NAME_ROLE) or ''))

        for items in selected_map.itervalues():
            items.sort(key=self.index_of_name)

        if selected_map['text']:
            m.addAction(QIcon(I('format-text-color.png')),
                        _('Link &stylesheets...'),
                        partial(self.link_stylesheets, selected_map['text']))

        if len(selected_map['text']) > 1:
            m.addAction(
                QIcon(I('merge.png')), _('&Merge selected text files'),
                partial(self.start_merge, 'text', selected_map['text']))
        if len(selected_map['styles']) > 1:
            m.addAction(
                QIcon(I('merge.png')), _('&Merge selected style files'),
                partial(self.start_merge, 'styles', selected_map['styles']))

        if len(list(m.actions())) > 0:
            m.popup(self.mapToGlobal(point))