mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Merge branch 'master' of https://github.com/cbhaley/calibre into master
This commit is contained in:
commit
dc67ed88f2
@ -134,6 +134,7 @@ def create_defs():
|
|||||||
defs['font'] = None
|
defs['font'] = None
|
||||||
defs['tags_browser_partition_method'] = 'first letter'
|
defs['tags_browser_partition_method'] = 'first letter'
|
||||||
defs['tags_browser_collapse_at'] = 100
|
defs['tags_browser_collapse_at'] = 100
|
||||||
|
defs['tags_browser_collapse_fl_at'] = 0
|
||||||
defs['tag_browser_dont_collapse'] = []
|
defs['tag_browser_dont_collapse'] = []
|
||||||
defs['edit_metadata_single_layout'] = 'default'
|
defs['edit_metadata_single_layout'] = 'default'
|
||||||
defs['preserve_date_on_ctl'] = True
|
defs['preserve_date_on_ctl'] = True
|
||||||
|
@ -487,6 +487,7 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form):
|
|||||||
(_('Partitioned'), 'partition')]
|
(_('Partitioned'), 'partition')]
|
||||||
r('tags_browser_partition_method', gprefs, choices=choices)
|
r('tags_browser_partition_method', gprefs, choices=choices)
|
||||||
r('tags_browser_collapse_at', gprefs)
|
r('tags_browser_collapse_at', gprefs)
|
||||||
|
r('tags_browser_collapse_fl_at', gprefs)
|
||||||
r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList)
|
r('tag_browser_dont_collapse', gprefs, setting=CommaSeparatedList)
|
||||||
|
|
||||||
choices = {k for k in db.field_metadata.all_field_keys()
|
choices = {k for k in db.field_metadata.all_field_keys()
|
||||||
|
@ -914,7 +914,32 @@ up into subcategories. If the partition method is set to disable, this value is
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Combine letters &when fewer items than:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_tags_browser_collapse_fl_at</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QSpinBox" name="opt_tags_browser_collapse_fl_at">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>If collapsing by first letter, combine adjacent letters together if
|
||||||
|
there are fewer items under a letter than specified here. If the partition method is
|
||||||
|
not set to first letter, this value is ignored.</string>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>10000</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
<widget class="QLabel" name="label_8111">
|
<widget class="QLabel" name="label_8111">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Categories &not to partition:</string>
|
<string>Categories &not to partition:</string>
|
||||||
@ -924,7 +949,7 @@ up into subcategories. If the partition method is set to disable, this value is
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="EditWithComplete" name="opt_tag_browser_dont_collapse">
|
<widget class="EditWithComplete" name="opt_tag_browser_dont_collapse">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
@ -1044,7 +1069,7 @@ see the counts by hovering your mouse over any item.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="5" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Spacing between &items:</string>
|
<string>Spacing between &items:</string>
|
||||||
@ -1054,7 +1079,7 @@ see the counts by hovering your mouse over any item.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="5" column="1">
|
||||||
<widget class="QDoubleSpinBox" name="opt_tag_browser_item_padding">
|
<widget class="QDoubleSpinBox" name="opt_tag_browser_item_padding">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>The spacing between consecutive items in the Tag browser. In units of (ex) which is the approximate height of the letter 'x' in the currently used font. </string>
|
<string>The spacing between consecutive items in the Tag browser. In units of (ex) which is the approximate height of the letter 'x' in the currently used font. </string>
|
||||||
|
@ -7,7 +7,7 @@ __copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
import traceback, copy, os
|
import traceback, copy, os
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict, namedtuple
|
||||||
|
|
||||||
from PyQt5.Qt import (QAbstractItemModel, QIcon, QFont, Qt,
|
from PyQt5.Qt import (QAbstractItemModel, QIcon, QFont, Qt,
|
||||||
QMimeData, QModelIndex, pyqtSignal, QObject)
|
QMimeData, QModelIndex, pyqtSignal, QObject)
|
||||||
@ -290,6 +290,8 @@ class TagTreeItem(object): # {{{
|
|||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
|
FL_Interval = namedtuple('FL_Interval', ['first_chr', 'last_chr', 'length'])
|
||||||
|
|
||||||
class TagsModel(QAbstractItemModel): # {{{
|
class TagsModel(QAbstractItemModel): # {{{
|
||||||
|
|
||||||
search_item_renamed = pyqtSignal()
|
search_item_renamed = pyqtSignal()
|
||||||
@ -525,18 +527,72 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
# Build a list of 'equal' first letters by noticing changes
|
# Build a list of 'equal' first letters by noticing changes
|
||||||
# in ICU's 'ordinal' for the first letter. In this case, the
|
# in ICU's 'ordinal' for the first letter. In this case, the
|
||||||
# first letter can actually be more than one letter long.
|
# first letter can actually be more than one letter long.
|
||||||
|
fl_collapse_when = self.prefs['tags_browser_collapse_fl_at']
|
||||||
|
fl_collapse = True if fl_collapse_when > 1 else False
|
||||||
|
intervals = list()
|
||||||
cl_list = [None] * len(data[key])
|
cl_list = [None] * len(data[key])
|
||||||
last_ordnum = 0
|
last_ordnum = 0
|
||||||
last_c = ' '
|
last_c = ' '
|
||||||
|
last_idx = 0
|
||||||
for idx,tag in enumerate(data[key]):
|
for idx,tag in enumerate(data[key]):
|
||||||
# Deal with items that don't have sorts, such as formats
|
# Deal with items that don't have sorts, such as formats
|
||||||
t = tag.sort if tag.sort else tag.name
|
t = tag.sort if tag.sort else tag.name
|
||||||
c = icu_upper(t) if t else ' '
|
c = icu_upper(t) if t else ' '
|
||||||
ordnum, ordlen = collation_order(c)
|
ordnum, ordlen = collation_order(c)
|
||||||
if last_ordnum != ordnum:
|
if last_ordnum != ordnum:
|
||||||
|
if fl_collapse and idx > 0:
|
||||||
|
intervals.append(FL_Interval(last_c, last_c, idx-last_idx))
|
||||||
|
last_idx = idx
|
||||||
last_c = c[0:ordlen]
|
last_c = c[0:ordlen]
|
||||||
last_ordnum = ordnum
|
last_ordnum = ordnum
|
||||||
cl_list[idx] = last_c
|
cl_list[idx] = last_c
|
||||||
|
if fl_collapse:
|
||||||
|
intervals.append(FL_Interval(last_c, last_c, len(cl_list)-last_idx))
|
||||||
|
# Combine together first letter categories that are smaller
|
||||||
|
# than the specified option. We choose which item to combine
|
||||||
|
# by the size of the items before and after, privileging making
|
||||||
|
# smaller categories. Loop through the intervals doing the combine
|
||||||
|
# until nothing changes. Multiple iterations are required because
|
||||||
|
# we might need to combine categories that are already combined.
|
||||||
|
fl_intervals_changed = True
|
||||||
|
null_interval = FL_Interval('', '', 100000000)
|
||||||
|
while fl_intervals_changed and len(intervals) > 1:
|
||||||
|
fl_intervals_changed = False
|
||||||
|
for idx,interval in enumerate(intervals):
|
||||||
|
if interval.length >= fl_collapse_when:
|
||||||
|
continue
|
||||||
|
prev = next_ = null_interval
|
||||||
|
if idx == 0:
|
||||||
|
next_ = intervals[idx+1]
|
||||||
|
else:
|
||||||
|
prev = intervals[idx-1]
|
||||||
|
if idx < len(intervals) - 1:
|
||||||
|
next_ = intervals[idx+1]
|
||||||
|
if prev.length < next_.length:
|
||||||
|
intervals[idx-1] = FL_Interval(prev.first_chr,
|
||||||
|
interval.last_chr,
|
||||||
|
prev.length + interval.length)
|
||||||
|
else:
|
||||||
|
intervals[idx+1] = FL_Interval(interval.first_chr,
|
||||||
|
next_.last_chr,
|
||||||
|
next_.length + interval.length)
|
||||||
|
del intervals[idx]
|
||||||
|
fl_intervals_changed = True
|
||||||
|
break
|
||||||
|
# Now correct the first letter list, entering either the letter
|
||||||
|
# or the range for each item in the category. If we ended up
|
||||||
|
# with only one 'first letter' category then don't combine
|
||||||
|
# letters and revert to basic 'by first letter'
|
||||||
|
if len(intervals) > 1:
|
||||||
|
cur_idx = 0
|
||||||
|
for interval in intervals:
|
||||||
|
first_chr, last_chr, length = interval
|
||||||
|
for i in range(0, length):
|
||||||
|
if first_chr == last_chr:
|
||||||
|
cl_list[cur_idx] = first_chr
|
||||||
|
else:
|
||||||
|
cl_list[cur_idx] = '{0} - {1}'.format(first_chr, last_chr)
|
||||||
|
cur_idx += 1
|
||||||
top_level_component = 'z' + data[key][0].original_name
|
top_level_component = 'z' + data[key][0].original_name
|
||||||
|
|
||||||
last_idx = -collapse
|
last_idx = -collapse
|
||||||
|
Loading…
x
Reference in New Issue
Block a user