diff --git a/src/calibre/gui2/actions/match_books.py b/src/calibre/gui2/actions/match_books.py index 93e1cffa43..26969e58ce 100644 --- a/src/calibre/gui2/actions/match_books.py +++ b/src/calibre/gui2/actions/match_books.py @@ -36,4 +36,4 @@ class MatchBookAction(InterfaceAction): return id_ = view.model().indices(rows)[0] - MatchBooks(self.gui, view, id_).exec_() + MatchBooks(self.gui, view, id_, rows[0]).exec_() diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index 94ed6de339..aa304a2059 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -1284,9 +1284,7 @@ class DeviceMixin(object): # {{{ prefix = ascii_filename(prefix) names.append('%s_%d%s'%(prefix, id, os.path.splitext(f)[1])) - if mi.cover and os.access(mi.cover, os.R_OK): - mi.thumbnail = self.cover_to_thumbnail(open(mi.cover, - 'rb').read()) + self.update_thumbnail(mi) dynamic.set('catalogs_to_be_synced', set([])) if files: remove = [] @@ -1367,9 +1365,7 @@ class DeviceMixin(object): # {{{ prefix = ascii_filename(prefix) names.append('%s_%d%s'%(prefix, id, os.path.splitext(f)[1])) - if mi.cover and os.access(mi.cover, os.R_OK): - mi.thumbnail = self.cover_to_thumbnail(open(mi.cover, - 'rb').read()) + self.update_thumbnail(mi) self.news_to_be_synced = set([]) if config['upload_news_to_device'] and files: remove = ids if del_on_upload else [] @@ -1423,8 +1419,7 @@ class DeviceMixin(object): # {{{ metadata = self.library_view.model().metadata_for(ids) ids = iter(ids) for mi in metadata: - if mi.cover and os.access(mi.cover, os.R_OK): - mi.thumbnail = self.cover_to_thumbnail(open(mi.cover, 'rb').read()) + self.update_thumbnail(mi) imetadata = iter(metadata) bad, good, gf, names, remove_ids = [], [], [], [], [] @@ -1665,6 +1660,13 @@ class DeviceMixin(object): # {{{ loc[4] |= self.book_db_uuid_path_map[id] return loc + def update_thumbnail(self, book): + if book.cover and os.access(book.cover, os.R_OK): + book.thumbnail = self.cover_to_thumbnail(open(book.cover, 'rb').read()) + else: + book.thumbnail = self.default_thumbnail + + def set_books_in_library(self, booklists, reset=False, add_as_step_to_job=None, force_send=False): ''' @@ -1738,10 +1740,7 @@ class DeviceMixin(object): # {{{ mi = db.get_metadata(id_, index_is_id=True, get_cover=get_covers) book.smart_update(mi, replace_metadata=True) if get_covers and desired_thumbnail_height != 0: - if book.cover and os.access(book.cover, os.R_OK): - book.thumbnail = self.cover_to_thumbnail(open(book.cover, 'rb').read()) - else: - book.thumbnail = self.default_thumbnail + self.update_thumbnail(book) def updateq(id_, book): try: diff --git a/src/calibre/gui2/dialogs/match_books.py b/src/calibre/gui2/dialogs/match_books.py index 6ac7aa533c..3861b3cbe9 100644 --- a/src/calibre/gui2/dialogs/match_books.py +++ b/src/calibre/gui2/dialogs/match_books.py @@ -46,7 +46,7 @@ class TableItem(QTableWidgetItem): class MatchBooks(QDialog, Ui_MatchBooks): - def __init__(self, gui, view, id_): + def __init__(self, gui, view, id_, row_index): QDialog.__init__(self, gui, flags=Qt.Window) Ui_MatchBooks.__init__(self) self.setupUi(self) @@ -73,6 +73,7 @@ class MatchBooks(QDialog, Ui_MatchBooks): self.view = view self.gui = gui self.current_device_book_id = id_ + self.current_device_book_index = row_index self.current_library_book_id = None # Set up the books table columns @@ -107,7 +108,9 @@ class MatchBooks(QDialog, Ui_MatchBooks): self.buttonBox.rejected.connect(self.reject) self.ignore_next_key = False - self.search_text.setText(self.device_db[self.current_device_book_id].title) + search_text= self.device_db[self.current_device_book_id].title + search_text = search_text.replace('(', '\\(').replace(')', '\\)') + self.search_text.setText(search_text) def return_pressed(self): self.ignore_next_key = True @@ -192,9 +195,14 @@ class MatchBooks(QDialog, Ui_MatchBooks): d.exec_() return mi = self.library_db.get_metadata(self.current_library_book_id, - index_is_id=True, get_user_categories=False) - self.device_db[self.current_device_book_id].smart_update(mi, replace_metadata=True) - self.device_db[self.current_device_book_id].in_library_waiting = True + index_is_id=True, get_user_categories=False, + get_cover=True) + book = self.device_db[self.current_device_book_id] + book.smart_update(mi, replace_metadata=True) + self.gui.update_thumbnail(book) + book.in_library_waiting = True + self.view.model().current_changed(self.current_device_book_index, + self.current_device_book_index) self.save_state() QDialog.accept(self) diff --git a/src/calibre/utils/search_query_parser.py b/src/calibre/utils/search_query_parser.py index 12ac9b3931..d3950577d2 100644 --- a/src/calibre/utils/search_query_parser.py +++ b/src/calibre/utils/search_query_parser.py @@ -177,14 +177,17 @@ class Parser(object): def parse(self, expr, locations): self.locations = locations - # Strip out escaped backslashes and escaped quotes so that the + # Strip out escaped backslashes, quotes and parens so that the # lex scanner doesn't get confused. We put them back later. expr = expr.replace(u'\\\\', u'\x01').replace(u'\\"', u'\x02') + expr = expr.replace(u'\\(', u'\x03').replace(u'\\)', u'\x04') self.tokens = self.lex_scanner.scan(expr)[0] for (i,tok) in enumerate(self.tokens): tt, tv = tok if tt == self.WORD or tt == self.QUOTED_WORD: - self.tokens[i] = (tt, tv.replace(u'\x01', u'\\').replace(u'\x02', u'"')) + self.tokens[i] = (tt, + tv.replace(u'\x01', u'\\').replace(u'\x02', u'"'). + replace(u'\x03', u'(').replace(u'\x04', u')')) self.current_token = 0 prog = self.or_expression() @@ -219,10 +222,10 @@ class Parser(object): return self.location_expression() def location_expression(self): - if self.token() == '(': + if self.token_type() == self.OPCODE and self.token() == '(': self.advance() res = self.or_expression() - if self.token(advance=True) != ')': + if self.token_type() != self.OPCODE or self.token(advance=True) != ')': raise ParseException(_('missing )')) return res if self.token_type() not in (self.WORD, self.QUOTED_WORD):