mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Removed table selection when lost focus, added reset button to exclude_genres
This commit is contained in:
parent
24aab4fb57
commit
e40bd0164d
@ -18,7 +18,7 @@ from PyQt4.Qt import (Qt, QAbstractItemView, QCheckBox, QComboBox, QDialog,
|
|||||||
QDialogButtonBox, QDoubleSpinBox,
|
QDialogButtonBox, QDoubleSpinBox,
|
||||||
QHBoxLayout, QIcon, QLabel, QLineEdit,
|
QHBoxLayout, QIcon, QLabel, QLineEdit,
|
||||||
QPlainTextEdit, QRadioButton, QSize, QSizePolicy,
|
QPlainTextEdit, QRadioButton, QSize, QSizePolicy,
|
||||||
QTableWidget, QTableWidgetItem,
|
QTableWidget, QTableWidgetItem, QTimer,
|
||||||
QToolButton, QVBoxLayout, QWidget)
|
QToolButton, QVBoxLayout, QWidget)
|
||||||
|
|
||||||
class PluginWidget(QWidget,Ui_Form):
|
class PluginWidget(QWidget,Ui_Form):
|
||||||
@ -72,8 +72,6 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
|
|
||||||
# LineEditControls
|
# LineEditControls
|
||||||
option_fields += zip(['exclude_genre'],['\[.+\]|\+'],['line_edit'])
|
option_fields += zip(['exclude_genre'],['\[.+\]|\+'],['line_edit'])
|
||||||
#***option_fields += zip(['exclude_pattern'],[None],['line_edit'])
|
|
||||||
#***option_fields += zip(['exclude_tags'],['~,'+_('Catalog')],['line_edit'])
|
|
||||||
|
|
||||||
# SpinBoxControls
|
# SpinBoxControls
|
||||||
option_fields += zip(['thumb_width'],[1.00],['spin_box'])
|
option_fields += zip(['thumb_width'],[1.00],['spin_box'])
|
||||||
@ -84,12 +82,7 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
'enabled':True,
|
'enabled':True,
|
||||||
'name':'Catalogs',
|
'name':'Catalogs',
|
||||||
'field':'Tags',
|
'field':'Tags',
|
||||||
'pattern':'Catalog'},
|
'pattern':'Catalog'},],
|
||||||
{'ordinal':1,
|
|
||||||
'enabled':False,
|
|
||||||
'name':'New rule',
|
|
||||||
'field':'',
|
|
||||||
'pattern':''}],
|
|
||||||
['table_widget','table_widget'])
|
['table_widget','table_widget'])
|
||||||
|
|
||||||
# Prefix rules
|
# Prefix rules
|
||||||
@ -105,13 +98,7 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
'name':'Wishlist item',
|
'name':'Wishlist item',
|
||||||
'field':'Tags',
|
'field':'Tags',
|
||||||
'pattern':'Wishlist',
|
'pattern':'Wishlist',
|
||||||
'prefix':u'\u00d7'},
|
'prefix':u'\u00d7'},],
|
||||||
{'ordinal':2,
|
|
||||||
'enabled':False,
|
|
||||||
'name':'New rule',
|
|
||||||
'field':'',
|
|
||||||
'pattern':'',
|
|
||||||
'prefix':''}],
|
|
||||||
['table_widget','table_widget','table_widget'])
|
['table_widget','table_widget','table_widget'])
|
||||||
|
|
||||||
self.OPTION_FIELDS = option_fields
|
self.OPTION_FIELDS = option_fields
|
||||||
@ -181,15 +168,9 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
if opt_value not in prefix_rules:
|
if opt_value not in prefix_rules:
|
||||||
prefix_rules.append(opt_value)
|
prefix_rules.append(opt_value)
|
||||||
|
|
||||||
'''
|
# Add icon to the reset button
|
||||||
***
|
self.reset_exclude_genres_tb.setIcon(QIcon(I('trash.png')))
|
||||||
# Init self.exclude_source_field_name
|
self.reset_exclude_genres_tb.clicked.connect(self.reset_exclude_genres)
|
||||||
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
|
# Init self.merge_source_field_name
|
||||||
self.merge_source_field_name = ''
|
self.merge_source_field_name = ''
|
||||||
@ -205,12 +186,6 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
header_note_source_spec = self.header_note_source_fields[cs]
|
header_note_source_spec = self.header_note_source_fields[cs]
|
||||||
self.header_note_source_field_name = header_note_source_spec['field']
|
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)
|
|
||||||
|
|
||||||
# Hook changes to Description section
|
|
||||||
self.generate_descriptions.stateChanged.connect(self.generate_descriptions_changed)
|
|
||||||
|
|
||||||
# Initialize exclusion rules
|
# Initialize exclusion rules
|
||||||
self.exclusion_rules_table = ExclusionRules(self.exclusion_rules_gb_hl,
|
self.exclusion_rules_table = ExclusionRules(self.exclusion_rules_gb_hl,
|
||||||
"exclusion_rules_tw",exclusion_rules, self.eligible_custom_fields,self.db)
|
"exclusion_rules_tw",exclusion_rules, self.eligible_custom_fields,self.db)
|
||||||
@ -219,6 +194,13 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
self.prefix_rules_table = PrefixRules(self.prefix_rules_gb_hl,
|
self.prefix_rules_table = PrefixRules(self.prefix_rules_gb_hl,
|
||||||
"prefix_rules_tw",prefix_rules, self.eligible_custom_fields,self.db)
|
"prefix_rules_tw",prefix_rules, self.eligible_custom_fields,self.db)
|
||||||
|
|
||||||
|
# Hook changes to thumb_width
|
||||||
|
self.thumb_width.valueChanged.connect(self.thumb_width_changed)
|
||||||
|
|
||||||
|
# Hook changes to Description section
|
||||||
|
self.generate_descriptions.stateChanged.connect(self.generate_descriptions_changed)
|
||||||
|
|
||||||
|
|
||||||
def options(self):
|
def options(self):
|
||||||
# Save/return the current options
|
# Save/return the current options
|
||||||
# exclude_genre stores literally
|
# exclude_genre stores literally
|
||||||
@ -310,15 +292,6 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
else:
|
else:
|
||||||
opts_dict[c_name] = opt_value
|
opts_dict[c_name] = opt_value
|
||||||
|
|
||||||
'''
|
|
||||||
***
|
|
||||||
# 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 specs for merge_comments, header_note_source_field
|
# Generate specs for merge_comments, header_note_source_field
|
||||||
checked = ''
|
checked = ''
|
||||||
if self.merge_before.isChecked():
|
if self.merge_before.isChecked():
|
||||||
@ -365,17 +338,6 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
if field_md['datatype'] in ['bool','composite','datetime','enumeration','text']:
|
if field_md['datatype'] in ['bool','composite','datetime','enumeration','text']:
|
||||||
custom_fields[field_md['name']] = {'field':custom_field,
|
custom_fields[field_md['name']] = {'field':custom_field,
|
||||||
'datatype':field_md['datatype']}
|
'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, key=sort_key):
|
|
||||||
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
|
# Populate the 'Header note' combo box
|
||||||
custom_fields = {}
|
custom_fields = {}
|
||||||
for custom_field in self.all_custom_fields:
|
for custom_field in self.all_custom_fields:
|
||||||
@ -508,6 +470,12 @@ class PluginWidget(QWidget,Ui_Form):
|
|||||||
self.merge_after.setEnabled(False)
|
self.merge_after.setEnabled(False)
|
||||||
self.include_hr.setEnabled(False)
|
self.include_hr.setEnabled(False)
|
||||||
|
|
||||||
|
def reset_exclude_genres(self):
|
||||||
|
for default in self.OPTION_FIELDS:
|
||||||
|
if default[0] == 'exclude_genre':
|
||||||
|
self.exclude_genre.setText(default[1])
|
||||||
|
break
|
||||||
|
|
||||||
def thumb_width_changed(self,new_value):
|
def thumb_width_changed(self,new_value):
|
||||||
'''
|
'''
|
||||||
Process changes in the thumb_width spin box
|
Process changes in the thumb_width spin box
|
||||||
@ -581,19 +549,20 @@ class GenericRulesTable(QTableWidget):
|
|||||||
self.layout = parent_gb_hl
|
self.layout = parent_gb_hl
|
||||||
|
|
||||||
# Add ourselves to the layout
|
# Add ourselves to the layout
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
|
#print("verticalHeader: %s" % dir(self.verticalHeader()))
|
||||||
|
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||||
sizePolicy.setHorizontalStretch(0)
|
sizePolicy.setHorizontalStretch(0)
|
||||||
sizePolicy.setVerticalStretch(0)
|
sizePolicy.setVerticalStretch(0)
|
||||||
sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
|
#sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
|
||||||
self.setSizePolicy(sizePolicy)
|
self.setSizePolicy(sizePolicy)
|
||||||
self.setMaximumSize(QSize(16777215, 114))
|
self.setMaximumSize(QSize(16777215, 113))
|
||||||
|
|
||||||
self.setColumnCount(0)
|
self.setColumnCount(0)
|
||||||
self.setRowCount(0)
|
self.setRowCount(0)
|
||||||
|
|
||||||
self.layout.addWidget(self)
|
self.layout.addWidget(self)
|
||||||
|
|
||||||
self._init_table_widget()
|
|
||||||
self._init_controls()
|
self._init_controls()
|
||||||
self._initialize()
|
|
||||||
|
|
||||||
def _init_controls(self):
|
def _init_controls(self):
|
||||||
# Add the control set
|
# Add the control set
|
||||||
@ -628,18 +597,6 @@ class GenericRulesTable(QTableWidget):
|
|||||||
|
|
||||||
self.layout.addLayout(vbl)
|
self.layout.addLayout(vbl)
|
||||||
|
|
||||||
def _init_table_widget(self):
|
|
||||||
'''
|
|
||||||
Override this in the specific instance
|
|
||||||
'''
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _initialize(self):
|
|
||||||
'''
|
|
||||||
Override this in the specific instance
|
|
||||||
'''
|
|
||||||
pass
|
|
||||||
|
|
||||||
def add_row(self):
|
def add_row(self):
|
||||||
self.setFocus()
|
self.setFocus()
|
||||||
row = self.currentRow() + 1
|
row = self.currentRow() + 1
|
||||||
@ -683,6 +640,10 @@ class GenericRulesTable(QTableWidget):
|
|||||||
def get_data(self):
|
def get_data(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def focusOutEvent(self,e):
|
||||||
|
# Override of QTableWidget method
|
||||||
|
self.clearSelection()
|
||||||
|
|
||||||
def move_row_down(self):
|
def move_row_down(self):
|
||||||
self.setFocus()
|
self.setFocus()
|
||||||
rows = self.selectionModel().selectedRows()
|
rows = self.selectionModel().selectedRows()
|
||||||
@ -760,8 +721,21 @@ class GenericRulesTable(QTableWidget):
|
|||||||
self.selectRow(row)
|
self.selectRow(row)
|
||||||
self.scrollToItem(self.currentItem())
|
self.scrollToItem(self.currentItem())
|
||||||
|
|
||||||
|
def tweak_height(self, height=4):
|
||||||
|
for i in range(min(3,self.rowCount())):
|
||||||
|
height += self.rowHeight(i)
|
||||||
|
height += self.verticalHeader().sizeHint().height()
|
||||||
|
print("computed table height for %d rows: %d" % (self.rowCount(),height, ))
|
||||||
|
self.setMinimumSize(QSize(16777215, height))
|
||||||
|
self.setMaximumSize(QSize(16777215, height))
|
||||||
|
|
||||||
class ExclusionRules(GenericRulesTable):
|
class ExclusionRules(GenericRulesTable):
|
||||||
|
|
||||||
|
def __init__(self, parent_gb_hl, object_name, rules, eligible_custom_fields, db):
|
||||||
|
super(ExclusionRules, self).__init__(parent_gb_hl, object_name, rules, eligible_custom_fields, db)
|
||||||
|
self._init_table_widget()
|
||||||
|
self._initialize()
|
||||||
|
|
||||||
def _init_table_widget(self):
|
def _init_table_widget(self):
|
||||||
header_labels = ['','Name','Field','Value']
|
header_labels = ['','Name','Field','Value']
|
||||||
self.setColumnCount(len(header_labels))
|
self.setColumnCount(len(header_labels))
|
||||||
@ -770,13 +744,11 @@ class ExclusionRules(GenericRulesTable):
|
|||||||
self.setSelectionBehavior(QAbstractItemView.SelectRows)
|
self.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||||
|
|
||||||
def _initialize(self):
|
def _initialize(self):
|
||||||
# Override max size (118) set in GenericRulesTable
|
|
||||||
self.setMaximumSize(QSize(16777215, 83))
|
|
||||||
|
|
||||||
self.populate()
|
self.populate()
|
||||||
self.resizeColumnsToContents()
|
self.resizeColumnsToContents()
|
||||||
self.resize_name(1.5)
|
self.resize_name(1.5)
|
||||||
self.horizontalHeader().setStretchLastSection(True)
|
self.horizontalHeader().setStretchLastSection(True)
|
||||||
|
self.clearSelection()
|
||||||
|
|
||||||
def convert_row_to_data(self, row):
|
def convert_row_to_data(self, row):
|
||||||
data = self.create_blank_row_data()
|
data = self.create_blank_row_data()
|
||||||
@ -790,7 +762,7 @@ class ExclusionRules(GenericRulesTable):
|
|||||||
def create_blank_row_data(self):
|
def create_blank_row_data(self):
|
||||||
data = {}
|
data = {}
|
||||||
data['ordinal'] = -1
|
data['ordinal'] = -1
|
||||||
data['enabled'] = False
|
data['enabled'] = True
|
||||||
data['name'] = 'New rule'
|
data['name'] = 'New rule'
|
||||||
data['field'] = ''
|
data['field'] = ''
|
||||||
data['pattern'] = ''
|
data['pattern'] = ''
|
||||||
@ -876,6 +848,11 @@ class ExclusionRules(GenericRulesTable):
|
|||||||
|
|
||||||
class PrefixRules(GenericRulesTable):
|
class PrefixRules(GenericRulesTable):
|
||||||
|
|
||||||
|
def __init__(self, parent_gb_hl, object_name, rules, eligible_custom_fields, db):
|
||||||
|
super(PrefixRules, self).__init__(parent_gb_hl, object_name, rules, eligible_custom_fields, db)
|
||||||
|
self._init_table_widget()
|
||||||
|
self._initialize()
|
||||||
|
|
||||||
def _init_table_widget(self):
|
def _init_table_widget(self):
|
||||||
header_labels = ['','Name','Prefix','Field','Value']
|
header_labels = ['','Name','Prefix','Field','Value']
|
||||||
self.setColumnCount(len(header_labels))
|
self.setColumnCount(len(header_labels))
|
||||||
@ -889,6 +866,7 @@ class PrefixRules(GenericRulesTable):
|
|||||||
self.resizeColumnsToContents()
|
self.resizeColumnsToContents()
|
||||||
self.resize_name(1.5)
|
self.resize_name(1.5)
|
||||||
self.horizontalHeader().setStretchLastSection(True)
|
self.horizontalHeader().setStretchLastSection(True)
|
||||||
|
self.clearSelection()
|
||||||
|
|
||||||
def convert_row_to_data(self, row):
|
def convert_row_to_data(self, row):
|
||||||
data = self.create_blank_row_data()
|
data = self.create_blank_row_data()
|
||||||
@ -903,7 +881,7 @@ class PrefixRules(GenericRulesTable):
|
|||||||
def create_blank_row_data(self):
|
def create_blank_row_data(self):
|
||||||
data = {}
|
data = {}
|
||||||
data['ordinal'] = -1
|
data['ordinal'] = -1
|
||||||
data['enabled'] = False
|
data['enabled'] = True
|
||||||
data['name'] = 'New rule'
|
data['name'] = 'New rule'
|
||||||
data['field'] = ''
|
data['field'] = ''
|
||||||
data['pattern'] = ''
|
data['pattern'] = ''
|
||||||
|
@ -111,7 +111,8 @@
|
|||||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||||
p, li { white-space: pre-wrap; }
|
p, li { white-space: pre-wrap; }
|
||||||
</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
|
</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
|
||||||
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Default pattern \[.+\]|\+ excludes tags of the form [tag], e.g., [Project Gutenberg], and '+', the default tag for a read book.</p></body></html></string>
|
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">A regular expression describing genres to be excluded from the generated catalog. Genres are derived from the tags applied to your books.</p>
|
||||||
|
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The default pattern \[.+\]|\+ excludes tags of the form [tag], e.g., [Project Gutenberg], and '+', the default tag for a read book.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Excluded genres</string>
|
<string>Excluded genres</string>
|
||||||
@ -178,6 +179,16 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="reset_exclude_genres_tb">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Reset to default</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -666,19 +666,13 @@ Author '{0}':
|
|||||||
# Remove dups
|
# Remove dups
|
||||||
self.exclude_tags = exclude_tags = list(set(exclude_tags))
|
self.exclude_tags = exclude_tags = list(set(exclude_tags))
|
||||||
|
|
||||||
|
# Report tag exclusions
|
||||||
if self.opts.verbose and self.exclude_tags:
|
if self.opts.verbose and self.exclude_tags:
|
||||||
#self.opts.log.info(" excluding tag list %s" % exclude_tags)
|
data = self.db.get_data_as_dict(ids=self.opts.ids)
|
||||||
search_terms = []
|
|
||||||
for tag in exclude_tags:
|
|
||||||
search_terms.append("tag:=%s" % tag)
|
|
||||||
search_phrase = "%s" % " or ".join(search_terms)
|
|
||||||
self.opts.search_text = search_phrase
|
|
||||||
data = self.plugin.search_sort_db(self.db, self.opts)
|
|
||||||
for record in data:
|
for record in data:
|
||||||
self.opts.log.info("\t- %s (Exclusion rule %s)" % (record['title'], exclude_tags))
|
matched = list(set(record['tags']) & set(exclude_tags))
|
||||||
# Reset the database
|
if matched :
|
||||||
self.opts.search_text = ''
|
self.opts.log.info(" - %s (Exclusion rule %s)" % (record['title'], matched))
|
||||||
data = self.plugin.search_sort_db(self.db, self.opts)
|
|
||||||
|
|
||||||
search_phrase = ''
|
search_phrase = ''
|
||||||
if exclude_tags:
|
if exclude_tags:
|
||||||
@ -3141,7 +3135,7 @@ Author '{0}':
|
|||||||
Evaluate conditions for including prefixes in various listings
|
Evaluate conditions for including prefixes in various listings
|
||||||
'''
|
'''
|
||||||
def log_prefix_rule_match_info(rule, record):
|
def log_prefix_rule_match_info(rule, record):
|
||||||
self.opts.log.info("\t%s %s by %s (Prefix rule '%s': %s:%s)" %
|
self.opts.log.info(" %s %s by %s (Prefix rule '%s': %s:%s)" %
|
||||||
(rule['prefix'],record['title'],
|
(rule['prefix'],record['title'],
|
||||||
record['authors'][0], rule['name'],
|
record['authors'][0], rule['name'],
|
||||||
rule['field'],rule['pattern']))
|
rule['field'],rule['pattern']))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user