From e2647b735fb8b96592a0732cfce67c05583655bf Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 15 Jan 2014 11:13:34 +0530 Subject: [PATCH] Allow errors to be associated with multiple locations --- src/calibre/ebooks/oeb/polish/check/base.py | 3 ++ src/calibre/gui2/tweak_book/boss.py | 8 ++- src/calibre/gui2/tweak_book/check.py | 59 ++++++++++++++------- 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/calibre/ebooks/oeb/polish/check/base.py b/src/calibre/ebooks/oeb/polish/check/base.py index 4f2a61f15a..089de1390e 100644 --- a/src/calibre/ebooks/oeb/polish/check/base.py +++ b/src/calibre/ebooks/oeb/polish/check/base.py @@ -18,10 +18,13 @@ class BaseError(object): HELP = '' INDIVIDUAL_FIX = '' level = ERROR + has_multiple_locations = False def __init__(self, msg, name, line=None, col=None): self.msg, self.line, self.col = msg, line, col self.name = name + # A list with entries of the form: (name, lnum, col) + self.all_locations = None def __str__(self): return '%s:%s (%s, %s):%s' % (self.__class__.__name__, self.name, self.line, self.col, self.msg) diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py index 9e310ac6ee..29f7cf821b 100644 --- a/src/calibre/gui2/tweak_book/boss.py +++ b/src/calibre/gui2/tweak_book/boss.py @@ -843,14 +843,18 @@ class Boss(QObject): @in_thread_job def check_item_activated(self, item): - name = item.name + is_mult = item.has_multiple_locations and getattr(item, 'current_location_index', None) is not None + name = item.all_locations[item.current_location_index][0] if is_mult else item.name if name in editors: editor = editors[name] self.gui.central.show_editor(editor) else: editor = self.edit_file_requested(name, None, current_container().mime_map[name]) if getattr(editor, 'has_line_numbers', False): - editor.go_to_line(item.line, item.col) + if is_mult: + editor.go_to_line(*(item.all_locations[item.current_location_index][1:3])) + else: + editor.go_to_line(item.line, item.col) editor.set_focus() @in_thread_job diff --git a/src/calibre/gui2/tweak_book/check.py b/src/calibre/gui2/tweak_book/check.py index 01c682d71e..2c1db5117d 100644 --- a/src/calibre/gui2/tweak_book/check.py +++ b/src/calibre/gui2/tweak_book/check.py @@ -85,6 +85,9 @@ class Check(QSplitter): num = int(url.rpartition(',')[-1]) errors = [self.items.item(num).data(Qt.UserRole).toPyObject()] self.fix_requested.emit(errors) + elif url.startswith('activate:item:'): + index = int(url.rpartition(':')[-1]) + self.location_activated(index) def next_error(self, delta=1): row = self.items.currentRow() @@ -100,35 +103,55 @@ class Check(QSplitter): err = i.data(Qt.UserRole).toPyObject() self.item_activated.emit(err) + def location_activated(self, index): + i = self.items.currentItem() + if i is not None: + err = i.data(Qt.UserRole).toPyObject() + err.current_location_index = index + self.item_activated.emit(err) + def current_item_changed(self, *args): i = self.items.currentItem() self.help.setText('') + def loc_to_string(line, col): + loc = '' + if line is not None: + loc = _('line: %d') % line + if col is not None: + loc += _(' column: %d') % col + if loc: + loc = ' (%s)' % loc + return loc + if i is not None: err = i.data(Qt.UserRole).toPyObject() header = {DEBUG:_('Debug'), INFO:_('Information'), WARN:_('Warning'), ERROR:_('Error'), CRITICAL:_('Error')}[err.level] - loc = '' - if err.line is not None: - loc = _('line: %d') % err.line - if err.col is not None: - loc += ' column: %d' % err.col - if loc: - loc = ' (%s)' % loc ifix = '' + loc = loc_to_string(err.line, err.col) if err.INDIVIDUAL_FIX: ifix = '%s

' % ( self.items.currentRow(), _('Try to fix only this error'), err.INDIVIDUAL_FIX) - + open_tt = _('Click to open in editor') + fix_tt = _('Try to fix all fixable errors automatically. Only works for some types of error.') + fix_msg = _('Try to correct all fixable errors automatically') + run_tt, run_msg = _('Re-run the check'), _('Re-run check') + header = '

%s [%d / %d]

' % ( + header, self.items.currentRow()+1, self.items.count()) + msg = '

%s

' + footer = '
%s%s

%s
' + if err.has_multiple_locations: + activate = [] + for i, (name, lnum, col) in enumerate(err.all_locations): + activate.append('%s %s' % ( + i, open_tt, name, loc_to_string(lnum, col))) + activate = '
%s

' % ('
'.join(activate)) + template = header + msg + activate + footer + else: + activate = '
%s %s
' % ( + open_tt, err.name, loc) + template = header + activate + msg + footer self.help.setText( - '''

%s [%d / %d]

-
%s %s
-

%s

-
%s%s

- %s
- ''' % (header, self.items.currentRow()+1, self.items.count(), - _('Click to open in editor'), err.name, loc, err.HELP, ifix, - _('Try to fix all fixable errors automatically. Only works for some types of error.'), - _('Try to correct all fixable errors automatically'), - _('Re-run the check'), _('Re-run check'))) + template % (err.HELP, ifix, fix_tt, fix_msg, run_tt, run_msg)) def run_checks(self, container): from calibre.gui2.tweak_book.boss import BusyCursor