mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement double clicking on image to jump to its references
This commit is contained in:
parent
484bfaed72
commit
f054562ecb
@ -55,15 +55,15 @@ def file_data(container):
|
||||
yield File(name, posixpath.dirname(name), posixpath.basename(name), safe_size(container, name),
|
||||
get_category(name, container.mime_map.get(name, '')))
|
||||
|
||||
Image = namedtuple('Image', 'name mime_type usage size basename width height')
|
||||
Image = namedtuple('Image', 'name mime_type usage size basename id width height')
|
||||
|
||||
L = namedtuple('Location', 'name line_number offset word')
|
||||
def Location(name, line_number=None, offset=0, word=None):
|
||||
return L(name, line_number, offset, word)
|
||||
L = namedtuple('Location', 'name line_number text_on_line word_on_line character_offset')
|
||||
def Location(name, line_number=None, text_on_line=None, word_on_line=None, character_offset=None):
|
||||
return L(name, line_number, text_on_line, word_on_line, character_offset)
|
||||
|
||||
def sort_locations(locations):
|
||||
def sort_key(l):
|
||||
return (numeric_sort_key(l.name), l.line_number, l.offset, l.word)
|
||||
return (numeric_sort_key(l.name), l.line_number, l.character_offset)
|
||||
return sorted(locations, key=sort_key)
|
||||
|
||||
def link_data(container):
|
||||
@ -76,13 +76,13 @@ def link_data(container):
|
||||
if target and container.exists(target):
|
||||
mt = container.mime_map.get(target)
|
||||
if mt and mt.startswith('image/'):
|
||||
image_usage[target].add(Location(name, line_number, offset))
|
||||
image_usage[target].add(Location(name, line_number, text_on_line=href))
|
||||
|
||||
image_data = []
|
||||
for name, mt in container.mime_map.iteritems():
|
||||
if mt.startswith('image/') and container.exists(name):
|
||||
image_data.append(Image(name, mt, sort_locations(image_usage.get(name, set())), safe_size(container, name),
|
||||
posixpath.basename(name), *safe_img_data(container, name, mt)))
|
||||
posixpath.basename(name), len(image_data), *safe_img_data(container, name, mt)))
|
||||
return tuple(image_data)
|
||||
|
||||
def gather_data(container):
|
||||
|
@ -1162,9 +1162,7 @@ class Boss(QObject):
|
||||
def reports_edit_requested(self, location):
|
||||
name = location.name
|
||||
mt = current_container().mime_map.get(name, guess_type(name))
|
||||
editor = self.edit_file_requested(name, None, mt)
|
||||
if editor is not None:
|
||||
pass
|
||||
self.edit_file_requested(name, None, mt)
|
||||
|
||||
def image_activated(self, name):
|
||||
mt = current_container().mime_map.get(name, guess_type(name))
|
||||
@ -1250,7 +1248,7 @@ class Boss(QObject):
|
||||
def edit_file_requested(self, name, syntax, mime):
|
||||
if name in editors:
|
||||
self.gui.central.show_editor(editors[name])
|
||||
return
|
||||
return editors[name]
|
||||
syntax = syntax or syntax_from_mime(name, mime)
|
||||
if not syntax:
|
||||
return error_dialog(
|
||||
|
@ -10,7 +10,9 @@ from threading import Thread
|
||||
from future_builtins import map
|
||||
from operator import itemgetter
|
||||
from functools import partial
|
||||
from collections import defaultdict
|
||||
|
||||
import regex
|
||||
from PyQt5.Qt import (
|
||||
QSize, QStackedLayout, QLabel, QVBoxLayout, Qt, QWidget, pyqtSignal,
|
||||
QAbstractTableModel, QTableView, QSortFilterProxyModel, QIcon, QListWidget,
|
||||
@ -18,6 +20,7 @@ from PyQt5.Qt import (
|
||||
QStyledItemDelegate, QModelIndex, QRect, QStyle, QPalette, QTimer, QMenu)
|
||||
|
||||
from calibre import human_readable, fit_image
|
||||
from calibre.ebooks.oeb.polish.container import guess_type
|
||||
from calibre.ebooks.oeb.polish.report import gather_data, Location
|
||||
from calibre.gui2 import error_dialog, question_dialog
|
||||
from calibre.gui2.tweak_book import current_container, tprefs
|
||||
@ -254,6 +257,39 @@ class FilesWidget(QWidget):
|
||||
|
||||
# }}}
|
||||
|
||||
class Jump(object): # {{{
|
||||
|
||||
def __init__(self):
|
||||
self.pos_map = defaultdict(lambda : -1)
|
||||
|
||||
def clear(self):
|
||||
self.pos_map.clear()
|
||||
|
||||
def __call__(self, key, locations):
|
||||
self.pos_map[key] = (self.pos_map[key] + 1) % len(locations)
|
||||
loc = locations[self.pos_map[key]]
|
||||
from calibre.gui2.tweak_book.boss import get_boss
|
||||
boss = get_boss()
|
||||
if boss is None:
|
||||
return
|
||||
name = loc.name
|
||||
mt = current_container().mime_map.get(name, guess_type(name))
|
||||
editor = boss.edit_file_requested(name, None, mt)
|
||||
if editor is None:
|
||||
return
|
||||
editor = editor.editor
|
||||
if loc.line_number is not None:
|
||||
block = editor.document().findBlockByNumber(loc.line_number - 1) # blockNumber() is zero based
|
||||
if not block.isValid():
|
||||
return
|
||||
c = editor.textCursor()
|
||||
c.setPosition(block.position(), c.MoveAnchor)
|
||||
editor.setTextCursor(c)
|
||||
if loc.text_on_line is not None:
|
||||
editor.find(regex.compile(regex.escape(loc.text_on_line)))
|
||||
|
||||
jump = Jump() # }}}
|
||||
|
||||
# Images {{{
|
||||
|
||||
class ImagesDelegate(QStyledItemDelegate):
|
||||
@ -384,9 +420,9 @@ class ImagesWidget(QWidget):
|
||||
QTimer.singleShot(0, self.files.resizeRowsToContents)
|
||||
|
||||
def double_clicked(self, index):
|
||||
location = self.model.location(index)
|
||||
if location is not None:
|
||||
self.edit_requested.emit(location)
|
||||
entry = index.data(Qt.UserRole)
|
||||
if entry is not None:
|
||||
jump((id(self), entry.id), entry.usage)
|
||||
|
||||
def customize_context_menu(self, menu, selected_locations, current_location):
|
||||
if current_location is not None:
|
||||
@ -436,6 +472,7 @@ class ReportsWidget(QWidget):
|
||||
self.reports.setCurrentRow(current_page)
|
||||
|
||||
def __call__(self, data):
|
||||
jump.clear()
|
||||
self.files(data)
|
||||
self.images(data)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user