mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Returned all the original options sr?_search and sr?_replace and added backward compatibility to search_and_replace.py
This commit is contained in:
parent
298654d9fa
commit
7ea167eec1
@ -156,7 +156,10 @@ def add_pipeline_options(parser, plumber):
|
|||||||
'SEARCH AND REPLACE' : (
|
'SEARCH AND REPLACE' : (
|
||||||
_('Modify the document text and structure using user defined patterns.'),
|
_('Modify the document text and structure using user defined patterns.'),
|
||||||
[
|
[
|
||||||
'search_replace',
|
'sr1_search', 'sr1_replace',
|
||||||
|
'sr2_search', 'sr2_replace',
|
||||||
|
'sr3_search', 'sr3_replace',
|
||||||
|
'search_replace',
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -599,6 +599,32 @@ OptionRecommendation(name='renumber_headings',
|
|||||||
help=_('Looks for occurrences of sequential <h1> or <h2> tags. '
|
help=_('Looks for occurrences of sequential <h1> or <h2> tags. '
|
||||||
'The tags are renumbered to prevent splitting in the middle '
|
'The tags are renumbered to prevent splitting in the middle '
|
||||||
'of chapter headings.')),
|
'of chapter headings.')),
|
||||||
|
OptionRecommendation(name='sr1_search',
|
||||||
|
recommended_value='', level=OptionRecommendation.LOW,
|
||||||
|
help=_('Search pattern (regular expression) to be replaced with '
|
||||||
|
'sr1-replace.')),
|
||||||
|
|
||||||
|
OptionRecommendation(name='sr1_replace',
|
||||||
|
recommended_value='', level=OptionRecommendation.LOW,
|
||||||
|
help=_('Replacement to replace the text found with sr1-search.')),
|
||||||
|
|
||||||
|
OptionRecommendation(name='sr2_search',
|
||||||
|
recommended_value='', level=OptionRecommendation.LOW,
|
||||||
|
help=_('Search pattern (regular expression) to be replaced with '
|
||||||
|
'sr2-replace.')),
|
||||||
|
|
||||||
|
OptionRecommendation(name='sr2_replace',
|
||||||
|
recommended_value='', level=OptionRecommendation.LOW,
|
||||||
|
help=_('Replacement to replace the text found with sr2-search.')),
|
||||||
|
|
||||||
|
OptionRecommendation(name='sr3_search',
|
||||||
|
recommended_value='', level=OptionRecommendation.LOW,
|
||||||
|
help=_('Search pattern (regular expression) to be replaced with '
|
||||||
|
'sr3-replace.')),
|
||||||
|
|
||||||
|
OptionRecommendation(name='sr3_replace',
|
||||||
|
recommended_value='', level=OptionRecommendation.LOW,
|
||||||
|
help=_('Replacement to replace the text found with sr3-search.')),
|
||||||
|
|
||||||
OptionRecommendation(name='search_replace',
|
OptionRecommendation(name='search_replace',
|
||||||
recommended_value='[]', level=OptionRecommendation.LOW,
|
recommended_value='[]', level=OptionRecommendation.LOW,
|
||||||
|
@ -22,7 +22,10 @@ class SearchAndReplaceWidget(Widget, Ui_Form):
|
|||||||
|
|
||||||
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
def __init__(self, parent, get_option, get_help, db=None, book_id=None):
|
||||||
Widget.__init__(self, parent,
|
Widget.__init__(self, parent,
|
||||||
['search_replace']
|
['search_replace',
|
||||||
|
'sr1_search', 'sr1_replace',
|
||||||
|
'sr2_search', 'sr2_replace',
|
||||||
|
'sr3_search', 'sr3_replace']
|
||||||
)
|
)
|
||||||
self.db, self.book_id = db, book_id
|
self.db, self.book_id = db, book_id
|
||||||
|
|
||||||
@ -34,65 +37,70 @@ class SearchAndReplaceWidget(Widget, Ui_Form):
|
|||||||
|
|
||||||
proto = QTableWidgetItem()
|
proto = QTableWidgetItem()
|
||||||
proto.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable + Qt.ItemIsEnabled))
|
proto.setFlags(Qt.ItemFlags(Qt.ItemIsSelectable + Qt.ItemIsEnabled))
|
||||||
self.opt_search_replace.setItemPrototype(proto)
|
self.search_replace.setItemPrototype(proto)
|
||||||
self.opt_search_replace.setColumnCount(2)
|
self.search_replace.setColumnCount(2)
|
||||||
self.opt_search_replace.setColumnWidth(0, 300)
|
self.search_replace.setColumnWidth(0, 300)
|
||||||
self.opt_search_replace.setColumnWidth(1, 300)
|
self.search_replace.setColumnWidth(1, 300)
|
||||||
self.opt_search_replace.setHorizontalHeaderLabels(['Search Expression', 'Replacement'])
|
self.search_replace.setHorizontalHeaderLabels(['Search Expression', 'Replacement'])
|
||||||
|
|
||||||
self.connect(self.sr_add, SIGNAL('clicked()'), self.sr_add_clicked)
|
self.connect(self.sr_add, SIGNAL('clicked()'), self.sr_add_clicked)
|
||||||
self.connect(self.sr_change, SIGNAL('clicked()'), self.sr_change_clicked)
|
self.connect(self.sr_change, SIGNAL('clicked()'), self.sr_change_clicked)
|
||||||
self.connect(self.sr_remove, SIGNAL('clicked()'), self.sr_remove_clicked)
|
self.connect(self.sr_remove, SIGNAL('clicked()'), self.sr_remove_clicked)
|
||||||
self.connect(self.sr_load, SIGNAL('clicked()'), self.sr_load_clicked)
|
self.connect(self.sr_load, SIGNAL('clicked()'), self.sr_load_clicked)
|
||||||
self.connect(self.sr_save, SIGNAL('clicked()'), self.sr_save_clicked)
|
self.connect(self.sr_save, SIGNAL('clicked()'), self.sr_save_clicked)
|
||||||
self.connect(self.opt_search_replace, SIGNAL('currentCellChanged(int, int, int, int)'), self.sr_currentCellChanged)
|
self.connect(self.search_replace, SIGNAL('currentCellChanged(int, int, int, int)'), self.sr_currentCellChanged)
|
||||||
|
|
||||||
self.initialize_options(get_option, get_help, db, book_id)
|
self.initialize_options(get_option, get_help, db, book_id)
|
||||||
|
|
||||||
def sr_add_clicked(self):
|
def sr_add_clicked(self):
|
||||||
if self.sr_search.regex:
|
if self.sr_search.regex:
|
||||||
self.opt_search_replace.insertRow(0)
|
row = self.sr_add_row(self.sr_search.regex, self.sr_replace.text())
|
||||||
newItem = self.opt_search_replace.itemPrototype().clone()
|
self.search_replace.setCurrentCell(row, 0)
|
||||||
newItem.setText(self.sr_search.regex)
|
|
||||||
self.opt_search_replace.setItem(0,0, newItem)
|
def sr_add_row(self, search, replace):
|
||||||
newItem = self.opt_search_replace.itemPrototype().clone()
|
row = self.search_replace.rowCount()
|
||||||
newItem.setText(self.sr_replace.text())
|
self.search_replace.setRowCount(row + 1)
|
||||||
self.opt_search_replace.setItem(0,1, newItem)
|
newItem = self.search_replace.itemPrototype().clone()
|
||||||
self.opt_search_replace.setCurrentCell(0, 0)
|
newItem.setText(search)
|
||||||
|
self.search_replace.setItem(row,0, newItem)
|
||||||
|
newItem = self.search_replace.itemPrototype().clone()
|
||||||
|
newItem.setText(replace)
|
||||||
|
self.search_replace.setItem(row,1, newItem)
|
||||||
|
return row
|
||||||
|
|
||||||
def sr_change_clicked(self):
|
def sr_change_clicked(self):
|
||||||
row = self.opt_search_replace.currentRow()
|
row = self.search_replace.currentRow()
|
||||||
if row >= 0:
|
if row >= 0:
|
||||||
self.opt_search_replace.item(row, 0).setText(self.sr_search.regex)
|
self.search_replace.item(row, 0).setText(self.sr_search.regex)
|
||||||
self.opt_search_replace.item(row, 1).setText(self.sr_replace.text())
|
self.search_replace.item(row, 1).setText(self.sr_replace.text())
|
||||||
self.opt_search_replace.setCurrentCell(row, 0)
|
self.search_replace.setCurrentCell(row, 0)
|
||||||
|
|
||||||
def sr_remove_clicked(self):
|
def sr_remove_clicked(self):
|
||||||
row = self.opt_search_replace.currentRow()
|
row = self.search_replace.currentRow()
|
||||||
if row >= 0:
|
if row >= 0:
|
||||||
self.opt_search_replace.removeRow(row)
|
self.search_replace.removeRow(row)
|
||||||
self.opt_search_replace.setCurrentCell(row-1, 0)
|
self.search_replace.setCurrentCell(row-1, 0)
|
||||||
|
|
||||||
def sr_load_clicked(self):
|
def sr_load_clicked(self):
|
||||||
filename = QFileDialog.getOpenFileName(self, 'Load Calibre Search-Replace definitions file', '.', 'Calibre Search-Replace definitions file (*.csr)')
|
filename = QFileDialog.getOpenFileName(self, 'Load Calibre Search-Replace definitions file', '.', 'Calibre Search-Replace definitions file (*.csr)')
|
||||||
if filename:
|
if filename:
|
||||||
with open(filename, 'r') as f:
|
with open(filename, 'r') as f:
|
||||||
val = f.read()
|
val = f.read()
|
||||||
self.set_value(self.opt_search_replace, val)
|
self.set_value(self.search_replace, val)
|
||||||
|
|
||||||
def sr_save_clicked(self):
|
def sr_save_clicked(self):
|
||||||
filename = QFileDialog.getSaveFileName(self, 'Save Calibre Search-Replace definitions file', '.', 'Calibre Search-Replace definitions file (*.csr)')
|
filename = QFileDialog.getSaveFileName(self, 'Save Calibre Search-Replace definitions file', '.', 'Calibre Search-Replace definitions file (*.csr)')
|
||||||
if filename:
|
if filename:
|
||||||
with open(filename, 'w') as f:
|
with open(filename, 'w') as f:
|
||||||
val = self.get_value(self.opt_search_replace)
|
val = self.get_value(self.search_replace)
|
||||||
f.write(val)
|
f.write(val)
|
||||||
|
|
||||||
def sr_currentCellChanged(self, row, column, previousRow, previousColumn) :
|
def sr_currentCellChanged(self, row, column, previousRow, previousColumn) :
|
||||||
if row >= 0:
|
if row >= 0:
|
||||||
self.sr_change.setEnabled(True)
|
self.sr_change.setEnabled(True)
|
||||||
self.sr_remove.setEnabled(True)
|
self.sr_remove.setEnabled(True)
|
||||||
self.sr_search.set_regex(self.opt_search_replace.item(row, 0).text())
|
self.sr_search.set_regex(self.search_replace.item(row, 0).text())
|
||||||
self.sr_replace.setText(self.opt_search_replace.item(row, 1).text())
|
self.sr_replace.setText(self.search_replace.item(row, 1).text())
|
||||||
else:
|
else:
|
||||||
self.sr_change.setEnabled(False)
|
self.sr_change.setEnabled(False)
|
||||||
self.sr_remove.setEnabled(False)
|
self.sr_remove.setEnabled(False)
|
||||||
@ -114,9 +122,9 @@ class SearchAndReplaceWidget(Widget, Ui_Form):
|
|||||||
self.sr_search.set_doc(doc)
|
self.sr_search.set_doc(doc)
|
||||||
|
|
||||||
def pre_commit_check(self):
|
def pre_commit_check(self):
|
||||||
for row in xrange(0, self.opt_search_replace.rowCount()):
|
for row in xrange(0, self.search_replace.rowCount()):
|
||||||
try:
|
try:
|
||||||
pat = unicode(self.opt_search_replace.item(row,0).text())
|
pat = unicode(self.search_replace.item(row,0).text())
|
||||||
re.compile(pat)
|
re.compile(pat)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
error_dialog(self, _('Invalid regular expression'),
|
error_dialog(self, _('Invalid regular expression'),
|
||||||
@ -124,23 +132,59 @@ class SearchAndReplaceWidget(Widget, Ui_Form):
|
|||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# Options
|
||||||
|
@property
|
||||||
|
def opt_search_replace(self):
|
||||||
|
return 'search_replace'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def opt_sr1_search(self):
|
||||||
|
return 'sr1_search'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def opt_sr1_replace(self):
|
||||||
|
return 'sr1_replace'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def opt_sr2_search(self):
|
||||||
|
return 'sr2_search'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def opt_sr2_replace(self):
|
||||||
|
return 'sr2_replace'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def opt_sr3_search(self):
|
||||||
|
return 'sr3_search'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def opt_sr3_replace(self):
|
||||||
|
return 'sr3_replace'
|
||||||
|
|
||||||
|
|
||||||
# Options handling
|
# Options handling
|
||||||
|
|
||||||
def connect_gui_obj_handler(self, g, slot):
|
def connect_gui_obj_handler(self, g, slot):
|
||||||
if isinstance(g, QTableWidget):
|
if g == self.opt_search_replace:
|
||||||
g.cellChanged.connect(slot)
|
self.search_replace.cellChanged.connect(slot)
|
||||||
|
|
||||||
def get_value_handler(self, g):
|
def get_value_handler(self, g):
|
||||||
|
if g != self.opt_search_replace:
|
||||||
|
return None
|
||||||
|
|
||||||
ans = []
|
ans = []
|
||||||
for row in xrange(0, g.rowCount()):
|
for row in xrange(0, self.search_replace.rowCount()):
|
||||||
colItems = []
|
colItems = []
|
||||||
for col in xrange(0, g.columnCount()):
|
for col in xrange(0, self.search_replace.columnCount()):
|
||||||
colItems.append(unicode(g.item(row, col).text()))
|
colItems.append(unicode(self.search_replace.item(row, col).text()))
|
||||||
ans.append(colItems)
|
ans.append(colItems)
|
||||||
return json.dumps(ans)
|
return json.dumps(ans)
|
||||||
|
|
||||||
def set_value_handler(self, g, val):
|
def set_value_handler(self, g, val):
|
||||||
|
if g != self.opt_search_replace:
|
||||||
|
self.handle_legacy(g, val)
|
||||||
|
return True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rowItems = json.loads(val)
|
rowItems = json.loads(val)
|
||||||
if not isinstance(rowItems, list):
|
if not isinstance(rowItems, list):
|
||||||
@ -148,11 +192,45 @@ class SearchAndReplaceWidget(Widget, Ui_Form):
|
|||||||
except:
|
except:
|
||||||
rowItems = []
|
rowItems = []
|
||||||
|
|
||||||
g.setRowCount(len(rowItems))
|
if len(rowItems) == 0:
|
||||||
|
return True
|
||||||
|
|
||||||
|
self.search_replace.setRowCount(len(rowItems))
|
||||||
|
|
||||||
for row, colItems in enumerate(rowItems):
|
for row, colItems in enumerate(rowItems):
|
||||||
for col, cellValue in enumerate(colItems):
|
for col, cellValue in enumerate(colItems):
|
||||||
newItem = g.itemPrototype().clone()
|
newItem = self.search_replace.itemPrototype().clone()
|
||||||
newItem.setText(cellValue)
|
newItem.setText(cellValue)
|
||||||
g.setItem(row,col, newItem)
|
self.search_replace.setItem(row,col, newItem)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def handle_legacy(self, g, val):
|
||||||
|
'''
|
||||||
|
Handles legacy search/replace options sr1_search, sr1_replace,
|
||||||
|
sr2_search, sr2_replace, sr3_search, sr3_replace.
|
||||||
|
Before introducing the search_replace option only three search/replace
|
||||||
|
definitions could be made. These where stored in the options named above.
|
||||||
|
This function is for backward compatibility with saved options and for
|
||||||
|
compatibility with setting sr* options in the CLI.
|
||||||
|
'''
|
||||||
|
|
||||||
|
if not val: return
|
||||||
|
|
||||||
|
row = int(g[2]) - 1 # the row to set in the search_replace table is 0 for sr1_*, 1 for sr2_*, etc
|
||||||
|
col = (0 if g[4] == 's' else 1) # the fourth character in g is 's' for search options and 'r' for replace options
|
||||||
|
|
||||||
|
# add any missing rows
|
||||||
|
while self.search_replace.rowCount() < row+1:
|
||||||
|
self.sr_add_row('', '')
|
||||||
|
|
||||||
|
# set the value
|
||||||
|
self.search_replace.item(row, col).setText(val)
|
||||||
|
|
||||||
|
def setup_help_handler(self, g, help):
|
||||||
|
if g != self.opt_search_replace:
|
||||||
|
return True
|
||||||
|
|
||||||
|
self.search_replace._help = help
|
||||||
|
self.setup_widget_help(self.search_replace)
|
||||||
|
return True
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QTableWidget" name="opt_search_replace" native="true">
|
<widget class="QTableWidget" name="search_replace" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>0</horstretch>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user