mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre
This commit is contained in:
commit
7adb5eba8c
@ -425,6 +425,7 @@ def create_defs():
|
|||||||
defs['allow_keyboard_search_in_library_views'] = True
|
defs['allow_keyboard_search_in_library_views'] = True
|
||||||
defs['show_links_in_tag_browser'] = False
|
defs['show_links_in_tag_browser'] = False
|
||||||
defs['show_notes_in_tag_browser'] = False
|
defs['show_notes_in_tag_browser'] = False
|
||||||
|
defs['icons_on_right_in_tag_browser'] = True
|
||||||
|
|
||||||
def migrate_tweak(tweak_name, pref_name):
|
def migrate_tweak(tweak_name, pref_name):
|
||||||
# If the tweak has been changed then leave the tweak in the file so
|
# If the tweak has been changed then leave the tweak in the file so
|
||||||
|
@ -648,6 +648,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
r('show_avg_rating', config)
|
r('show_avg_rating', config)
|
||||||
r('show_links_in_tag_browser', gprefs)
|
r('show_links_in_tag_browser', gprefs)
|
||||||
r('show_notes_in_tag_browser', gprefs)
|
r('show_notes_in_tag_browser', gprefs)
|
||||||
|
r('icons_on_right_in_tag_browser', gprefs)
|
||||||
r('disable_animations', config)
|
r('disable_animations', config)
|
||||||
r('systray_icon', config, restart_required=True)
|
r('systray_icon', config, restart_required=True)
|
||||||
r('show_splash_screen', gprefs)
|
r('show_splash_screen', gprefs)
|
||||||
|
@ -1370,6 +1370,21 @@ box will cause these empty categories to be hidden.</p></string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QCheckBox" name="opt_icons_on_right_in_tag_browser">
|
||||||
|
<property name="text">
|
||||||
|
<string>Place icons on the &right, in columns</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>If checked the notes and links icons will be placed at the right, after
|
||||||
|
the count and in columns. If unchecked, the icons will be placed immediately after the text,
|
||||||
|
to the left of the count and not in columns.</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="2" column="2">
|
<item row="2" column="2">
|
||||||
<widget class="QCheckBox" name="opt_tag_browser_always_autocollapse">
|
<widget class="QCheckBox" name="opt_tag_browser_always_autocollapse">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
|
@ -782,10 +782,16 @@ class TagBrowserWidget(QFrame): # {{{
|
|||||||
l.m.aboutToShow.connect(self.about_to_show_configure_menu)
|
l.m.aboutToShow.connect(self.about_to_show_configure_menu)
|
||||||
# Show/hide counts
|
# Show/hide counts
|
||||||
l.m.show_counts_action = ac = l.m.addAction('counts')
|
l.m.show_counts_action = ac = l.m.addAction('counts')
|
||||||
|
parent.keyboard.register_shortcut('tag browser toggle counts',
|
||||||
|
_('Toggle counts'), default_keys=(),
|
||||||
|
action=ac, group=_('Tag browser'))
|
||||||
ac.triggered.connect(self.toggle_counts)
|
ac.triggered.connect(self.toggle_counts)
|
||||||
# Show/hide average rating
|
# Show/hide average rating
|
||||||
l.m.show_avg_rating_action = ac = l.m.addAction(QIcon.ic('rating.png'), 'avg rating')
|
l.m.show_avg_rating_action = ac = l.m.addAction(QIcon.ic('rating.png'), 'avg rating')
|
||||||
ac.triggered.connect(self.toggle_avg_rating)
|
ac.triggered.connect(self.toggle_avg_rating)
|
||||||
|
parent.keyboard.register_shortcut('tag browser toggle average ratings',
|
||||||
|
_('Toggle average ratings'), default_keys=(),
|
||||||
|
action=ac, group=_('Tag browser'))
|
||||||
# Show/hide notes icon
|
# Show/hide notes icon
|
||||||
l.m.show_notes_icon_action = ac = l.m.addAction(QIcon.ic('notes.png'), 'notes icon')
|
l.m.show_notes_icon_action = ac = l.m.addAction(QIcon.ic('notes.png'), 'notes icon')
|
||||||
ac.triggered.connect(self.toggle_notes_icon)
|
ac.triggered.connect(self.toggle_notes_icon)
|
||||||
|
@ -87,50 +87,86 @@ class TagDelegate(QStyledItemDelegate): # {{{
|
|||||||
def draw_text(self, style, painter, option, widget, index, item):
|
def draw_text(self, style, painter, option, widget, index, item):
|
||||||
tr = style.subElementRect(QStyle.SubElement.SE_ItemViewItemText, option, widget)
|
tr = style.subElementRect(QStyle.SubElement.SE_ItemViewItemText, option, widget)
|
||||||
text = index.data(Qt.ItemDataRole.DisplayRole)
|
text = index.data(Qt.ItemDataRole.DisplayRole)
|
||||||
|
flags = Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignLeft | Qt.TextFlag.TextSingleLine
|
||||||
|
lr = QRect(tr)
|
||||||
|
lr.setRight(lr.right() * 2)
|
||||||
|
text_rec = painter.boundingRect(lr, flags, text)
|
||||||
hover = option.state & QStyle.StateFlag.State_MouseOver
|
hover = option.state & QStyle.StateFlag.State_MouseOver
|
||||||
is_search = (True if item.type == TagTreeItem.TAG and
|
is_search = (True if item.type == TagTreeItem.TAG and
|
||||||
item.tag.category == 'search' else False)
|
item.tag.category == 'search' else False)
|
||||||
|
|
||||||
show_notes = gprefs['show_notes_in_tag_browser']
|
def render_count():
|
||||||
show_links = gprefs['show_links_in_tag_browser']
|
if not is_search and (hover or gprefs['tag_browser_show_counts']):
|
||||||
|
count = str(index.data(COUNT_ROLE))
|
||||||
|
width = painter.fontMetrics().boundingRect(count).width()
|
||||||
|
r = QRect(tr)
|
||||||
|
r.setRight(r.right() - 1), r.setLeft(r.right() - width - 4)
|
||||||
|
self.paint_text(painter, r, Qt.AlignmentFlag.AlignCenter | Qt.TextFlag.TextSingleLine, count, hover, option)
|
||||||
|
tr.setRight(r.left() - 1)
|
||||||
|
else:
|
||||||
|
tr.setRight(tr.right() - 1)
|
||||||
|
|
||||||
if item.type == TagTreeItem.TAG:
|
if item.type == TagTreeItem.TAG:
|
||||||
category = item.tag.category
|
category = item.tag.category
|
||||||
name = item.tag.original_name
|
name = item.tag.original_name
|
||||||
tv = self.tags_view
|
tv = self.tags_view
|
||||||
m = tv._model
|
m = tv._model
|
||||||
if show_links and m.category_has_links(category):
|
positions = {'links': (-1, -1), 'notes': (-1, -1)}
|
||||||
|
|
||||||
|
# The icons fits in a rectangle height/2 + 4 x height/2 + 4. This
|
||||||
|
# ensures they are a 'pleasant' size compared to the text.
|
||||||
|
icon_width = int(tr.height()/2) + 4
|
||||||
|
|
||||||
|
def render_link_icon():
|
||||||
icon = self.links_icon if m.item_has_link(category, name) else self.blank_icon
|
icon = self.links_icon if m.item_has_link(category, name) else self.blank_icon
|
||||||
width = int(tr.height()/2)
|
|
||||||
r = QRect(tr)
|
r = QRect(tr)
|
||||||
r.setRight(r.right() - 1), r.setLeft(r.right() - width - 4)
|
r.setRight(r.right() - 1)
|
||||||
tv.category_button_positions[category]['links'] = (r.left(), r.left()+r.width())
|
r.setLeft(r.right() - icon_width)
|
||||||
|
positions['links'] = (r.left(), r.left()+r.width())
|
||||||
icon.paint(painter, r, option.decorationAlignment, QIcon.Mode.Normal, QIcon.State.On)
|
icon.paint(painter, r, option.decorationAlignment, QIcon.Mode.Normal, QIcon.State.On)
|
||||||
tr.setRight(r.left() - 1)
|
tr.setRight(r.left() - 1)
|
||||||
if show_notes and m.category_has_notes(category):
|
def render_note_icon():
|
||||||
icon = self.notes_icon if m.item_has_note(category, name) else self.blank_icon
|
icon = self.notes_icon if m.item_has_note(category, name) else self.blank_icon
|
||||||
width = int(tr.height()/2)
|
|
||||||
r = QRect(tr)
|
r = QRect(tr)
|
||||||
r.setRight(r.right() - 1), r.setLeft(r.right() - width - 4)
|
r.setRight(r.right() - 1)
|
||||||
tv.category_button_positions[category]['notes'] = (r.left(), r.left()+r.width())
|
r.setLeft(r.right() - icon_width)
|
||||||
|
positions['notes'] = (r.left(), r.left()+r.width())
|
||||||
icon.paint(painter, r, option.decorationAlignment, QIcon.Mode.Normal, QIcon.State.On)
|
icon.paint(painter, r, option.decorationAlignment, QIcon.Mode.Normal, QIcon.State.On)
|
||||||
tr.setRight(r.left() - 1)
|
tr.setRight(r.left() - 1)
|
||||||
if not is_search and (hover or gprefs['tag_browser_show_counts']):
|
|
||||||
count = str(index.data(COUNT_ROLE))
|
if gprefs['icons_on_right_in_tag_browser']:
|
||||||
width = painter.fontMetrics().boundingRect(count).width()
|
# Icons go far right, in columns after the counts
|
||||||
r = QRect(tr)
|
show_note_icon = gprefs['show_notes_in_tag_browser'] and m.category_has_notes(category)
|
||||||
r.setRight(r.right() - 1), r.setLeft(r.right() - width - 4)
|
show_link_icon = gprefs['show_links_in_tag_browser'] and m.category_has_links(category)
|
||||||
self.paint_text(painter, r, Qt.AlignmentFlag.AlignCenter | Qt.TextFlag.TextSingleLine, count, hover, option)
|
if show_link_icon:
|
||||||
tr.setRight(r.left() - 1)
|
render_link_icon()
|
||||||
|
if show_note_icon:
|
||||||
|
render_note_icon()
|
||||||
|
render_count()
|
||||||
|
else:
|
||||||
|
# Icons go after the text to the left of the counts, not in columns
|
||||||
|
show_note_icon = gprefs['show_notes_in_tag_browser'] and m.item_has_note(category, name)
|
||||||
|
show_link_icon = gprefs['show_links_in_tag_browser'] and m.item_has_link(category, name)
|
||||||
|
|
||||||
|
render_count()
|
||||||
|
# The link icon has a margin of 1 px on each side. Account for
|
||||||
|
# this when computing the width of the icons. If you change the
|
||||||
|
# order of the icons then you must change this calculation
|
||||||
|
w = (int(show_link_icon) * (icon_width + 2)) + (int(show_note_icon) * icon_width)
|
||||||
|
# Leave a 5 px margin between the text and the icon.
|
||||||
|
tr.setWidth(min(tr.width(), text_rec.width() + 5 + w))
|
||||||
|
if show_link_icon:
|
||||||
|
render_link_icon()
|
||||||
|
if show_note_icon:
|
||||||
|
render_note_icon()
|
||||||
|
tv.category_button_positions[category][name] = positions
|
||||||
else:
|
else:
|
||||||
tr.setRight(tr.right() - 1)
|
render_count()
|
||||||
|
|
||||||
is_rating = item.type == TagTreeItem.TAG and not self.rating_pat.sub('', text)
|
is_rating = item.type == TagTreeItem.TAG and not self.rating_pat.sub('', text)
|
||||||
if is_rating:
|
if is_rating:
|
||||||
painter.setFont(self.rating_font)
|
painter.setFont(self.rating_font)
|
||||||
flags = Qt.AlignmentFlag.AlignVCenter | Qt.AlignmentFlag.AlignLeft | Qt.TextFlag.TextSingleLine
|
if text_rec.width() > tr.width():
|
||||||
lr = QRect(tr)
|
|
||||||
lr.setRight(lr.right() * 2)
|
|
||||||
br = painter.boundingRect(lr, flags, text)
|
|
||||||
if br.width() > tr.width():
|
|
||||||
g = QLinearGradient(QPointF(tr.topLeft()), QPointF(tr.topRight()))
|
g = QLinearGradient(QPointF(tr.topLeft()), QPointF(tr.topRight()))
|
||||||
c = option.palette.color(QPalette.ColorRole.WindowText)
|
c = option.palette.color(QPalette.ColorRole.WindowText)
|
||||||
g.setColorAt(0, c), g.setColorAt(0.8, c)
|
g.setColorAt(0, c), g.setColorAt(0.8, c)
|
||||||
@ -522,8 +558,8 @@ class TagsView(QTreeView): # {{{
|
|||||||
joiner = ' and ' if self.match_all else ' or '
|
joiner = ' and ' if self.match_all else ' or '
|
||||||
return joiner.join(tokens)
|
return joiner.join(tokens)
|
||||||
|
|
||||||
def click_in_button_range(self, val, category, kind):
|
def click_in_button_range(self, val, category, item_name, kind):
|
||||||
range_tuple = self.category_button_positions[category].get(kind)
|
range_tuple = self.category_button_positions[category].get(item_name, {}).get(kind)
|
||||||
return range_tuple and range_tuple[0] <= val <= range_tuple[1]
|
return range_tuple and range_tuple[0] <= val <= range_tuple[1]
|
||||||
|
|
||||||
def toggle_current_index(self):
|
def toggle_current_index(self):
|
||||||
@ -540,13 +576,13 @@ class TagsView(QTreeView): # {{{
|
|||||||
category = t.tag.category
|
category = t.tag.category
|
||||||
orig_name = t.tag.original_name
|
orig_name = t.tag.original_name
|
||||||
x = self.mouse_clicked_point.x()
|
x = self.mouse_clicked_point.x()
|
||||||
if self.click_in_button_range(x, category, 'notes'):
|
if self.click_in_button_range(x, category, orig_name, 'notes'):
|
||||||
from calibre.gui2.dialogs.show_category_note import ShowNoteDialog
|
from calibre.gui2.dialogs.show_category_note import ShowNoteDialog
|
||||||
item_id = db.get_item_id(category, orig_name)
|
item_id = db.get_item_id(category, orig_name)
|
||||||
if db.notes_for(category, item_id):
|
if db.notes_for(category, item_id):
|
||||||
ShowNoteDialog(category, item_id, db, parent=self).show()
|
ShowNoteDialog(category, item_id, db, parent=self).show()
|
||||||
return
|
return
|
||||||
if self.click_in_button_range(x, category, 'links'):
|
if self.click_in_button_range(x, category, orig_name, 'links'):
|
||||||
link = db.get_link_map(category).get(orig_name)
|
link = db.get_link_map(category).get(orig_name)
|
||||||
if link:
|
if link:
|
||||||
safe_open_url(link)
|
safe_open_url(link)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user