This commit is contained in:
ingkebil 2014-04-04 22:41:12 +02:00
commit 05fb53ff42
8 changed files with 129 additions and 34 deletions

View File

@ -20,6 +20,53 @@
# new recipes: # new recipes:
# - title: # - title:
- version: 1.31.0
date: 2014-04-04
new features:
- title: "DOCX Input: Support for converting indexes created using the Word Index tool. The entries in the index are automatically converted into links pointing to the indexed locations."
- title: "AZW3 Output: Add support for converting documents with very large table of contents (with more than 2000 entries)."
tickets: [1250475]
- title: "Edit Book: Add a button to easily insert HTML tags. Useful if you want to quickly surround selected text with an arbitrary tag. You can right click the button to get a list of recently used tags."
- title: "Driver for Tolino Vision (OS X/Linux only)."
tickets: [1301875]
- title: "Edit book: Allow editing SVG files as raw XML"
bug fixes:
- title: "DOCX Input: Fix incorrect numbering being generated for numbered lists in some circumstances."
tickets: [1301044]
- title: "calibredb check_library: Do not create empty library if user specifies incorrect path"
- title: "DOCX Input: Fix handling of hyperlinks in documents where the hyperlink is specified as a field internally (Microsoft Word does not use fields for hyperlinks)"
- title: "Get Books: Update WH Smiths plugin for website changes and remove Diesel eBooks, as they are shutting down"
- title: "AZW3 Output: Fix a bug that caused popup footnotes in some AZW3 files to not work properly. The popup would show all remaining footnotes instead of only the current footnote."
tickets: [1293290]
- title: "AZW3 Output: Various tweaks to the internal structure and headers of the output file to make it closer to what kindlegen 2.9 generates"
- title: "Edit Book: When user is editing files belonging to another user account on linux/os x rather than erroring out when saving, change the ownership of the file to the editing user."
tickets: [1299097]
- title: "Edit Book: Fix insert Inline ToC creating non-linear jumps in class names"
- title: "Fix regression that broke ebook-device cp"
improved recipes:
- CNET
- El Pais Impreso
- CNet News
- Antyweb
new recipes:
- title:
- version: 1.30.0 - version: 1.30.0
date: 2014-03-28 date: 2014-03-28

View File

@ -4,7 +4,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
__appname__ = u'calibre' __appname__ = u'calibre'
numeric_version = (1, 30, 0) numeric_version = (1, 31, 0)
__version__ = u'.'.join(map(unicode, numeric_version)) __version__ = u'.'.join(map(unicode, numeric_version))
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>" __author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"

View File

@ -229,9 +229,6 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
for n1, k1 in cols: for n1, k1 in cols:
self.colored_field.addItem(n1, k1) self.colored_field.addItem(n1, k1)
self.colored_field.setCurrentIndex(self.colored_field.findData(color_field)) self.colored_field.setCurrentIndex(self.colored_field.findData(color_field))
colors = QColor.colorNames()
colors.sort()
self.color_name.addItems(colors)
elif self.iconing: elif self.iconing:
self.icon_layout.setVisible(True) self.icon_layout.setVisible(True)
for n1, k1 in cols: for n1, k1 in cols:
@ -362,7 +359,7 @@ class TemplateDialog(QDialog, Ui_TemplateDialog):
def color_to_clipboard(self): def color_to_clipboard(self):
app = QApplication.instance() app = QApplication.instance()
c = app.clipboard() c = app.clipboard()
c.setText(unicode(self.color_name.currentText())) c.setText(unicode(self.color_name.color))
def icon_to_clipboard(self): def icon_to_clipboard(self):
app = QApplication.instance() app = QApplication.instance()

View File

@ -48,7 +48,7 @@
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<widget class="QComboBox" name="color_name"> <widget class="ColorButton" name="color_name">
</widget> </widget>
</item> </item>
<item row="1" column="2"> <item row="1" column="2">
@ -246,6 +246,13 @@
</item> </item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>ColorButton</class>
<extends>QPushButton</extends>
<header>calibre/gui2/widgets2.h</header>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections> <connections>
<connection> <connection>

View File

@ -10,7 +10,7 @@ __docformat__ = 'restructuredtext en'
import os, textwrap import os, textwrap
from PyQt4.Qt import (QWidget, QDialog, QLabel, QGridLayout, QComboBox, QSize, from PyQt4.Qt import (QWidget, QDialog, QLabel, QGridLayout, QComboBox, QSize,
QLineEdit, QIntValidator, QDoubleValidator, QFrame, QColor, Qt, QIcon, QLineEdit, QIntValidator, QDoubleValidator, QFrame, Qt, QIcon,
QScrollArea, QPushButton, QVBoxLayout, QDialogButtonBox, QToolButton, QScrollArea, QPushButton, QVBoxLayout, QDialogButtonBox, QToolButton,
QListView, QAbstractListModel, pyqtSignal, QSizePolicy, QSpacerItem, QListView, QAbstractListModel, pyqtSignal, QSizePolicy, QSpacerItem,
QApplication, QStandardItem, QStandardItemModel, QCheckBox) QApplication, QStandardItem, QStandardItemModel, QCheckBox)
@ -21,6 +21,7 @@ from calibre.utils.icu import sort_key
from calibre.gui2 import error_dialog, choose_files, pixmap_to_data from calibre.gui2 import error_dialog, choose_files, pixmap_to_data
from calibre.gui2.dialogs.template_dialog import TemplateDialog from calibre.gui2.dialogs.template_dialog import TemplateDialog
from calibre.gui2.metadata.single_download import RichTextDelegate from calibre.gui2.metadata.single_download import RichTextDelegate
from calibre.gui2.widgets2 import ColorButton
from calibre.library.coloring import (Rule, conditionable_columns, from calibre.library.coloring import (Rule, conditionable_columns,
displayable_columns, rule_from_template, color_row_key) displayable_columns, rule_from_template, color_row_key)
from calibre.utils.localization import lang_map from calibre.utils.localization import lang_map
@ -33,6 +34,7 @@ icon_rule_kinds = [(_('icon with text'), 'icon'),
(_('composed icons w/text'), 'icon_composed'), (_('composed icons w/text'), 'icon_composed'),
(_('composed icons w/no text'), 'icon_only_composed'),] (_('composed icons w/no text'), 'icon_only_composed'),]
class ConditionEditor(QWidget): # {{{ class ConditionEditor(QWidget): # {{{
ACTION_MAP = { ACTION_MAP = {
@ -86,7 +88,6 @@ class ConditionEditor(QWidget): # {{{
for x in ('float', 'rating'): for x in ('float', 'rating'):
ACTION_MAP[x] = ACTION_MAP['int'] ACTION_MAP[x] = ACTION_MAP['int']
def __init__(self, fm, parent=None): def __init__(self, fm, parent=None):
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.fm = fm self.fm = fm
@ -108,8 +109,6 @@ class ConditionEditor(QWidget): # {{{
self.column_box = QComboBox(self) self.column_box = QComboBox(self)
l.addWidget(self.column_box, 0, 1) l.addWidget(self.column_box, 0, 1)
self.l2 = l2 = QLabel(two) self.l2 = l2 = QLabel(two)
l.addWidget(l2, 0, 2) l.addWidget(l2, 0, 2)
@ -329,7 +328,7 @@ class RuleEditor(QDialog): # {{{
l.addWidget(l4, 2, 4) l.addWidget(l4, 2, 4)
if self.rule_kind == 'color': if self.rule_kind == 'color':
self.color_box = QComboBox(self) self.color_box = ColorButton(parent=self)
self.color_label = QLabel('Sample text Sample text') self.color_label = QLabel('Sample text Sample text')
self.color_label.setTextFormat(Qt.RichText) self.color_label.setTextFormat(Qt.RichText)
l.addWidget(self.color_box, 2, 5) l.addWidget(self.color_box, 2, 5)
@ -393,7 +392,7 @@ class RuleEditor(QDialog): # {{{
self.conditions = [] self.conditions = []
if self.rule_kind == 'color': if self.rule_kind == 'color':
for b in (self.column_box, self.color_box): for b in (self.column_box, ):
b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon) b.setSizeAdjustPolicy(b.AdjustToMinimumContentsLengthWithIcon)
b.setMinimumContentsLength(15) b.setMinimumContentsLength(15)
@ -407,10 +406,9 @@ class RuleEditor(QDialog): # {{{
self.column_box.setCurrentIndex(0) self.column_box.setCurrentIndex(0)
if self.rule_kind == 'color': if self.rule_kind == 'color':
self.color_box.addItems(QColor.colorNames()) self.color_box.color = '#000'
self.color_box.setCurrentIndex(0)
self.update_color_label() self.update_color_label()
self.color_box.currentIndexChanged.connect(self.update_color_label) self.color_box.color_changed.connect(self.update_color_label)
else: else:
self.rule_icon_files = [] self.rule_icon_files = []
self.filename_button.clicked.connect(self.filename_button_clicked) self.filename_button.clicked.connect(self.filename_button_clicked)
@ -436,10 +434,10 @@ class RuleEditor(QDialog): # {{{
for i,filename in enumerate(self.icon_file_names): for i,filename in enumerate(self.icon_file_names):
item = QStandardItem(filename) item = QStandardItem(filename)
if doing_multiple: if doing_multiple:
item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled); item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
item.setData(Qt.Unchecked, Qt.CheckStateRole) item.setData(Qt.Unchecked, Qt.CheckStateRole)
else: else:
item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable); item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
icon = QIcon(os.path.join(config_dir, 'cc_icons', filename)) icon = QIcon(os.path.join(config_dir, 'cc_icons', filename))
item.setIcon(icon) item.setIcon(icon)
model.appendRow(item) model.appendRow(item)
@ -448,7 +446,7 @@ class RuleEditor(QDialog): # {{{
pal = QApplication.palette() pal = QApplication.palette()
bg1 = unicode(pal.color(pal.Base).name()) bg1 = unicode(pal.color(pal.Base).name())
bg2 = unicode(pal.color(pal.AlternateBase).name()) bg2 = unicode(pal.color(pal.AlternateBase).name())
c = unicode(self.color_box.currentText()) c = self.color_box.color
self.color_label.setText(''' self.color_label.setText('''
<span style="color: {c}; background-color: {bg1}">&nbsp;{st}&nbsp;</span> <span style="color: {c}; background-color: {bg1}">&nbsp;{st}&nbsp;</span>
<span style="color: {c}; background-color: {bg2}">&nbsp;{st}&nbsp;</span> <span style="color: {c}; background-color: {bg2}">&nbsp;{st}&nbsp;</span>
@ -528,9 +526,7 @@ class RuleEditor(QDialog): # {{{
def apply_rule(self, kind, col, rule): def apply_rule(self, kind, col, rule):
if kind == 'color': if kind == 'color':
if rule.color: if rule.color:
idx = self.color_box.findText(rule.color) self.color_box.color = rule.color
if idx >= 0:
self.color_box.setCurrentIndex(idx)
else: else:
for i,tup in enumerate(icon_rule_kinds): for i,tup in enumerate(icon_rule_kinds):
if kind == tup[1]: if kind == tup[1]:
@ -595,7 +591,7 @@ class RuleEditor(QDialog): # {{{
if self.rule_kind != 'color': if self.rule_kind != 'color':
r.color = self.get_filenames_from_box() r.color = self.get_filenames_from_box()
else: else:
r.color = unicode(self.color_box.currentText()) r.color = self.color_box.color
idx = self.column_box.currentIndex() idx = self.column_box.currentIndex()
col = unicode(self.column_box.itemData(idx).toString()) col = unicode(self.column_box.itemData(idx).toString())
for c in self.conditions: for c in self.conditions:
@ -623,7 +619,8 @@ class RulesModel(QAbstractListModel): # {{{
rules = list(prefs[pref_name]) rules = list(prefs[pref_name])
self.rules = [] self.rules = []
for col, template in rules: for col, template in rules:
if col not in self.fm and col != color_row_key: continue if col not in self.fm and col != color_row_key:
continue
try: try:
rule = rule_from_template(self.fm, template) rule = rule_from_template(self.fm, template)
except: except:
@ -634,7 +631,8 @@ class RulesModel(QAbstractListModel): # {{{
rules = list(prefs[pref_name]) rules = list(prefs[pref_name])
self.rules = [] self.rules = []
for kind, col, template in rules: for kind, col, template in rules:
if col not in self.fm and col != color_row_key: continue if col not in self.fm and col != color_row_key:
continue
try: try:
rule = rule_from_template(self.fm, template) rule = rule_from_template(self.fm, template)
except: except:
@ -945,7 +943,7 @@ if __name__ == '__main__':
d.add_blank_condition() d.add_blank_condition()
d.exec_() d.exec_()
col, r = d.rule kind, col, r = d.rule
print ('Column to be colored:', col) print ('Column to be colored:', col)
print ('Template:') print ('Template:')

View File

@ -84,10 +84,15 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
for t in self.column_types: for t in self.column_types:
self.column_type_box.addItem(self.column_types[t]['text']) self.column_type_box.addItem(self.column_types[t]['text'])
self.column_type_box.currentIndexChanged.connect(self.datatype_changed) self.column_type_box.currentIndexChanged.connect(self.datatype_changed)
all_colors = [unicode(s) for s in list(QColor.colorNames())]
self.enum_colors_label.setToolTip('<p>' + ', '.join(all_colors) + '</p>')
if not self.editing_col: if not self.editing_col:
self.datatype_changed() self.datatype_changed()
self.exec_() self.exec_()
return return
self.setWindowTitle(_('Edit a custom column')) self.setWindowTitle(_('Edit a custom column'))
self.heading_label.setText(_('Edit a custom column')) self.heading_label.setText(_('Edit a custom column'))
self.shortcuts.setVisible(False) self.shortcuts.setVisible(False)
@ -141,9 +146,6 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
elif ct == '*text': elif ct == '*text':
self.is_names.setChecked(c['display'].get('is_names', False)) self.is_names.setChecked(c['display'].get('is_names', False))
all_colors = [unicode(s) for s in list(QColor.colorNames())]
self.enum_colors_label.setToolTip('<p>' + ', '.join(all_colors) + '</p>')
self.composite_contains_html.setToolTip('<p>' + self.composite_contains_html.setToolTip('<p>' +
_('If checked, this column will be displayed as HTML in ' _('If checked, this column will be displayed as HTML in '
'book details and the content server. This can be used to ' 'book details and the content server. This can be used to '
@ -295,7 +297,7 @@ class CreateCustomColumn(QDialog, Ui_QCreateCustomColumn):
return self.simple_error('', _('The colors box must be empty or ' return self.simple_error('', _('The colors box must be empty or '
'contain the same number of items as the value box')) 'contain the same number of items as the value box'))
for tc in c: for tc in c:
if tc not in QColor.colorNames(): if tc not in QColor.colorNames() and not re.match("#(?:[0-9a-f]{3}){1,4}",tc,re.I):
return self.simple_error('', return self.simple_error('',
_('The color {0} is unknown').format(tc)) _('The color {0} is unknown').format(tc))

View File

@ -6,6 +6,8 @@ from __future__ import (unicode_literals, division, absolute_import,
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>' __copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
from PyQt4.Qt import QPushButton, QPixmap, QIcon, QColor, Qt, QColorDialog, pyqtSignal
from calibre.gui2.complete2 import LineEdit from calibre.gui2.complete2 import LineEdit
from calibre.gui2.widgets import history from calibre.gui2.widgets import history
@ -46,3 +48,41 @@ class HistoryLineEdit2(LineEdit):
history.set(self.store_name, self.history) history.set(self.store_name, self.history)
self.update_items_cache(self.history) self.update_items_cache(self.history)
class ColorButton(QPushButton):
color_changed = pyqtSignal(object)
def __init__(self, initial_color=None, parent=None, choose_text=None):
QPushButton.__init__(self, parent)
self._color = None
self.choose_text = choose_text or _('Choose &color')
self.color = initial_color
self.clicked.connect(self.choose_color)
@dynamic_property
def color(self):
def fget(self):
return self._color
def fset(self, val):
val = unicode(val or '')
col = QColor(val)
orig = self._color
if col.isValid():
self._color = val
self.setText(val)
p = QPixmap(self.iconSize())
p.fill(col)
self.setIcon(QIcon(p))
else:
self._color = None
self.setText(self.choose_text)
self.setIcon(QIcon())
if orig != col:
self.color_changed.emit(self._color)
return property(fget=fget, fset=fset)
def choose_color(self):
col = QColorDialog.getColor(QColor(self._color or Qt.white), self, _('Choose a color'))
if col.isValid():
self.color = unicode(col.name())

View File

@ -1211,6 +1211,10 @@ def command_check_library(args, dbpath):
for i in list: for i in list:
print ' %-40.40s - %-40.40s'%(i[0], i[1]) print ' %-40.40s - %-40.40s'%(i[0], i[1])
if not LibraryDatabase.exists_at(dbpath):
prints('No library found at', dbpath, file=sys.stderr)
raise SystemExit(1)
db = LibraryDatabase(dbpath) db = LibraryDatabase(dbpath)
checker = CheckLibrary(dbpath, db) checker = CheckLibrary(dbpath, db)
checker.scan_library(names, exts) checker.scan_library(names, exts)