mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
KG updates
This commit is contained in:
commit
de4534e150
@ -594,7 +594,7 @@ from calibre.devices.iliad.driver import ILIAD
|
|||||||
from calibre.devices.irexdr.driver import IREXDR1000, IREXDR800
|
from calibre.devices.irexdr.driver import IREXDR1000, IREXDR800
|
||||||
from calibre.devices.jetbook.driver import JETBOOK, MIBUK, JETBOOK_MINI
|
from calibre.devices.jetbook.driver import JETBOOK, MIBUK, JETBOOK_MINI
|
||||||
from calibre.devices.kindle.driver import KINDLE, KINDLE2, KINDLE_DX
|
from calibre.devices.kindle.driver import KINDLE, KINDLE2, KINDLE_DX
|
||||||
from calibre.devices.nook.driver import NOOK, NOOK_COLOR, NOOK_TSR
|
from calibre.devices.nook.driver import NOOK, NOOK_COLOR
|
||||||
from calibre.devices.prs505.driver import PRS505
|
from calibre.devices.prs505.driver import PRS505
|
||||||
from calibre.devices.user_defined.driver import USER_DEFINED
|
from calibre.devices.user_defined.driver import USER_DEFINED
|
||||||
from calibre.devices.android.driver import ANDROID, S60
|
from calibre.devices.android.driver import ANDROID, S60
|
||||||
@ -603,10 +603,11 @@ from calibre.devices.eslick.driver import ESLICK, EBK52
|
|||||||
from calibre.devices.nuut2.driver import NUUT2
|
from calibre.devices.nuut2.driver import NUUT2
|
||||||
from calibre.devices.iriver.driver import IRIVER_STORY
|
from calibre.devices.iriver.driver import IRIVER_STORY
|
||||||
from calibre.devices.binatone.driver import README
|
from calibre.devices.binatone.driver import README
|
||||||
from calibre.devices.hanvon.driver import N516, EB511, ALEX, AZBOOKA, THEBOOK
|
from calibre.devices.hanvon.driver import (N516, EB511, ALEX, AZBOOKA, THEBOOK,
|
||||||
|
LIBREAIR)
|
||||||
from calibre.devices.edge.driver import EDGE
|
from calibre.devices.edge.driver import EDGE
|
||||||
from calibre.devices.teclast.driver import TECLAST_K3, NEWSMY, IPAPYRUS, \
|
from calibre.devices.teclast.driver import (TECLAST_K3, NEWSMY, IPAPYRUS,
|
||||||
SOVOS, PICO, SUNSTECH_EB700, ARCHOS7O, STASH, WEXLER
|
SOVOS, PICO, SUNSTECH_EB700, ARCHOS7O, STASH, WEXLER)
|
||||||
from calibre.devices.sne.driver import SNE
|
from calibre.devices.sne.driver import SNE
|
||||||
from calibre.devices.misc import (PALMPRE, AVANT, SWEEX, PDNOVEL,
|
from calibre.devices.misc import (PALMPRE, AVANT, SWEEX, PDNOVEL,
|
||||||
GEMEI, VELOCITYMICRO, PDNOVEL_KOBO, LUMIREAD, ALURATEK_COLOR,
|
GEMEI, VELOCITYMICRO, PDNOVEL_KOBO, LUMIREAD, ALURATEK_COLOR,
|
||||||
@ -693,7 +694,7 @@ plugins += [
|
|||||||
KINDLE,
|
KINDLE,
|
||||||
KINDLE2,
|
KINDLE2,
|
||||||
KINDLE_DX,
|
KINDLE_DX,
|
||||||
NOOK, NOOK_COLOR, NOOK_TSR,
|
NOOK, NOOK_COLOR,
|
||||||
PRS505,
|
PRS505,
|
||||||
ANDROID,
|
ANDROID,
|
||||||
S60,
|
S60,
|
||||||
@ -716,7 +717,7 @@ plugins += [
|
|||||||
EB600,
|
EB600,
|
||||||
README,
|
README,
|
||||||
N516,
|
N516,
|
||||||
THEBOOK,
|
THEBOOK, LIBREAIR,
|
||||||
EB511,
|
EB511,
|
||||||
ELONEX,
|
ELONEX,
|
||||||
TECLAST_K3,
|
TECLAST_K3,
|
||||||
|
@ -52,6 +52,18 @@ class THEBOOK(N516):
|
|||||||
EBOOK_DIR_MAIN = 'My books'
|
EBOOK_DIR_MAIN = 'My books'
|
||||||
WINDOWS_CARD_A_MEM = '_FILE-STOR_GADGE'
|
WINDOWS_CARD_A_MEM = '_FILE-STOR_GADGE'
|
||||||
|
|
||||||
|
class LIBREAIR(N516):
|
||||||
|
name = 'Libre Air Driver'
|
||||||
|
gui_name = 'Libre Air'
|
||||||
|
description = _('Communicate with the Libre Air reader.')
|
||||||
|
author = 'Kovid Goyal'
|
||||||
|
FORMATS = ['epub', 'mobi', 'prc', 'fb2', 'rtf', 'txt', 'pdf']
|
||||||
|
|
||||||
|
BCD = [0x399]
|
||||||
|
VENDOR_NAME = 'ALURATEK'
|
||||||
|
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = '_FILE-STOR_GADGET'
|
||||||
|
EBOOK_DIR_MAIN = 'Books'
|
||||||
|
|
||||||
class ALEX(N516):
|
class ALEX(N516):
|
||||||
|
|
||||||
name = 'Alex driver'
|
name = 'Alex driver'
|
||||||
|
@ -81,55 +81,27 @@ class NOOK(USBMS):
|
|||||||
return [x.replace('#', '_') for x in components]
|
return [x.replace('#', '_') for x in components]
|
||||||
|
|
||||||
class NOOK_COLOR(NOOK):
|
class NOOK_COLOR(NOOK):
|
||||||
gui_name = _('Nook Color')
|
description = _('Communicate with the Nook Color and TSR eBook readers.')
|
||||||
description = _('Communicate with the Nook Color eBook reader.')
|
|
||||||
|
|
||||||
PRODUCT_ID = [0x002]
|
PRODUCT_ID = [0x002, 0x003]
|
||||||
BCD = [0x216]
|
BCD = [0x216]
|
||||||
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOK_DISK'
|
|
||||||
|
|
||||||
|
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOK_DISK'
|
||||||
EBOOK_DIR_MAIN = 'My Files'
|
EBOOK_DIR_MAIN = 'My Files'
|
||||||
|
|
||||||
|
def upload_cover(self, path, filename, metadata, filepath):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_carda_ebook_dir(self, for_upload=False):
|
||||||
|
if for_upload:
|
||||||
|
return self.EBOOK_DIR_MAIN
|
||||||
|
return ''
|
||||||
|
|
||||||
def create_upload_path(self, path, mdata, fname, create_dirs=True):
|
def create_upload_path(self, path, mdata, fname, create_dirs=True):
|
||||||
filepath = NOOK.create_upload_path(self, path, mdata, fname,
|
is_news = mdata.tags and _('News') in mdata.tags
|
||||||
create_dirs=False)
|
subdir = 'Magazines' if is_news else 'Books'
|
||||||
edm = self.EBOOK_DIR_MAIN
|
path = os.path.join(path, subdir)
|
||||||
subdir = 'Books'
|
return USBMS.create_upload_path(self, path, mdata, fname,
|
||||||
if mdata.tags:
|
create_dirs=create_dirs)
|
||||||
if _('News') in mdata.tags:
|
|
||||||
subdir = 'Magazines'
|
|
||||||
filepath = filepath.replace(os.sep+edm+os.sep,
|
|
||||||
os.sep+edm+os.sep+subdir+os.sep)
|
|
||||||
filedir = os.path.dirname(filepath)
|
|
||||||
if create_dirs and not os.path.exists(filedir):
|
|
||||||
os.makedirs(filedir)
|
|
||||||
|
|
||||||
return filepath
|
|
||||||
|
|
||||||
def upload_cover(self, path, filename, metadata, filepath):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_carda_ebook_dir(self, for_upload=False):
|
|
||||||
if for_upload:
|
|
||||||
return 'My Files/Books'
|
|
||||||
return ''
|
|
||||||
|
|
||||||
class NOOK_TSR(NOOK):
|
|
||||||
gui_name = _('Nook Simple')
|
|
||||||
description = _('Communicate with the Nook TSR eBook reader.')
|
|
||||||
|
|
||||||
PRODUCT_ID = [0x003]
|
|
||||||
BCD = [0x216]
|
|
||||||
|
|
||||||
EBOOK_DIR_MAIN = 'My Files/Books'
|
|
||||||
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOK_DISK'
|
|
||||||
|
|
||||||
def upload_cover(self, path, filename, metadata, filepath):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_carda_ebook_dir(self, for_upload=False):
|
|
||||||
if for_upload:
|
|
||||||
return 'My Files/Books'
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -394,6 +394,13 @@ class EPUBOutput(OutputFormatPlugin):
|
|||||||
for tag in XPath('//h:img[@src]')(root):
|
for tag in XPath('//h:img[@src]')(root):
|
||||||
tag.set('src', tag.get('src', '').replace('&', ''))
|
tag.set('src', tag.get('src', '').replace('&', ''))
|
||||||
|
|
||||||
|
# ADE whimpers in fright when it encounters a <td> outside a
|
||||||
|
# <table>
|
||||||
|
in_table = XPath('ancestor::h:table')
|
||||||
|
for tag in XPath('//h:td|//h:tr|//h:th')(root):
|
||||||
|
if not in_table(tag):
|
||||||
|
tag.tag = XHTML('div')
|
||||||
|
|
||||||
special_chars = re.compile(u'[\u200b\u00ad]')
|
special_chars = re.compile(u'[\u200b\u00ad]')
|
||||||
for elem in root.iterdescendants():
|
for elem in root.iterdescendants():
|
||||||
if getattr(elem, 'text', False):
|
if getattr(elem, 'text', False):
|
||||||
@ -413,7 +420,7 @@ class EPUBOutput(OutputFormatPlugin):
|
|||||||
rule.style.removeProperty('margin-left')
|
rule.style.removeProperty('margin-left')
|
||||||
# padding-left breaks rendering in webkit and gecko
|
# padding-left breaks rendering in webkit and gecko
|
||||||
rule.style.removeProperty('padding-left')
|
rule.style.removeProperty('padding-left')
|
||||||
# Change whitespace:pre to pre-line to accommodate readers that
|
# Change whitespace:pre to pre-wrap to accommodate readers that
|
||||||
# cannot scroll horizontally
|
# cannot scroll horizontally
|
||||||
for rule in stylesheet.data.cssRules.rulesOfType(CSSRule.STYLE_RULE):
|
for rule in stylesheet.data.cssRules.rulesOfType(CSSRule.STYLE_RULE):
|
||||||
style = rule.style
|
style = rule.style
|
||||||
|
@ -455,13 +455,16 @@ class HTMLInput(InputFormatPlugin):
|
|||||||
bhref = os.path.basename(link)
|
bhref = os.path.basename(link)
|
||||||
id, href = self.oeb.manifest.generate(id='added',
|
id, href = self.oeb.manifest.generate(id='added',
|
||||||
href=bhref)
|
href=bhref)
|
||||||
|
guessed = self.guess_type(href)[0]
|
||||||
|
media_type = guessed or self.BINARY_MIME
|
||||||
|
if 'text' in media_type:
|
||||||
|
self.log.warn('Ignoring link to text file %r'%link_)
|
||||||
|
return None
|
||||||
|
|
||||||
self.oeb.log.debug('Added', link)
|
self.oeb.log.debug('Added', link)
|
||||||
self.oeb.container = self.DirContainer(os.path.dirname(link),
|
self.oeb.container = self.DirContainer(os.path.dirname(link),
|
||||||
self.oeb.log, ignore_opf=True)
|
self.oeb.log, ignore_opf=True)
|
||||||
# Load into memory
|
# Load into memory
|
||||||
guessed = self.guess_type(href)[0]
|
|
||||||
media_type = guessed or self.BINARY_MIME
|
|
||||||
|
|
||||||
item = self.oeb.manifest.add(id, href, media_type)
|
item = self.oeb.manifest.add(id, href, media_type)
|
||||||
item.html_input_href = bhref
|
item.html_input_href = bhref
|
||||||
if guessed in self.OEB_STYLES:
|
if guessed in self.OEB_STYLES:
|
||||||
|
@ -442,9 +442,12 @@ class MobiMLizer(object):
|
|||||||
if tag in TABLE_TAGS and self.ignore_tables:
|
if tag in TABLE_TAGS and self.ignore_tables:
|
||||||
tag = 'span' if tag == 'td' else 'div'
|
tag = 'span' if tag == 'td' else 'div'
|
||||||
|
|
||||||
# GR: Added 'width', 'border' and 'scope'
|
if tag == 'table':
|
||||||
|
css = style.cssdict()
|
||||||
|
if 'border' in css or 'border-width' in css:
|
||||||
|
elem.set('border', '1')
|
||||||
if tag in TABLE_TAGS:
|
if tag in TABLE_TAGS:
|
||||||
for attr in ('rowspan', 'colspan','width','border','scope'):
|
for attr in ('rowspan', 'colspan', 'width', 'border', 'scope'):
|
||||||
if attr in elem.attrib:
|
if attr in elem.attrib:
|
||||||
istate.attrib[attr] = elem.attrib[attr]
|
istate.attrib[attr] = elem.attrib[attr]
|
||||||
if tag == 'q':
|
if tag == 'q':
|
||||||
|
@ -1110,6 +1110,8 @@ class DeviceBooksModel(BooksModel): # {{{
|
|||||||
if self.last_search:
|
if self.last_search:
|
||||||
self.searched.emit(True)
|
self.searched.emit(True)
|
||||||
|
|
||||||
|
def research(self, reset=True):
|
||||||
|
self.search(self.last_search, reset)
|
||||||
|
|
||||||
def sort(self, col, order, reset=True):
|
def sort(self, col, order, reset=True):
|
||||||
descending = order != Qt.AscendingOrder
|
descending = order != Qt.AscendingOrder
|
||||||
@ -1171,6 +1173,8 @@ class DeviceBooksModel(BooksModel): # {{{
|
|||||||
self.custom_columns = {}
|
self.custom_columns = {}
|
||||||
self.db = db
|
self.db = db
|
||||||
self.map = list(range(0, len(db)))
|
self.map = list(range(0, len(db)))
|
||||||
|
self.research(reset=False)
|
||||||
|
self.resort()
|
||||||
|
|
||||||
def cover(self, row):
|
def cover(self, row):
|
||||||
item = self.db[self.map[row]]
|
item = self.db[self.map[row]]
|
||||||
@ -1319,8 +1323,6 @@ class DeviceBooksModel(BooksModel): # {{{
|
|||||||
ans = Qt.AlignVCenter | ALIGNMENT_MAP[self.alignment_map.get(cname,
|
ans = Qt.AlignVCenter | ALIGNMENT_MAP[self.alignment_map.get(cname,
|
||||||
'left')]
|
'left')]
|
||||||
return QVariant(ans)
|
return QVariant(ans)
|
||||||
|
|
||||||
|
|
||||||
return NONE
|
return NONE
|
||||||
|
|
||||||
def headerData(self, section, orientation, role):
|
def headerData(self, section, orientation, role):
|
||||||
|
@ -48,7 +48,7 @@ class BooksView(QTableView): # {{{
|
|||||||
files_dropped = pyqtSignal(object)
|
files_dropped = pyqtSignal(object)
|
||||||
add_column_signal = pyqtSignal()
|
add_column_signal = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, parent, modelcls=BooksModel):
|
def __init__(self, parent, modelcls=BooksModel, use_edit_metadata_dialog=True):
|
||||||
QTableView.__init__(self, parent)
|
QTableView.__init__(self, parent)
|
||||||
|
|
||||||
self.setEditTriggers(self.EditKeyPressed)
|
self.setEditTriggers(self.EditKeyPressed)
|
||||||
@ -60,8 +60,12 @@ class BooksView(QTableView): # {{{
|
|||||||
elif tweaks['doubleclick_on_library_view'] == 'edit_metadata':
|
elif tweaks['doubleclick_on_library_view'] == 'edit_metadata':
|
||||||
# Must not enable single-click to edit, or the field will remain
|
# Must not enable single-click to edit, or the field will remain
|
||||||
# open in edit mode underneath the edit metadata dialog
|
# open in edit mode underneath the edit metadata dialog
|
||||||
self.doubleClicked.connect(
|
if use_edit_metadata_dialog:
|
||||||
partial(parent.iactions['Edit Metadata'].edit_metadata, checked=False))
|
self.doubleClicked.connect(
|
||||||
|
partial(parent.iactions['Edit Metadata'].edit_metadata,
|
||||||
|
checked=False))
|
||||||
|
else:
|
||||||
|
self.setEditTriggers(self.DoubleClicked|self.editTriggers())
|
||||||
|
|
||||||
self.drag_allowed = True
|
self.drag_allowed = True
|
||||||
self.setDragEnabled(True)
|
self.setDragEnabled(True)
|
||||||
@ -792,7 +796,8 @@ class BooksView(QTableView): # {{{
|
|||||||
class DeviceBooksView(BooksView): # {{{
|
class DeviceBooksView(BooksView): # {{{
|
||||||
|
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
BooksView.__init__(self, parent, DeviceBooksModel)
|
BooksView.__init__(self, parent, DeviceBooksModel,
|
||||||
|
use_edit_metadata_dialog=False)
|
||||||
self.can_add_columns = False
|
self.can_add_columns = False
|
||||||
self.columns_resized = False
|
self.columns_resized = False
|
||||||
self.resize_on_select = False
|
self.resize_on_select = False
|
||||||
|
@ -22,11 +22,7 @@ from calibre.library.coloring import (Rule, conditionable_columns,
|
|||||||
|
|
||||||
class ConditionEditor(QWidget): # {{{
|
class ConditionEditor(QWidget): # {{{
|
||||||
|
|
||||||
def __init__(self, fm, parent=None):
|
ACTION_MAP = {
|
||||||
QWidget.__init__(self, parent)
|
|
||||||
self.fm = fm
|
|
||||||
|
|
||||||
self.action_map = {
|
|
||||||
'bool' : (
|
'bool' : (
|
||||||
(_('is true'), 'is true',),
|
(_('is true'), 'is true',),
|
||||||
(_('is false'), 'is false'),
|
(_('is false'), 'is false'),
|
||||||
@ -61,10 +57,17 @@ class ConditionEditor(QWidget): # {{{
|
|||||||
(_('is set'), 'is set'),
|
(_('is set'), 'is set'),
|
||||||
(_('is not set'), 'is not set'),
|
(_('is not set'), 'is not set'),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in ('float', 'rating', 'datetime'):
|
for x in ('float', 'rating', 'datetime'):
|
||||||
self.action_map[x] = self.action_map['int']
|
ACTION_MAP[x] = ACTION_MAP['int']
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, fm, parent=None):
|
||||||
|
QWidget.__init__(self, parent)
|
||||||
|
self.fm = fm
|
||||||
|
|
||||||
|
self.action_map = self.ACTION_MAP
|
||||||
|
|
||||||
self.l = l = QGridLayout(self)
|
self.l = l = QGridLayout(self)
|
||||||
self.setLayout(l)
|
self.setLayout(l)
|
||||||
@ -446,9 +449,15 @@ class RulesModel(QAbstractListModel): # {{{
|
|||||||
|
|
||||||
def condition_to_html(self, condition):
|
def condition_to_html(self, condition):
|
||||||
c, a, v = condition
|
c, a, v = condition
|
||||||
|
action_name = a
|
||||||
|
for actions in ConditionEditor.ACTION_MAP.itervalues():
|
||||||
|
for trans, ac in actions:
|
||||||
|
if ac == a:
|
||||||
|
action_name = trans
|
||||||
|
|
||||||
return (
|
return (
|
||||||
_('<li>If the <b>%s</b> column <b>%s</b> value: <b>%s</b>') %
|
_('<li>If the <b>%s</b> column <b>%s</b> value: <b>%s</b>') %
|
||||||
(c, a, prepare_string_for_xml(v)))
|
(c, action_name, prepare_string_for_xml(v)))
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ __license__ = 'GPL 3'
|
|||||||
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
__copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
from PyQt4.Qt import (QWidget, QIcon, QDialog)
|
from PyQt4.Qt import (QWidget, QIcon, QDialog, QComboBox)
|
||||||
|
|
||||||
from calibre.gui2.store.config.chooser.adv_search_builder import AdvSearchBuilderDialog
|
from calibre.gui2.store.config.chooser.adv_search_builder import AdvSearchBuilderDialog
|
||||||
from calibre.gui2.store.config.chooser.chooser_widget_ui import Ui_Form
|
from calibre.gui2.store.config.chooser.chooser_widget_ui import Ui_Form
|
||||||
@ -18,6 +18,8 @@ class StoreChooserWidget(QWidget, Ui_Form):
|
|||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
|
||||||
self.query.initialize('store_config_chooser_query')
|
self.query.initialize('store_config_chooser_query')
|
||||||
|
self.query.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
|
||||||
|
self.query.setMinimumContentsLength(25)
|
||||||
|
|
||||||
self.adv_search_builder.setIcon(QIcon(I('search.png')))
|
self.adv_search_builder.setIcon(QIcon(I('search.png')))
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ __copyright__ = '2011, John Schember <john@nachtimwald.com>'
|
|||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
|
||||||
from PyQt4.Qt import (Qt, QDialog, QIcon)
|
from PyQt4.Qt import (Qt, QDialog, QIcon, QComboBox)
|
||||||
|
|
||||||
from calibre.gui2.store.mobileread.adv_search_builder import AdvSearchBuilderDialog
|
from calibre.gui2.store.mobileread.adv_search_builder import AdvSearchBuilderDialog
|
||||||
from calibre.gui2.store.mobileread.models import BooksModel
|
from calibre.gui2.store.mobileread.models import BooksModel
|
||||||
@ -21,6 +21,8 @@ class MobileReadStoreDialog(QDialog, Ui_Dialog):
|
|||||||
|
|
||||||
self.plugin = plugin
|
self.plugin = plugin
|
||||||
self.search_query.initialize('store_mobileread_search')
|
self.search_query.initialize('store_mobileread_search')
|
||||||
|
self.search_query.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
|
||||||
|
self.search_query.setMinimumContentsLength(25)
|
||||||
|
|
||||||
self.adv_search_button.setIcon(QIcon(I('search.png')))
|
self.adv_search_button.setIcon(QIcon(I('search.png')))
|
||||||
|
|
||||||
|
@ -10,7 +10,8 @@ import re
|
|||||||
from random import shuffle
|
from random import shuffle
|
||||||
|
|
||||||
from PyQt4.Qt import (Qt, QDialog, QDialogButtonBox, QTimer, QCheckBox, QLabel,
|
from PyQt4.Qt import (Qt, QDialog, QDialogButtonBox, QTimer, QCheckBox, QLabel,
|
||||||
QVBoxLayout, QIcon, QWidget, QTabWidget, QGridLayout)
|
QVBoxLayout, QIcon, QWidget, QTabWidget, QGridLayout,
|
||||||
|
QComboBox)
|
||||||
|
|
||||||
from calibre.gui2 import JSONConfig, info_dialog
|
from calibre.gui2 import JSONConfig, info_dialog
|
||||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||||
@ -57,6 +58,8 @@ class SearchDialog(QDialog, Ui_Dialog):
|
|||||||
|
|
||||||
# Set the search query
|
# Set the search query
|
||||||
self.search_edit.setText(query)
|
self.search_edit.setText(query)
|
||||||
|
self.search_edit.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon)
|
||||||
|
self.search_edit.setMinimumContentsLength(25)
|
||||||
|
|
||||||
# Create and add the progress indicator
|
# Create and add the progress indicator
|
||||||
self.pi = ProgressIndicator(self, 24)
|
self.pi = ProgressIndicator(self, 24)
|
||||||
|
@ -610,7 +610,7 @@ class TagTreeItem(object): # {{{
|
|||||||
self.temporary = temporary
|
self.temporary = temporary
|
||||||
self.tag = Tag(data, category=category_key,
|
self.tag = Tag(data, category=category_key,
|
||||||
is_editable=category_key not in ['news', 'search', 'identifiers'],
|
is_editable=category_key not in ['news', 'search', 'identifiers'],
|
||||||
is_searchable=category_key not in ['news', 'search'])
|
is_searchable=category_key not in ['search'])
|
||||||
|
|
||||||
elif self.type == self.TAG:
|
elif self.type == self.TAG:
|
||||||
self.icon_state_map[0] = QVariant(data.icon)
|
self.icon_state_map[0] = QVariant(data.icon)
|
||||||
@ -1642,7 +1642,13 @@ class TagsModel(QAbstractItemModel): # {{{
|
|||||||
|
|
||||||
for node in self.category_nodes:
|
for node in self.category_nodes:
|
||||||
if node.tag.state:
|
if node.tag.state:
|
||||||
ans.append('%s:%s'%(node.category_key, node_searches[node.tag.state]))
|
if node.category_key == "news":
|
||||||
|
if node_searches[node.tag.state] == 'true':
|
||||||
|
ans.append('tags:=news')
|
||||||
|
else:
|
||||||
|
ans.append('( not tags:=news )')
|
||||||
|
else:
|
||||||
|
ans.append('%s:%s'%(node.category_key, node_searches[node.tag.state]))
|
||||||
|
|
||||||
key = node.category_key
|
key = node.category_key
|
||||||
for tag_item in node.child_tags():
|
for tag_item in node.child_tags():
|
||||||
|
@ -417,7 +417,7 @@ You might find the following tips useful.
|
|||||||
|
|
||||||
* Create a custom composite column to test templates. Once you have the column, you can change its template simply by double-clicking on the column. Hide the column when you are not testing.
|
* Create a custom composite column to test templates. Once you have the column, you can change its template simply by double-clicking on the column. Hide the column when you are not testing.
|
||||||
* Templates can use other templates by referencing a composite custom column.
|
* Templates can use other templates by referencing a composite custom column.
|
||||||
* In a plugboard, you can set a field to empty (or whatever is equivalent to empty) by using the special template ``{null}``. This template will always evaluate to an empty string.
|
* In a plugboard, you can set a field to empty (or whatever is equivalent to empty) by using the special template ``{}``. This template will always evaluate to an empty string.
|
||||||
* The technique described above to show numbers even if they have a zero value works with the standard field series_index.
|
* The technique described above to show numbers even if they have a zero value works with the standard field series_index.
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
@ -101,6 +101,7 @@ def get_custom_recipe_collection(*args):
|
|||||||
if recipe_class is not None:
|
if recipe_class is not None:
|
||||||
rmap['custom:%s'%id_] = recipe_class
|
rmap['custom:%s'%id_] = recipe_class
|
||||||
except:
|
except:
|
||||||
|
print 'Failed to load recipe from: %r'%fname
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
continue
|
continue
|
||||||
|
Loading…
x
Reference in New Issue
Block a user