diff --git a/Changelog.yaml b/Changelog.yaml index c063d65041..99bcfcfeb0 100644 --- a/Changelog.yaml +++ b/Changelog.yaml @@ -24,7 +24,7 @@ new features: - title: "When searching, allow use of un-accented characters to match accented characters in all fields and all languages (not just authors and English as before)" - description: "The rules for matching un-accented characters are done in a language dependent way. So if your calibre interface language is set to English, n will match both n and ñ, but if it is set to Spanish, it will match only n, as in Spanish ñ is a separate alphabet in Spanish." + description: "The rules for matching un-accented characters are done in a language dependent way. So if your calibre interface language is set to English, n will match both n and ñ, but if it is set to Spanish, it will match only n, as in Spanish ñ is a separate alphabet in Spanish. This makes searching a little slower, so if you have a very large library you can turn it off via Preferences->Searching." type: major - title: "Content server: Show a best guess for the IP address the content server is currently listening at in the connect/share menu." diff --git a/manual/customize.rst b/manual/customize.rst index e2e2825de6..ceee4ece62 100644 --- a/manual/customize.rst +++ b/manual/customize.rst @@ -30,6 +30,7 @@ Environment variables * ``CALIBRE_OVERRIDE_DATABASE_PATH`` - allows you to specify the full path to metadata.db. Using this variable you can have metadata.db be in a location other than the library folder. Useful if your library folder is on a networked drive that does not support file locking. * ``CALIBRE_DEVELOP_FROM`` - Used to run from a calibre development environment. See :ref:`develop`. * ``CALIBRE_OVERRIDE_LANG`` - Used to force the language used by the interface (ISO 639 language code) + * ``CALIBRE_NO_NATIVE_FILEDIALOGS`` - Causes calibre to not use native file dialogs for selecting files/directories. * ``SYSFS_PATH`` - Use if sysfs is mounted somewhere other than /sys * ``http_proxy`` - Used on linux to specify an HTTP proxy diff --git a/resources/default_tweaks.py b/resources/default_tweaks.py index cc798a09ba..420df116ce 100644 --- a/resources/default_tweaks.py +++ b/resources/default_tweaks.py @@ -98,15 +98,6 @@ authors_split_regex = r'(?i),?\s+(and|with)\s+' # categories_use_field_for_author_name = 'author_sort' categories_use_field_for_author_name = 'author' -#: Completion sort order: choose when to change from lexicographic to ASCII-like -# Calibre normally uses locale-dependent lexicographic ordering when showing -# completion values. This means that the sort order is correct for the user's -# language. However, this can be slow. Performance is improved by switching to -# ascii ordering. This tweak controls when that switch happens. Set it to zero -# to always use ascii ordering. Set it to something larger than zero to switch -# to ascii ordering for performance reasons. -completion_change_to_ascii_sorting = 2500 - #: Control partitioning of Tag Browser # When partitioning the tags browser, the format of the subcategory label is # controlled by a template: categories_collapsed_name_template if sorting by @@ -522,6 +513,6 @@ default_tweak_format = None # consideration when partitioning by first letter. # Examples: # enable_multicharacters_in_tag_browser = True -# enable_multicharacters_in_tag_browser = True +# enable_multicharacters_in_tag_browser = False enable_multicharacters_in_tag_browser = True diff --git a/src/calibre/devices/kobo/driver.py b/src/calibre/devices/kobo/driver.py index 6f2358ade1..cc826eb1c1 100644 --- a/src/calibre/devices/kobo/driver.py +++ b/src/calibre/devices/kobo/driver.py @@ -423,7 +423,7 @@ class KOBO(USBMS): def delete_books(self, paths, end_session=True): if self.modify_database_check("delete_books") == False: - return + return for i, path in enumerate(paths): self.report_progress((i+1) / float(len(paths)), _('Removing books from device...')) @@ -462,7 +462,7 @@ class KOBO(USBMS): def remove_books_from_metadata(self, paths, booklists): if self.modify_datbase_check("remove_books_from_metatata") == False: - return + return for i, path in enumerate(paths): self.report_progress((i+1) / float(len(paths)), _('Removing books from device metadata listing...')) @@ -598,7 +598,7 @@ class KOBO(USBMS): # Checks to see whether the database version is supported # and whether the user has chosen to support the firmware version if self.dbversion > self.supported_dbversion: - # Unsupported database + # Unsupported database opts = self.settings() if not opts.extra_customization[self.OPT_SUPPORT_NEWER_FIRMWARE]: debug_print('The database has been upgraded past supported version') @@ -606,11 +606,11 @@ class KOBO(USBMS): self.report_progress(1.0, _('Removing books from device...')) from calibre.devices.errors import UserFeedback raise UserFeedback(_("Kobo database version unsupported - See details"), - _('Your Kobo is running an updated firmware/database version ' + _('Your Kobo is running an updated firmware/database version. ' 'As Calibre has not been updated, database editing is disabled. ' 'You can enable support for your Kobo in plugin preferences. ' 'Doing so may require you to perform a factory reset. ' - 'before selecting the "Attempt to support newer firmware" option ' + 'Before selecting the "Attempt to support newer firmware" option ' 'you should be familiar with restoring your Kobo to factory defaults.'), UserFeedback.WARN) @@ -741,7 +741,7 @@ class KOBO(USBMS): def update_device_database_collections(self, booklists, collections_attributes, oncard): if self.modify_database_check("update_device_database_collections") == False: - return + return # Only process categories in this list supportedcategories = { diff --git a/src/calibre/ebooks/mobi/debug/headers.py b/src/calibre/ebooks/mobi/debug/headers.py index 6aaafbffa3..2b5d6920a5 100644 --- a/src/calibre/ebooks/mobi/debug/headers.py +++ b/src/calibre/ebooks/mobi/debug/headers.py @@ -144,9 +144,9 @@ class EXTHRecord(object): 118 : 'retailprice', 119 : 'retailpricecurrency', 121 : 'KF8 header section index', - 125 : 'KF8 resources (images/fonts) count', - 129 : 'KF8 cover URI', - 131 : 'KF8 unknown count', + 125 : 'KF8 unknown count', + 129 : 'KF8 thumbnail URI', + 131 : 'KF8 resources (images/fonts) count', 201 : 'coveroffset', 202 : 'thumboffset', 203 : 'hasfakecover', @@ -163,6 +163,7 @@ class EXTHRecord(object): 501 : 'cdetype', # 4 chars (PDOC or EBOK) 502 : 'lastupdatetime', 503 : 'updatedtitle', + 524 : 'language', }.get(self.type, repr(self.type)) if (self.name in {'coveroffset', 'thumboffset', 'hasfakecover', diff --git a/src/calibre/ebooks/mobi/reader/headers.py b/src/calibre/ebooks/mobi/reader/headers.py index 51da05ea83..bfbffe546e 100644 --- a/src/calibre/ebooks/mobi/reader/headers.py +++ b/src/calibre/ebooks/mobi/reader/headers.py @@ -13,6 +13,7 @@ from calibre.utils.date import parse_date from calibre.ebooks.mobi import MobiError from calibre.ebooks.metadata import MetaInformation, check_isbn from calibre.ebooks.mobi.langcodes import main_language, sub_language, mobi2iana +from calibre.utils.localization import canonicalize_lang NULL_INDEX = 0xffffffff @@ -68,6 +69,14 @@ class EXTHHeader(object): # {{{ title = content.decode(codec) except: pass + elif idx == 524: # Lang code + try: + lang = content.decode(codec) + lang = canonicalize_lang(lang) + if lang: + self.mi.language = lang + except: + pass #else: # print 'unknown record', idx, repr(content) if title: @@ -201,10 +210,11 @@ class BookHeader(object): self.exth = EXTHHeader(raw[16 + self.length:], self.codec, self.title) self.exth.mi.uid = self.unique_id - try: - self.exth.mi.language = mobi2iana(langid, sublangid) - except: - self.log.exception('Unknown language code') + if self.exth.mi.is_null('language'): + try: + self.exth.mi.language = mobi2iana(langid, sublangid) + except: + self.log.exception('Unknown language code') except: self.log.exception('Invalid EXTH header') self.exth_flag = 0 diff --git a/src/calibre/ebooks/mobi/writer2/main.py b/src/calibre/ebooks/mobi/writer2/main.py index e9f10a605e..b0146daebc 100644 --- a/src/calibre/ebooks/mobi/writer2/main.py +++ b/src/calibre/ebooks/mobi/writer2/main.py @@ -297,10 +297,13 @@ class MobiWriter(object): # 0x70 - 0x73 : EXTH flags # Bit 6 (0b1000000) being set indicates the presence of an EXTH header + # Bit 12 being set indicates the presence of embedded fonts # The purpose of the other bits is unknown exth_flags = 0b1010000 if self.is_periodical: exth_flags |= 0b1000 + if self.resources.has_fonts: + exth_flags |= 0b1000000000000 record0.write(pack(b'>I', exth_flags)) # 0x74 - 0x93 : Unknown @@ -406,7 +409,10 @@ class MobiWriter(object): # Now change the header fields that need to be different in the MOBI 6 # header header_fields['first_resource_record'] = first_image_record - header_fields['exth_flags'] = 0b100001010000 # Kinglegen uses this + ef = 0b100001010000 # Kinglegen uses this + if self.resources.has_fonts: + ef |= 0b1000000000000 + header_fields['exth_flags'] = ef header_fields['fdst_record'] = pack(b'>HH', 1, last_content_record) header_fields['fdst_count'] = 1 # Why not 0? Kindlegen uses 1 header_fields['flis_record'] = flis_number diff --git a/src/calibre/ebooks/mobi/writer2/resources.py b/src/calibre/ebooks/mobi/writer2/resources.py index 2f12793b03..bdf20a6f2c 100644 --- a/src/calibre/ebooks/mobi/writer2/resources.py +++ b/src/calibre/ebooks/mobi/writer2/resources.py @@ -32,6 +32,7 @@ class Resources(object): self.used_image_indices = set() self.image_indices = set() self.cover_offset = self.thumbnail_offset = None + self.has_fonts = False self.add_resources(add_fonts) @@ -109,6 +110,7 @@ class Resources(object): 'ttf', 'otf'} and isinstance(item.data, bytes): self.records.append(write_font_record(item.data)) self.item_map[item.href] = len(self.records) + self.has_fonts = True def add_extra_images(self): ''' diff --git a/src/calibre/ebooks/mobi/writer8/exth.py b/src/calibre/ebooks/mobi/writer8/exth.py index daf6da62d6..0af54946cb 100644 --- a/src/calibre/ebooks/mobi/writer8/exth.py +++ b/src/calibre/ebooks/mobi/writer8/exth.py @@ -12,6 +12,7 @@ from struct import pack from io import BytesIO from calibre.ebooks.mobi.utils import utf8_text +from calibre.utils.localization import lang_as_iso639_1 EXTH_CODES = { 'creator': 100, @@ -28,13 +29,15 @@ EXTH_CODES = { 'versionnumber': 114, 'startreading': 116, 'kf8_header_index': 121, - 'num_of_resources': 125, - 'kf8_unknown_count': 131, + 'kf8_unknown_count': 125, + 'kf8_thumbnail_uri': 129, + 'num_of_resources': 131, 'coveroffset': 201, 'thumboffset': 202, 'hasfakecover': 203, 'lastupdatetime': 502, 'title': 503, + 'language': 524, } COLLAPSE_RE = re.compile(r'[ \t\r\n\v]+') @@ -57,6 +60,16 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, else: creators = [unicode(c) for c in items] items = creators + elif term == 'rights': + try: + rights = utf8_text(unicode(metadata.rights[0])) + except: + rights = b'Unknown' + exth.write(pack(b'>II', EXTH_CODES['rights'], len(rights) + 8)) + exth.write(rights) + nrecs += 1 + continue + for item in items: data = unicode(item) if term != 'description': @@ -68,18 +81,14 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, pass else: continue + if term == 'language': + d2 = lang_as_iso639_1(data) + if d2: + data = d2 data = utf8_text(data) exth.write(pack(b'>II', code, len(data) + 8)) exth.write(data) nrecs += 1 - if term == 'rights' : - try: - rights = utf8_text(unicode(metadata.rights[0])) - except: - rights = b'Unknown' - exth.write(pack(b'>II', EXTH_CODES['rights'], len(rights) + 8)) - exth.write(rights) - nrecs += 1 # Write UUID as ASIN uuid = None @@ -132,7 +141,7 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, nrecs += 1 if be_kindlegen2: - vals = {204:201, 205:2, 206:2, 207:35621} + vals = {204:201, 205:2, 206:5, 207:0} elif is_periodical: # Pretend to be amazon's super secret periodical generator vals = {204:201, 205:2, 206:0, 207:101} @@ -151,7 +160,10 @@ def build_exth(metadata, prefer_author_sort=False, is_periodical=False, if thumbnail_offset is not None: exth.write(pack(b'>III', EXTH_CODES['thumboffset'], 12, thumbnail_offset)) - nrecs += 1 + cover_uri_str = bytes('kindle:embed:%04X' %(thumbnail_offset)) + exth.write(pack(b'>II', EXTH_CODES['kf8_thumbnail_uri'], len(cover_uri_str) + 8)) + exth.write(cover_uri_str) + nrecs += 2 if start_offset is not None: try: diff --git a/src/calibre/ebooks/mobi/writer8/mobi.py b/src/calibre/ebooks/mobi/writer8/mobi.py index 48e0833ddb..769b301a50 100644 --- a/src/calibre/ebooks/mobi/writer8/mobi.py +++ b/src/calibre/ebooks/mobi/writer8/mobi.py @@ -277,6 +277,8 @@ class KF8Book(object): self.exth_flags = 0b1010000 if writer.opts.mobi_periodical: self.exth_flags |= 0b1000 + if resources.has_fonts: + self.exth_flags |= 0b1000000000000 self.opts = writer.opts self.start_offset = writer.start_offset diff --git a/src/calibre/gui2/__init__.py b/src/calibre/gui2/__init__.py index 370e2dc993..00f5bef03d 100644 --- a/src/calibre/gui2/__init__.py +++ b/src/calibre/gui2/__init__.py @@ -573,17 +573,24 @@ class FileDialog(QObject): if not isinstance(initial_dir, basestring): initial_dir = os.path.expanduser(default_dir) self.selected_files = [] + use_native_dialog = not os.environ.has_key('CALIBRE_NO_NATIVE_FILEDIALOGS') with SanitizeLibraryPath(): + opts = QFileDialog.Option() + if not use_native_dialog: + opts |= QFileDialog.DontUseNativeDialog if mode == QFileDialog.AnyFile: - f = unicode(QFileDialog.getSaveFileName(parent, title, initial_dir, ftext, "")) + f = unicode(QFileDialog.getSaveFileName(parent, title, + initial_dir, ftext, "", opts)) if f: self.selected_files.append(f) elif mode == QFileDialog.ExistingFile: - f = unicode(QFileDialog.getOpenFileName(parent, title, initial_dir, ftext, "")) + f = unicode(QFileDialog.getOpenFileName(parent, title, + initial_dir, ftext, "", opts)) if f and os.path.exists(f): self.selected_files.append(f) elif mode == QFileDialog.ExistingFiles: - fs = QFileDialog.getOpenFileNames(parent, title, initial_dir, ftext, "") + fs = QFileDialog.getOpenFileNames(parent, title, initial_dir, + ftext, "", opts) for f in fs: f = unicode(f) if not f: continue @@ -594,7 +601,8 @@ class FileDialog(QObject): if f and os.path.exists(f): self.selected_files.append(f) else: - opts = QFileDialog.ShowDirsOnly if mode == QFileDialog.Directory else QFileDialog.Option() + if mode == QFileDialog.Directory: + opts |= QFileDialog.ShowDirsOnly f = unicode(QFileDialog.getExistingDirectory(parent, title, initial_dir, opts)) if os.path.exists(f): self.selected_files.append(f) diff --git a/src/calibre/gui2/complete.py b/src/calibre/gui2/complete.py index ec2720b534..1c2d567130 100644 --- a/src/calibre/gui2/complete.py +++ b/src/calibre/gui2/complete.py @@ -16,7 +16,6 @@ from PyQt4.Qt import (QLineEdit, QAbstractListModel, Qt, from calibre.utils.icu import sort_key from calibre.gui2 import NONE from calibre.gui2.widgets import EnComboBox, LineEditECM -from calibre.utils.config_base import tweaks class CompleteModel(QAbstractListModel): @@ -27,7 +26,7 @@ class CompleteModel(QAbstractListModel): def set_items(self, items): items = [unicode(x.strip()) for x in items] - if len(items) < tweaks['completion_change_to_ascii_sorting']: + if len(items) < 2500: self.items = sorted(items, key=sort_key) self.sorting = QCompleter.UnsortedModel else: diff --git a/src/calibre/gui2/complete2.py b/src/calibre/gui2/complete2.py index dc2b6e8e91..8e0718c78e 100644 --- a/src/calibre/gui2/complete2.py +++ b/src/calibre/gui2/complete2.py @@ -284,6 +284,8 @@ class LineEdit(QLineEdit, LineEditECM): if self.no_popup: return self.update_completions() select_first = len(self.mcompleter.model().current_prefix) > 0 + if not select_first: + self.mcompleter.setCurrentIndex(QModelIndex()) self.complete(select_first=select_first) def update_completions(self): @@ -357,9 +359,8 @@ class EditWithComplete(EnComboBox): def show_initial_value(self, what): what = unicode(what) if what else u'' - le = self.lineEdit() - self.setEditText(what) - le.selectAll() + self.setText(what) + self.lineEdit().selectAll() @dynamic_property def all_items(self): @@ -373,6 +374,9 @@ class EditWithComplete(EnComboBox): def text(self): return unicode(self.lineEdit().text()) + def selectAll(self): + self.lineEdit().selectAll() + def setText(self, val): le = self.lineEdit() le.no_popup = True diff --git a/src/calibre/gui2/library/delegates.py b/src/calibre/gui2/library/delegates.py index 0c2d050860..4c26bf9ded 100644 --- a/src/calibre/gui2/library/delegates.py +++ b/src/calibre/gui2/library/delegates.py @@ -125,12 +125,15 @@ class TextDelegate(QStyledItemDelegate): # {{{ editor.set_separator(None) complete_items = [i[1] for i in self.auto_complete_function()] editor.update_items_cache(complete_items) - ct = index.data(Qt.DisplayRole).toString() - editor.show_initial_value(ct) else: editor = EnLineEdit(parent) return editor + def setEditorData(self, editor, index): + ct = unicode(index.data(Qt.DisplayRole).toString()) + editor.setText(ct) + editor.selectAll() + def setModelData(self, editor, model, index): if isinstance(editor, EditWithComplete): val = editor.lineEdit().text() @@ -164,12 +167,15 @@ class CompleteDelegate(QStyledItemDelegate): # {{{ all_items = list(self.db.all_custom( label=self.db.field_metadata.key_to_label(col))) editor.update_items_cache(all_items) - ct = index.data(Qt.DisplayRole).toString() - editor.show_initial_value(ct) else: editor = EnLineEdit(parent) return editor + def setEditorData(self, editor, index): + ct = unicode(index.data(Qt.DisplayRole).toString()) + editor.setText(ct) + editor.selectAll() + def setModelData(self, editor, model, index): if isinstance(editor, EditWithComplete): val = editor.lineEdit().text() @@ -183,10 +189,12 @@ class LanguagesDelegate(QStyledItemDelegate): # {{{ def createEditor(self, parent, option, index): editor = LanguagesEdit(parent=parent) editor.init_langs(index.model().db) - ct = index.data(Qt.DisplayRole).toString() - editor.show_initial_value(ct) return editor + def setEditorData(self, editor, index): + ct = unicode(index.data(Qt.DisplayRole).toString()) + editor.show_initial_value(ct) + def setModelData(self, editor, model, index): val = ','.join(editor.lang_codes) model.setData(index, QVariant(val), Qt.EditRole) @@ -251,6 +259,14 @@ class CcTextDelegate(QStyledItemDelegate): # {{{ editor.update_items_cache(complete_items) return editor + def setEditorData(self, editor, index): + ct = unicode(index.data(Qt.DisplayRole).toString()) + editor.setText(ct) + editor.selectAll() + + def setModelData(self, editor, model, index): + val = editor.text() + model.setData(index, QVariant(val), Qt.EditRole) # }}} class CcNumberDelegate(QStyledItemDelegate): # {{{ diff --git a/src/calibre/gui2/preferences/search.py b/src/calibre/gui2/preferences/search.py index b5998022e7..5c9e31790a 100644 --- a/src/calibre/gui2/preferences/search.py +++ b/src/calibre/gui2/preferences/search.py @@ -184,7 +184,6 @@ class ConfigWidget(ConfigWidgetBase, Ui_Form): self.opt_grouped_search_make_user_categories.update_items_cache(terms) self.gst_names.blockSignals(True) self.gst_names.clear() - print (1111, self.gst_names) self.gst_names.addItem('', '') for t in terms: self.gst_names.addItem(t, t) diff --git a/src/calibre/library/caches.py b/src/calibre/library/caches.py index 4f0cc82fa9..e9bb6286f3 100644 --- a/src/calibre/library/caches.py +++ b/src/calibre/library/caches.py @@ -156,12 +156,14 @@ def _match(query, value, matchkind): elif query == t: return True elif matchkind == REGEXP_MATCH: - return re.search(query, t, re.I|re.UNICODE) + if re.search(query, t, re.I|re.UNICODE): + return True elif matchkind == CONTAINS_MATCH: if pref_use_primary_find_in_search: - return primary_find(query, t)[0] != -1 - else: - return query in t + if primary_find(query, t)[0] != -1: + return True + elif query in t: + return True except re.error: pass return False diff --git a/src/calibre/translations/calibre.pot b/src/calibre/translations/calibre.pot index 0da59a2354..5ec9811e64 100644 --- a/src/calibre/translations/calibre.pot +++ b/src/calibre/translations/calibre.pot @@ -5,8 +5,8 @@ msgid "" msgstr "" "Project-Id-Version: calibre 0.8.60\n" -"POT-Creation-Date: 2012-07-13 10:25+IST\n" -"PO-Revision-Date: 2012-07-13 10:25+IST\n" +"POT-Creation-Date: 2012-07-13 16:26+IST\n" +"PO-Revision-Date: 2012-07-13 16:26+IST\n" "Last-Translator: Automatically generated\n" "Language-Team: LANGUAGE\n" "MIME-Version: 1.0\n" @@ -1459,7 +1459,7 @@ msgid "Kobo database version unsupported - See details" msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:609 -msgid "Your Kobo is running an updated firmware/database version As Calibre has not been updated, database editing is disabled. You can enable support for your Kobo in plugin preferences. Doing so may require you to perform a factory reset. before selecting the \"Attempt to support newer firmware\" option you should be familiar with restoring your Kobo to factory defaults." +msgid "Your Kobo is running an updated firmware/database version. As Calibre has not been updated, database editing is disabled. You can enable support for your Kobo in plugin preferences. Doing so may require you to perform a factory reset. Before selecting the \"Attempt to support newer firmware\" option you should be familiar with restoring your Kobo to factory defaults." msgstr "" #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:630 @@ -16981,7 +16981,8 @@ msgid "Choose columns to be searched when not using prefixes, as for example, wh msgstr "" #: /home/kovid/work/calibre/src/calibre/utils/config_base.py:426 -msgid "Characters typed in the search box will match their accented versions, based on the language you have chosen for the calibre interface. For example, in English, searching for n will match and n, but if your language is Spanish it will only match n. Note that this is much slower than a simple search on very large libraries." +#, python-format +msgid "Characters typed in the search box will match their accented versions, based on the language you have chosen for the calibre interface. For example, in English, searching for n will match %s and n, but if your language is Spanish it will only match n. Note that this is much slower than a simple search on very large libraries." msgstr "" #: /home/kovid/work/calibre/src/calibre/utils/formatter.py:31 @@ -18179,5 +18180,5 @@ msgid "Enable multi-character first-letters in the tag browser" msgstr "" #: /home/kovid/work/calibre/resources/default_tweaks.py:518 -msgid "Some languages have letters that can be represented by multiple characters.\nFor example, Czech has a 'character' \"ch\" that sorts between \"h\" and \"i\".\nIf this tweak is True, then the tag browser will take these characters into\nconsideration when partitioning by first letter.\nExamples:\nenable_multicharacters_in_tag_browser = True\nenable_multicharacters_in_tag_browser = True" +msgid "Some languages have letters that can be represented by multiple characters.\nFor example, Czech has a 'character' \"ch\" that sorts between \"h\" and \"i\".\nIf this tweak is True, then the tag browser will take these characters into\nconsideration when partitioning by first letter.\nExamples:\nenable_multicharacters_in_tag_browser = True\nenable_multicharacters_in_tag_browser = False" msgstr "" diff --git a/src/calibre/utils/config_base.py b/src/calibre/utils/config_base.py index 198c09bfcd..a31b7052b1 100644 --- a/src/calibre/utils/config_base.py +++ b/src/calibre/utils/config_base.py @@ -423,13 +423,13 @@ def _prefs(): 'separated by commas. Only takes effect if you set the option ' 'to limit search columns above.')) c.add_opt('use_primary_find_in_search', default=True, - help=_('Characters typed in the search box will match their ' + help=_(u'Characters typed in the search box will match their ' 'accented versions, based on the language you have chosen ' 'for the calibre interface. For example, in ' - u' English, searching for n will match ñ and n, but if ' + u' English, searching for n will match %s and n, but if ' 'your language is Spanish it will only match n. Note that ' 'this is much slower than a simple search on very large ' - 'libraries.')) + 'libraries.')%u'\xf1') c.add_opt('migrated', default=False, help='For Internal use. Don\'t modify.') return c