Пример #1
0
 def set_results(self, results, emphasize_text):
     self.clear()
     self.delegate.emphasize_text = emphasize_text
     self.number_of_results = 0
     self.item_map = []
     book_id_map = {}
     db = current_db()
     for result in results:
         book_id = result['book_id']
         if book_id not in book_id_map:
             book_id_map[book_id] = {
                 'title': db.field_for('title', book_id),
                 'matches': []
             }
         book_id_map[book_id]['matches'].append(result)
     for book_id, entry in book_id_map.items():
         section = QTreeWidgetItem([entry['title']], 1)
         section.setFlags(Qt.ItemFlag.ItemIsEnabled)
         section.setFont(0, self.section_font)
         self.addTopLevelItem(section)
         section.setExpanded(True)
         for result in entry['matches']:
             item = QTreeWidgetItem(section, [' '], 2)
             self.item_map.append(item)
             item.setFlags(Qt.ItemFlag.ItemIsSelectable
                           | Qt.ItemFlag.ItemIsEnabled
                           | Qt.ItemFlag.ItemNeverHasChildren)
             item.setData(0, Qt.ItemDataRole.UserRole, result)
             item.setData(0, Qt.ItemDataRole.UserRole + 1,
                          self.number_of_results)
             self.number_of_results += 1
     if self.item_map:
         self.setCurrentItem(self.item_map[0])
Пример #2
0
 def process_node(toc, parent):
     for child in toc:
         node = QTreeWidgetItem(parent)
         node.setText(0, child.title or '')
         node.setData(0, DEST_ROLE, child.dest or '')
         node.setData(0, FRAG_ROLE, child.frag or '')
         tt = _('File: {0}\nAnchor: {1}').format(
             child.dest or '', child.frag or _('Top of file'))
         node.setData(0, Qt.ItemDataRole.ToolTipRole, tt)
         process_node(child, node)
Пример #3
0
        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.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable
            if category == 'text':
                flags |= Qt.ItemFlag.ItemIsDragEnabled | Qt.ItemFlag.ItemIsDropEnabled
            if name not in cannot_be_renamed:
                flags |= Qt.ItemFlag.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'))
            if category == 'fonts' and name.rpartition('.')[-1].lower() in ('ttf', 'otf'):
                fname = self.get_font_family_name(name)
                if fname:
                    tooltips.append(fname)
                else:
                    emblems.append('dialog_error.png')
                    tooltips.append(_('Not a valid font'))

            render_emblems(item, emblems)
            if tooltips:
                item.setData(0, Qt.ItemDataRole.ToolTipRole, '\n'.join(tooltips))
            return item
Пример #4
0
    def process_duplicates(self, db, duplicates):
        ta = _('%(title)s by %(author)s [%(formats)s]')
        bf = QFont(self.dup_list.font())
        bf.setBold(True)
        itf = QFont(self.dup_list.font())
        itf.setItalic(True)

        for mi, cover, formats in duplicates:
            # formats is a list of file paths
            # Grab just the extension and display to the user
            # Based only off the file name, no file type tests are done.
            incoming_formats = ', '.join(
                os.path.splitext(path)[-1].replace('.', '').upper()
                for path in formats)
            item = QTreeWidgetItem([
                ta % dict(title=mi.title,
                          author=mi.format_field('authors')[1],
                          formats=incoming_formats)
            ], 0)
            item.setCheckState(0, Qt.CheckState.Checked)
            item.setFlags(Qt.ItemFlag.ItemIsEnabled
                          | Qt.ItemFlag.ItemIsUserCheckable)
            item.setData(0, Qt.ItemDataRole.FontRole, bf)
            item.setData(0, Qt.ItemDataRole.UserRole, (mi, cover, formats))
            matching_books = db.books_with_same_title(mi)

            def add_child(text):
                c = QTreeWidgetItem([text], 1)
                c.setFlags(Qt.ItemFlag.ItemIsEnabled)
                item.addChild(c)
                return c

            add_child(_('Already in calibre:')).setData(
                0, Qt.ItemDataRole.FontRole, itf)

            author_text = {}
            for book_id in matching_books:
                author_text[book_id] = authors_to_string([
                    a.replace('|', ',') for a in (
                        db.authors(book_id, index_is_id=True) or '').split(',')
                ])

            def key(x):
                return primary_sort_key(str(author_text[x]))

            for book_id in sorted(matching_books, key=key):
                add_child(
                    ta %
                    dict(title=db.title(book_id, index_is_id=True),
                         author=author_text[book_id],
                         formats=db.formats(
                             book_id, index_is_id=True, verify_formats=False)))
            add_child('')

            yield item
Пример #5
0
 def unserialize_node(dict_node, parent):
     n = QTreeWidgetItem(parent)
     n.setData(0, Qt.ItemDataRole.DisplayRole, dict_node['title'])
     n.setData(0, Qt.ItemDataRole.UserRole, dict_node['toc_node'])
     n.setFlags(NODE_FLAGS)
     n.setData(0, Qt.ItemDataRole.DecorationRole, dict_node['icon'])
     n.setData(0, Qt.ItemDataRole.ToolTipRole, dict_node['tooltip'])
     self.update_status_tip(n)
     n.setExpanded(dict_node['is_expanded'])
     n.setSelected(dict_node['is_selected'])
     for c in dict_node['children']:
         unserialize_node(c, n)
 def create_item(self, f, parent):
     name = f.name
     ans = QTreeWidgetItem(parent, [name])
     ans.setData(0, Qt.ItemDataRole.UserRole, '/'.join(f.full_path[1:]))
     ans.setFlags(Qt.ItemFlag.ItemIsUserCheckable
                  | Qt.ItemFlag.ItemIsEnabled)
     ans.setCheckState(
         0, Qt.CheckState.Unchecked if self.dev.is_folder_ignored(
             f.storage_id, f.full_path[1:]) else Qt.CheckState.Checked)
     ans.setData(0, Qt.ItemDataRole.DecorationRole,
                 file_icon_provider().icon_from_ext('dir'))
     return ans
Пример #7
0
 def add_result(self, result):
     section_title = _('Unknown')
     section_id = -1
     toc_nodes = getattr(result, 'toc_nodes', ()) or ()
     if toc_nodes:
         section_title = toc_nodes[-1].get('title') or _('Unknown')
         section_id = toc_nodes[-1].get('id')
         if section_id is None:
             section_id = -1
     section_key = section_id
     section = self.section_map.get(section_key)
     spine_idx = getattr(result, 'spine_idx', -1)
     if section is None:
         section = QTreeWidgetItem([section_title], 1)
         section.setFlags(Qt.ItemFlag.ItemIsEnabled)
         section.setFont(0, self.section_font)
         section.setData(0, SPINE_IDX_ROLE, spine_idx)
         lines = []
         for i, node in enumerate(toc_nodes):
             lines.append('\xa0\xa0' * i + '➤ ' +
                          (node.get('title') or _('Unknown')))
         if lines:
             tt = ngettext('Table of Contents section:',
                           'Table of Contents sections:', len(lines))
             tt += '\n' + '\n'.join(lines)
             section.setToolTip(0, tt)
         self.section_map[section_key] = section
         for s in range(self.topLevelItemCount()):
             ti = self.topLevelItem(s)
             if ti.data(0, SPINE_IDX_ROLE) > spine_idx:
                 self.insertTopLevelItem(s, section)
                 break
         else:
             self.addTopLevelItem(section)
         section.setExpanded(True)
     item = QTreeWidgetItem(section, [' '], 2)
     item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled
                   | Qt.ItemFlag.ItemNeverHasChildren)
     item.setData(0, SEARCH_RESULT_ROLE, result)
     item.setData(0, RESULT_NUMBER_ROLE, len(self.search_results))
     item.setData(0, SPINE_IDX_ROLE, spine_idx)
     if isinstance(result, SearchResult):
         tt = '<p>…' + escape(result.before, False) + '<b>' + escape(
             result.text, False) + '</b>' + escape(result.after,
                                                   False) + '…'
         item.setData(0, Qt.ItemDataRole.ToolTipRole, tt)
     item.setIcon(0, self.blank_icon)
     self.item_map[len(self.search_results)] = item
     self.search_results.append(result)
     n = self.number_of_results
     self.count_changed.emit(n)
def browser_item(f, parent):
    name = f.name
    if not f.is_folder:
        name += ' [%s]' % f.last_mod_string
    ans = QTreeWidgetItem(parent, [name])
    ans.setData(0, Qt.ItemDataRole.UserRole, f.full_path)
    if f.is_folder:
        ext = 'dir'
    else:
        ext = f.name.rpartition('.')[-1]
    ans.setData(0, Qt.ItemDataRole.DecorationRole,
                file_icon_provider().icon_from_ext(ext))

    return ans
Пример #9
0
 def load(self, highlights, preserve_state=False):
     s = self.style()
     expanded_chapters = set()
     if preserve_state:
         root = self.invisibleRootItem()
         for i in range(root.childCount()):
             chapter = root.child(i)
             if chapter.isExpanded():
                 expanded_chapters.add(chapter.data(0, Qt.ItemDataRole.DisplayRole))
     icon_size = s.pixelMetric(QStyle.PixelMetric.PM_SmallIconSize, None, self)
     dpr = self.devicePixelRatioF()
     is_dark = is_dark_theme()
     self.clear()
     self.uuid_map = {}
     highlights = (h for h in highlights if not h.get('removed') and h.get('highlighted_text'))
     section_map = defaultdict(list)
     section_tt_map = {}
     for h in self.sorted_highlights(highlights):
         tfam = h.get('toc_family_titles') or ()
         if tfam:
             tsec = tfam[0]
             lsec = tfam[-1]
         else:
             tsec = h.get('top_level_section_title')
             lsec = h.get('lowest_level_section_title')
         sec = lsec or tsec or _('Unknown')
         if len(tfam) > 1:
             lines = []
             for i, node in enumerate(tfam):
                 lines.append('\xa0\xa0' * i + '➤ ' + node)
             tt = ngettext('Table of Contents section:', 'Table of Contents sections:', len(lines))
             tt += '\n' + '\n'.join(lines)
             section_tt_map[sec] = tt
         section_map[sec].append(h)
     for secnum, (sec, items) in enumerate(section_map.items()):
         section = QTreeWidgetItem([sec], 1)
         section.setFlags(Qt.ItemFlag.ItemIsEnabled)
         section.setFont(0, self.section_font)
         tt = section_tt_map.get(sec)
         if tt:
             section.setToolTip(0, tt)
         self.addTopLevelItem(section)
         section.setExpanded(not preserve_state or sec in expanded_chapters)
         for itemnum, h in enumerate(items):
             txt = h.get('highlighted_text')
             txt = txt.replace('\n', ' ')
             if h.get('notes'):
                 txt = '•' + txt
             if len(txt) > 100:
                 txt = txt[:100] + '…'
             item = QTreeWidgetItem(section, [txt], 2)
             item.setFlags(Qt.ItemFlag.ItemIsSelectable | Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemNeverHasChildren)
             item.setData(0, Qt.ItemDataRole.UserRole, h)
             try:
                 dec = decoration_for_style(self.palette(), h.get('style') or {}, icon_size, dpr, is_dark)
             except Exception:
                 import traceback
                 traceback.print_exc()
                 dec = None
             if dec is None:
                 dec = self.default_decoration
             item.setData(0, Qt.ItemDataRole.DecorationRole, dec)
             self.uuid_map[h['uuid']] = secnum, itemnum
             self.num_of_items += 1