Merge from trunk

This commit is contained in:
Charles Haley 2010-12-31 19:44:12 +00:00
commit 04cf235146
11 changed files with 1624 additions and 589 deletions

View File

@ -2,19 +2,29 @@ body { background-color: white; }
p.title {
margin-top:0em;
margin-bottom:1em;
margin-bottom:0em;
text-align:center;
font-style:italic;
font-size:xx-large;
border-bottom: solid black 2px;
}
p.series_id {
margin-top:0em;
margin-bottom:0em;
text-align:center;
}
a.series_id {
font-style:normal;
font-size:large;
}
p.author {
font-size:large;
margin-top:0em;
margin-bottom:0em;
text-align: center;
text-indent: 0em;
font-size:large;
}
p.author_index {
@ -26,7 +36,8 @@ p.author_index {
text-indent: 0em;
}
p.tags {
p.genres {
font-style:normal;
margin-top:0.5em;
margin-bottom:0em;
text-align: left;
@ -108,6 +119,13 @@ p.date_read {
text-indent:-6em;
}
hr.annotations_divider {
width:50%;
margin-left:1em;
margin-top:0em;
margin-bottom:0em;
}
hr.description_divider {
width:90%;
margin-left:5%;
@ -117,20 +135,37 @@ hr.description_divider {
border-left: solid white 0px;
}
hr.annotations_divider {
width:50%;
margin-left:1em;
margin-top:0em;
margin-bottom:0em;
hr.header_divider {
width:100%;
border-top: solid white 1px;
border-right: solid white 0px;
border-bottom: solid black 2px;
border-left: solid white 0px;
}
hr.merged_comments_divider {
width:80%;
margin-left:10%;
border-top: solid white 0px;
border-right: solid white 0px;
border-bottom: dashed gray 2px;
border-left: solid white 0px;
}
td.publisher, td.date {
font-weight:bold;
text-align:center;
}
td.rating {
text-align: center;
td.rating{
text-align:center;
}
td.notes {
font-size: 100%;
text-align:center;
}
td.thumbnail img {
-webkit-box-shadow: 4px 4px 12px #999;
}

View File

@ -0,0 +1,41 @@
<html xmlns="{xmlns}">
<head>
<title>{title_str}</title>
<meta name="catalog description header" http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="stylesheet.css" media="screen" />
</head>
<body>
<p class="title">{title}</p>
<p class="series_id"><a class="series_id">{series} [{series_index}]</a></p>
<hr class="header_divider" />
<p class="author">{author_prefix}<a class="author">{author}</a></p>
<p class="genres">{genres}</p>
<p class="formats">{formats}</p>
<table width="100%" border="0">
<tr>
<td class="thumbnail" rowspan="7"></td>
<td>&#160;</td>
</tr>
<tr>
<td>&#160;</td>
</tr>
<tr>
<td class="publisher">{publisher}</td>
</tr>
<tr>
<td class="date">{pubyear}</td>
</tr>
<tr>
<td class="rating">{rating}</td>
</tr>
<tr>
<td class="notes">{note_source}: {note_content}</td>
</tr>
<tr>
<td>&#160;</td>
</tr>
</table>
<hr class="description_divider" />
<div class="description"></div>
</body>
</html>

View File

@ -307,6 +307,14 @@ class CatalogPlugin(Plugin): # {{{
#: cli_options parsed in library.cli:catalog_option_parser()
cli_options = []
def _field_sorter(self, key):
'''
Custom fields sort after standard fields
'''
if key.startswith('#'):
return '~%s' % key[1:]
else:
return key
def search_sort_db(self, db, opts):
@ -315,18 +323,18 @@ class CatalogPlugin(Plugin): # {{{
if opts.sort_by:
# 2nd arg = ascending
db.sort(opts.sort_by, True)
return db.get_data_as_dict(ids=opts.ids)
def get_output_fields(self, opts):
def get_output_fields(self, db, opts):
# Return a list of requested fields, with opts.sort_by first
all_fields = set(
all_std_fields = set(
['author_sort','authors','comments','cover','formats',
'id','isbn','ondevice','pubdate','publisher','rating',
'series_index','series','size','tags','timestamp',
'title','uuid'])
all_custom_fields = set(db.custom_field_keys())
all_fields = all_std_fields.union(all_custom_fields)
fields = all_fields
if opts.fields != 'all':
# Make a list from opts.fields
requested_fields = set(opts.fields.split(','))
@ -337,7 +345,7 @@ class CatalogPlugin(Plugin): # {{{
if not opts.connected_device['is_device_connected'] and 'ondevice' in fields:
fields.pop(int(fields.index('ondevice')))
fields.sort()
fields = sorted(fields, key=self._field_sorter)
if opts.sort_by and opts.sort_by in fields:
fields.insert(0,fields.pop(int(fields.index(opts.sort_by))))
return fields

View File

@ -624,6 +624,8 @@ class KindleDXOutput(OutputProfile):
#comic_screen_size = (741, 1022)
supports_mobi_indexing = True
periodical_date_in_title = False
missing_char = u'x\u2009'
empty_ratings_char = u'\u2606'
ratings_char = u'\u2605'
read_char = u'\u2713'
mobi_ems_per_blockquote = 2.0

View File

@ -57,7 +57,7 @@ class GenerateCatalogAction(InterfaceAction):
if job.result:
# Search terms nulled catalog results
return error_dialog(self.gui, _('No books found'),
_("No books to catalog\nCheck exclude tags"),
_("No books to catalog\nCheck exclusion criteria"),
show=True)
if job.failed:
return self.gui.job_exception(job)

View File

@ -6,9 +6,9 @@ __license__ = 'GPL v3'
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
from calibre.gui2 import gprefs
from calibre.gui2.catalog.catalog_csv_xml_ui import Ui_Form
from calibre.library import db as db_
from PyQt4.Qt import QWidget, QListWidgetItem
class PluginWidget(QWidget, Ui_Form):
@ -28,6 +28,12 @@ class PluginWidget(QWidget, Ui_Form):
self.all_fields.append(x)
QListWidgetItem(x, self.db_fields)
db = db_()
for x in sorted(db.custom_field_keys()):
self.all_fields.append(x)
QListWidgetItem(x, self.db_fields)
def initialize(self, name, db):
self.name = name
fields = gprefs.get(name+'_db_fields', self.all_fields)

View File

@ -17,18 +17,55 @@ class PluginWidget(QWidget,Ui_Form):
TITLE = _('E-book options')
HELP = _('Options specific to')+' EPUB/MOBI '+_('output')
OPTION_FIELDS = [('exclude_genre','\[.+\]'),
('exclude_tags','~,'+_('Catalog')),
('generate_titles', True),
('generate_series', True),
('generate_recently_added', True),
('note_tag','*'),
('numbers_as_text', False),
('read_pattern','+'),
('read_source_field_cb','Tag'),
('wishlist_tag','Wishlist'),
]
CheckBoxControls = [
'generate_titles',
'generate_series',
'generate_genres',
'generate_recently_added',
'generate_descriptions',
'include_hr'
]
ComboBoxControls = [
'read_source_field',
'exclude_source_field',
'header_note_source_field',
'merge_source_field'
]
LineEditControls = [
'exclude_genre',
'exclude_pattern',
'exclude_tags',
'read_pattern',
'wishlist_tag'
]
RadioButtonControls = [
'merge_before',
'merge_after'
]
SpinBoxControls = [
'thumb_width'
]
OPTION_FIELDS = zip(CheckBoxControls,
[True for i in CheckBoxControls],
['check_box' for i in CheckBoxControls])
OPTION_FIELDS += zip(ComboBoxControls,
[None for i in ComboBoxControls],
['combo_box' for i in ComboBoxControls])
OPTION_FIELDS += zip(RadioButtonControls,
[None for i in RadioButtonControls],
['radio_button' for i in RadioButtonControls])
# LineEditControls
OPTION_FIELDS += zip(['exclude_genre'],['\[.+\]'],['line_edit'])
OPTION_FIELDS += zip(['exclude_pattern'],[None],['line_edit'])
OPTION_FIELDS += zip(['exclude_tags'],['~,'+_('Catalog')],['line_edit'])
OPTION_FIELDS += zip(['read_pattern'],['+'],['line_edit'])
OPTION_FIELDS += zip(['wishlist_tag'],['Wishlist'],['line_edit'])
# SpinBoxControls
OPTION_FIELDS += zip(['thumb_width'],[1.00],['spin_box'])
# Output synced to the connected device?
sync_enabled = True
@ -42,105 +79,203 @@ class PluginWidget(QWidget,Ui_Form):
def initialize(self, name, db):
self.name = name
# Populate the 'Read book' source fields
all_custom_fields = db.custom_field_keys()
custom_fields = {}
custom_fields['Tag'] = {'field':'tag', 'datatype':u'text'}
for custom_field in all_custom_fields:
field_md = db.metadata_for_field(custom_field)
if field_md['datatype'] in ['bool','composite','datetime','text']:
custom_fields[field_md['name']] = {'field':custom_field,
'datatype':field_md['datatype']}
# Add the sorted eligible fields to the combo box
for cf in sorted(custom_fields):
self.read_source_field_cb.addItem(cf)
self.read_source_fields = custom_fields
self.read_source_field_cb.currentIndexChanged.connect(self.read_source_field_changed)
self.db = db
self.populateComboBoxes()
# Update dialog fields from stored options
for opt in self.OPTION_FIELDS:
opt_value = gprefs.get(self.name + '_' + opt[0], opt[1])
if opt[0] in [
'generate_recently_added',
'generate_series',
'generate_titles',
'numbers_as_text',
]:
getattr(self, opt[0]).setChecked(opt_value)
c_name, c_def, c_type = opt
opt_value = gprefs.get(self.name + '_' + c_name, c_def)
if c_type in ['check_box']:
getattr(self, c_name).setChecked(eval(str(opt_value)))
elif c_type in ['combo_box'] and opt_value is not None:
# *** Test this code with combo boxes ***
#index = self.read_source_field.findText(opt_value)
index = getattr(self,c_name).findText(opt_value)
if index == -1 and c_name == 'read_source_field':
index = self.read_source_field.findText('Tag')
#self.read_source_field.setCurrentIndex(index)
getattr(self,c_name).setCurrentIndex(index)
elif c_type in ['line_edit']:
getattr(self, c_name).setText(opt_value if opt_value else '')
elif c_type in ['radio_button'] and opt_value is not None:
getattr(self, c_name).setChecked(opt_value)
elif c_type in ['spin_box']:
getattr(self, c_name).setValue(float(opt_value))
# Combo box
elif opt[0] in ['read_source_field_cb']:
# Look for last-stored combo box value
index = self.read_source_field_cb.findText(opt_value)
if index == -1:
index = self.read_source_field_cb.findText('Tag')
self.read_source_field_cb.setCurrentIndex(index)
# Text fields
else:
getattr(self, opt[0]).setText(opt_value)
# Init self.read_source_field
cs = unicode(self.read_source_field_cb.currentText())
# Init self.read_source_field_name
cs = unicode(self.read_source_field.currentText())
read_source_spec = self.read_source_fields[cs]
self.read_source_field = read_source_spec['field']
self.read_source_field_name = read_source_spec['field']
# Init self.exclude_source_field_name
self.exclude_source_field_name = ''
cs = unicode(self.exclude_source_field.currentText())
if cs > '':
exclude_source_spec = self.exclude_source_fields[cs]
self.exclude_source_field_name = exclude_source_spec['field']
# Init self.merge_source_field_name
self.merge_source_field_name = ''
cs = unicode(self.merge_source_field.currentText())
if cs > '':
merge_source_spec = self.merge_source_fields[cs]
self.merge_source_field_name = merge_source_spec['field']
# Init self.header_note_source_field_name
self.header_note_source_field_name = ''
cs = unicode(self.header_note_source_field.currentText())
if cs > '':
header_note_source_spec = self.header_note_source_fields[cs]
self.header_note_source_field_name = header_note_source_spec['field']
# Hook changes to thumb_width
self.thumb_width.valueChanged.connect(self.thumb_width_changed)
def options(self):
# Save/return the current options
# exclude_genre stores literally
# generate_titles, generate_recently_added, numbers_as_text stores as True/False
# others store as lists
opts_dict = {}
# Save values to gprefs
for opt in self.OPTION_FIELDS:
# Save values to gprefs
if opt[0] in [
'generate_recently_added',
'generate_series',
'generate_titles',
'numbers_as_text',
]:
opt_value = getattr(self,opt[0]).isChecked()
c_name, c_def, c_type = opt
if c_type in ['check_box', 'radio_button']:
opt_value = getattr(self, c_name).isChecked()
elif c_type in ['combo_box']:
opt_value = unicode(getattr(self,c_name).currentText()).strip()
elif c_type in ['line_edit']:
opt_value = unicode(getattr(self, c_name).text()).strip()
elif c_type in ['spin_box']:
opt_value = unicode(getattr(self, c_name).value())
gprefs.set(self.name + '_' + c_name, opt_value)
# Combo box uses .currentText()
elif opt[0] in ['read_source_field_cb']:
opt_value = unicode(getattr(self, opt[0]).currentText())
# text fields use .text()
# Construct opts object
if c_name == 'exclude_tags':
# store as list
opts_dict[c_name] = opt_value.split(',')
else:
opt_value = unicode(getattr(self, opt[0]).text())
gprefs.set(self.name + '_' + opt[0], opt_value)
opts_dict[c_name] = opt_value
# Construct opts
if opt[0] in [
'exclude_genre',
'generate_recently_added',
'generate_series',
'generate_titles',
'numbers_as_text',
]:
opts_dict[opt[0]] = opt_value
else:
opts_dict[opt[0]] = opt_value.split(',')
# Generate markers for hybrids
opts_dict['read_book_marker'] = "%s:%s" % (self.read_source_field_name,
self.read_pattern.text())
opts_dict['exclude_book_marker'] = "%s:%s" % (self.exclude_source_field_name,
self.exclude_pattern.text())
# Generate read_book_marker
opts_dict['read_book_marker'] = "%s:%s" % (self.read_source_field, self.read_pattern.text())
# Generate specs for merge_comments, header_note_source_field
checked = ''
if self.merge_before.isChecked():
checked = 'before'
elif self.merge_after.isChecked():
checked = 'after'
include_hr = self.include_hr.isChecked()
opts_dict['merge_comments'] = "%s:%s:%s" % \
(self.merge_source_field_name, checked, include_hr)
opts_dict['header_note_source_field'] = self.header_note_source_field_name
# Append the output profile
opts_dict['output_profile'] = [load_defaults('page_setup')['output_profile']]
if False:
print "opts_dict"
for opt in sorted(opts_dict.keys()):
print " %s: %s" % (opt, repr(opts_dict[opt]))
return opts_dict
def populateComboBoxes(self):
# Custom column types declared in
# gui2.preferences.create_custom_column:CreateCustomColumn()
# As of 0.7.34:
# bool Yes/No
# comments Long text, like comments, not shown in tag browser
# composite Column built from other columns
# datetime Date
# enumeration Text, but with a fixed set of permitted values
# float Floating point numbers
# int Integers
# rating Ratings, shown with stars
# series Text column for keeping series-like information
# text Column shown in the tag browser
# *text Comma-separated text, like tags, shown in tag browser
all_custom_fields = self.db.custom_field_keys()
# Populate the 'Read book' hybrid
custom_fields = {}
custom_fields['Tag'] = {'field':'tag', 'datatype':u'text'}
for custom_field in all_custom_fields:
field_md = self.db.metadata_for_field(custom_field)
if field_md['datatype'] in ['bool','composite','datetime','enumeration','text']:
custom_fields[field_md['name']] = {'field':custom_field,
'datatype':field_md['datatype']}
# Add the sorted eligible fields to the combo box
for cf in sorted(custom_fields):
self.read_source_field.addItem(cf)
self.read_source_fields = custom_fields
self.read_source_field.currentIndexChanged.connect(self.read_source_field_changed)
# Populate the 'Excluded books' hybrid
custom_fields = {}
for custom_field in all_custom_fields:
field_md = self.db.metadata_for_field(custom_field)
if field_md['datatype'] in ['bool','composite','datetime','enumeration','text']:
custom_fields[field_md['name']] = {'field':custom_field,
'datatype':field_md['datatype']}
# Blank field first
self.exclude_source_field.addItem('')
# Add the sorted eligible fields to the combo box
for cf in sorted(custom_fields):
self.exclude_source_field.addItem(cf)
self.exclude_source_fields = custom_fields
self.exclude_source_field.currentIndexChanged.connect(self.exclude_source_field_changed)
# Populate the 'Header note' combo box
custom_fields = {}
for custom_field in all_custom_fields:
field_md = self.db.metadata_for_field(custom_field)
if field_md['datatype'] in ['bool','composite','datetime','enumeration','text']:
custom_fields[field_md['name']] = {'field':custom_field,
'datatype':field_md['datatype']}
# Blank field first
self.header_note_source_field.addItem('')
# Add the sorted eligible fields to the combo box
for cf in sorted(custom_fields):
self.header_note_source_field.addItem(cf)
self.header_note_source_fields = custom_fields
self.header_note_source_field.currentIndexChanged.connect(self.header_note_source_field_changed)
# Populate the 'Merge with Comments' combo box
custom_fields = {}
for custom_field in all_custom_fields:
field_md = self.db.metadata_for_field(custom_field)
if field_md['datatype'] in ['text','comments']:
custom_fields[field_md['name']] = {'field':custom_field,
'datatype':field_md['datatype']}
# Blank field first
self.merge_source_field.addItem('')
# Add the sorted eligible fields to the combo box
for cf in sorted(custom_fields):
self.merge_source_field.addItem(cf)
self.merge_source_fields = custom_fields
self.merge_source_field.currentIndexChanged.connect(self.merge_source_field_changed)
self.merge_before.setEnabled(False)
self.merge_after.setEnabled(False)
self.include_hr.setEnabled(False)
def read_source_field_changed(self,new_index):
'''
Process changes in the read_source_field combo box
Currently using QLineEdit for all field types
Possible to modify to switch QWidget type
'''
new_source = str(self.read_source_field_cb.currentText())
new_source = str(self.read_source_field.currentText())
read_source_spec = self.read_source_fields[str(new_source)]
self.read_source_field = read_source_spec['field']
self.read_source_field_name = read_source_spec['field']
# Change pattern input widget to match the source field datatype
if read_source_spec['datatype'] in ['bool','composite','datetime','text']:
@ -152,3 +287,63 @@ class PluginWidget(QWidget,Ui_Form):
self.read_pattern = dw
self.read_spec_hl.addWidget(dw)
def exclude_source_field_changed(self,new_index):
'''
Process changes in the exclude_source_field combo box
Currently using QLineEdit for all field types
Possible to modify to switch QWidget type
'''
new_source = str(self.exclude_source_field.currentText())
self.exclude_source_field_name = new_source
if new_source > '':
exclude_source_spec = self.exclude_source_fields[str(new_source)]
self.exclude_source_field_name = exclude_source_spec['field']
self.exclude_pattern.setEnabled(True)
# Change pattern input widget to match the source field datatype
if exclude_source_spec['datatype'] in ['bool','composite','datetime','text']:
if not isinstance(self.exclude_pattern, QLineEdit):
self.exclude_spec_hl.removeWidget(self.exclude_pattern)
dw = QLineEdit(self)
dw.setObjectName('exclude_pattern')
dw.setToolTip('Exclusion pattern')
self.exclude_pattern = dw
self.exclude_spec_hl.addWidget(dw)
else:
self.exclude_pattern.setEnabled(False)
def header_note_source_field_changed(self,new_index):
'''
Process changes in the header_note_source_field combo box
'''
new_source = str(self.header_note_source_field.currentText())
self.header_note_source_field_name = new_source
if new_source > '':
header_note_source_spec = self.header_note_source_fields[str(new_source)]
self.header_note_source_field_name = header_note_source_spec['field']
def merge_source_field_changed(self,new_index):
'''
Process changes in the header_note_source_field combo box
'''
new_source = str(self.merge_source_field.currentText())
self.merge_source_field_name = new_source
if new_source > '':
merge_source_spec = self.merge_source_fields[str(new_source)]
self.merge_source_field_name = merge_source_spec['field']
if not self.merge_before.isChecked() and not self.merge_after.isChecked():
self.merge_after.setChecked(True)
self.merge_before.setEnabled(True)
self.merge_after.setEnabled(True)
self.include_hr.setEnabled(True)
else:
self.merge_before.setEnabled(False)
self.merge_after.setEnabled(False)
self.include_hr.setEnabled(False)
def thumb_width_changed(self,new_value):
'''
Process changes in the thumb_width spin box
'''
pass

View File

@ -6,163 +6,681 @@
<rect>
<x>0</x>
<y>0</y>
<width>627</width>
<height>549</height>
<width>650</width>
<height>582</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>'Don't include this book' tag:</string>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="includedSections">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="exclude_tags">
<property name="toolTip">
<string extracomment="Default: ~,Catalog"/>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Additional note tag prefix:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="note_tag">
<property name="toolTip">
<string extracomment="Default: *"/>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLineEdit" name="exclude_genre">
<property name="toolTip">
<string extracomment="Default: \[[\w]*\]"/>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Regex pattern describing tags to exclude as genres:</string>
</property>
<property name="textFormat">
<enum>Qt::LogText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Regex tips:
- The default regex - \[.+\] - excludes genre tags of the form [tag], e.g., [Amazon Freebie]
- A regex pattern of a single dot excludes all genre tags, generating no Genre Section</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<property name="minimumSize">
<size>
<width>20</width>
<height>40</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="10" column="0">
<widget class="QCheckBox" name="generate_titles">
<property name="text">
<string>Include 'Titles' Section</string>
<property name="toolTip">
<string>Sections to include in catalog. All catalogs include 'Books by Author'.</string>
</property>
<property name="title">
<string>Included sections</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="generate_titles">
<property name="text">
<string>Books by &amp;Title</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="generate_series">
<property name="text">
<string>Books by &amp;Series</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="generate_recently_added">
<property name="text">
<string>Recently &amp;Added</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QCheckBox" name="generate_genres">
<property name="text">
<string>Books by &amp;Genre</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QCheckBox" name="generate_descriptions">
<property name="text">
<string>&amp;Descriptions</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="12" column="0">
<widget class="QCheckBox" name="generate_recently_added">
<property name="text">
<string>Include 'Recently Added' Section</string>
<item>
<widget class="QGroupBox" name="excludedGenres">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Default pattern &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt;\[.+\]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;excludes tags of the form [&lt;span style=&quot; font-family:'Courier New,courier';&quot;&gt;tag&lt;/span&gt;], &lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;e.g., [Project Gutenberg]&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="title">
<string>Excluded genres</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::FieldsStayAtSizeHint</enum>
</property>
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>-1</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
<width>175</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Tags to &amp;exclude</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>exclude_genre</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="exclude_genre">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string extracomment="Default: \[[\w]*\]"/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="13" column="0">
<widget class="QCheckBox" name="numbers_as_text">
<property name="text">
<string>Sort numbers as text</string>
<item>
<widget class="QGroupBox" name="excludedBooks">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Books matching either pattern will not be included in generated catalog. </string>
</property>
<property name="title">
<string>Excluded books</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>175</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Tags to &amp;exclude</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>exclude_tags</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="exclude_tags">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Comma-separated list of tags to exclude.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt;&quot;&gt;Default:&lt;/span&gt;&lt;span style=&quot; font-family:'Courier New,courier'; font-size:12pt;&quot;&gt; ~,Catalog&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="exclude_spec_hl">
<item>
<widget class="QLabel" name="label_7">
<property name="minimumSize">
<size>
<width>175</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>&amp;Column/value</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>exclude_source_field</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="exclude_source_field">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Column containing additional exclusion criteria</string>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
<property name="minimumContentsLength">
<number>18</number>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="exclude_pattern">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Exclusion pattern</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="11" column="0">
<widget class="QCheckBox" name="generate_series">
<property name="text">
<string>Include 'Series' Section</string>
<item>
<widget class="QGroupBox" name="readBooks">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Matching books will be displayed with ✓</string>
</property>
<property name="title">
<string>Read books</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="read_spec_hl">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QLabel" name="label_3">
<property name="minimumSize">
<size>
<width>175</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>&amp;Column/value</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>read_source_field</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="read_source_field">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Column containing 'read' status</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
</property>
<property name="minimumContentsLength">
<number>18</number>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="read_pattern">
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>'read book' pattern</string>
</property>
<property name="statusTip">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="wishlist_tag"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Wishlist tag:</string>
<item>
<widget class="QGroupBox" name="otherOptions">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="read_spec_hl">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<item>
<widget class="QComboBox" name="read_source_field_cb">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Source column for read book</string>
</property>
<property name="statusTip">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="read_pattern">
<property name="toolTip">
<string>Pattern for read book</string>
</property>
<property name="statusTip">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Books marked as read:</string>
<property name="title">
<string>Other options</string>
</property>
<layout class="QFormLayout" name="formLayout_4">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::FieldsStayAtSizeHint</enum>
</property>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_5">
<property name="minimumSize">
<size>
<width>175</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>&amp;Wishlist tag</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>wishlist_tag</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="wishlist_tag">
<property name="toolTip">
<string>Books tagged as Wishlist items will be displayed with ✕</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="minimumSize">
<size>
<width>175</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>&amp;Thumbnail width</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="buddy">
<cstring>thumb_width</cstring>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="thumb_width">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Size hint for Description cover thumbnails</string>
</property>
<property name="suffix">
<string> inch</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>2.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>175</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>&amp;Description note</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>header_note_source_field</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="header_note_source_field">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Custom column source for note to include in Description header area</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLabel" name="label_9">
<property name="minimumSize">
<size>
<width>175</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>&amp;Merge with Comments</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>merge_source_field</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="merge_source_field">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Additional content merged with Comments during catalog generation</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="merge_before">
<property name="toolTip">
<string>Merge additional content before Comments</string>
</property>
<property name="text">
<string>&amp;Before</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="merge_after">
<property name="toolTip">
<string>Merge additional content after Comments</string>
</property>
<property name="text">
<string>&amp;After</string>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="include_hr">
<property name="toolTip">
<string>Separate Comments and additional content with horizontal rule</string>
</property>
<property name="text">
<string>&amp;Separator</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>579</width>
<height>411</height>
<width>650</width>
<height>575</height>
</rect>
</property>
<property name="windowTitle">

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>611</width>
<height>514</height>
<width>674</width>
<height>660</height>
</rect>
</property>
<property name="windowTitle">
@ -33,6 +33,18 @@
</item>
<item row="1" column="0" colspan="2">
<widget class="QTabWidget" name="tabs">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>650</width>
<height>575</height>
</size>
</property>
<property name="currentIndex">
<number>0</number>
</property>

File diff suppressed because it is too large Load Diff