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),
|
yield File(name, posixpath.dirname(name), posixpath.basename(name), safe_size(container, name),
|
||||||
get_category(name, container.mime_map.get(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')
|
L = namedtuple('Location', 'name line_number text_on_line word_on_line character_offset')
|
||||||
def Location(name, line_number=None, offset=0, word=None):
|
def Location(name, line_number=None, text_on_line=None, word_on_line=None, character_offset=None):
|
||||||
return L(name, line_number, offset, word)
|
return L(name, line_number, text_on_line, word_on_line, character_offset)
|
||||||
|
|
||||||
def sort_locations(locations):
|
def sort_locations(locations):
|
||||||
def sort_key(l):
|
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)
|
return sorted(locations, key=sort_key)
|
||||||
|
|
||||||
def link_data(container):
|
def link_data(container):
|
||||||
@ -76,13 +76,13 @@ def link_data(container):
|
|||||||
if target and container.exists(target):
|
if target and container.exists(target):
|
||||||
mt = container.mime_map.get(target)
|
mt = container.mime_map.get(target)
|
||||||
if mt and mt.startswith('image/'):
|
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 = []
|
image_data = []
|
||||||
for name, mt in container.mime_map.iteritems():
|
for name, mt in container.mime_map.iteritems():
|
||||||
if mt.startswith('image/') and container.exists(name):
|
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),
|
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)
|
return tuple(image_data)
|
||||||
|
|
||||||
def gather_data(container):
|
def gather_data(container):
|
||||||
|
@ -1162,9 +1162,7 @@ class Boss(QObject):
|
|||||||
def reports_edit_requested(self, location):
|
def reports_edit_requested(self, location):
|
||||||
name = location.name
|
name = location.name
|
||||||
mt = current_container().mime_map.get(name, guess_type(name))
|
mt = current_container().mime_map.get(name, guess_type(name))
|
||||||
editor = self.edit_file_requested(name, None, mt)
|
self.edit_file_requested(name, None, mt)
|
||||||
if editor is not None:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def image_activated(self, name):
|
def image_activated(self, name):
|
||||||
mt = current_container().mime_map.get(name, guess_type(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):
|
def edit_file_requested(self, name, syntax, mime):
|
||||||
if name in editors:
|
if name in editors:
|
||||||
self.gui.central.show_editor(editors[name])
|
self.gui.central.show_editor(editors[name])
|
||||||
return
|
return editors[name]
|
||||||
syntax = syntax or syntax_from_mime(name, mime)
|
syntax = syntax or syntax_from_mime(name, mime)
|
||||||
if not syntax:
|
if not syntax:
|
||||||
return error_dialog(
|
return error_dialog(
|
||||||
|
@ -10,7 +10,9 @@ from threading import Thread
|
|||||||
from future_builtins import map
|
from future_builtins import map
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
|
import regex
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QSize, QStackedLayout, QLabel, QVBoxLayout, Qt, QWidget, pyqtSignal,
|
QSize, QStackedLayout, QLabel, QVBoxLayout, Qt, QWidget, pyqtSignal,
|
||||||
QAbstractTableModel, QTableView, QSortFilterProxyModel, QIcon, QListWidget,
|
QAbstractTableModel, QTableView, QSortFilterProxyModel, QIcon, QListWidget,
|
||||||
@ -18,6 +20,7 @@ from PyQt5.Qt import (
|
|||||||
QStyledItemDelegate, QModelIndex, QRect, QStyle, QPalette, QTimer, QMenu)
|
QStyledItemDelegate, QModelIndex, QRect, QStyle, QPalette, QTimer, QMenu)
|
||||||
|
|
||||||
from calibre import human_readable, fit_image
|
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.ebooks.oeb.polish.report import gather_data, Location
|
||||||
from calibre.gui2 import error_dialog, question_dialog
|
from calibre.gui2 import error_dialog, question_dialog
|
||||||
from calibre.gui2.tweak_book import current_container, tprefs
|
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 {{{
|
# Images {{{
|
||||||
|
|
||||||
class ImagesDelegate(QStyledItemDelegate):
|
class ImagesDelegate(QStyledItemDelegate):
|
||||||
@ -384,9 +420,9 @@ class ImagesWidget(QWidget):
|
|||||||
QTimer.singleShot(0, self.files.resizeRowsToContents)
|
QTimer.singleShot(0, self.files.resizeRowsToContents)
|
||||||
|
|
||||||
def double_clicked(self, index):
|
def double_clicked(self, index):
|
||||||
location = self.model.location(index)
|
entry = index.data(Qt.UserRole)
|
||||||
if location is not None:
|
if entry is not None:
|
||||||
self.edit_requested.emit(location)
|
jump((id(self), entry.id), entry.usage)
|
||||||
|
|
||||||
def customize_context_menu(self, menu, selected_locations, current_location):
|
def customize_context_menu(self, menu, selected_locations, current_location):
|
||||||
if current_location is not None:
|
if current_location is not None:
|
||||||
@ -436,6 +472,7 @@ class ReportsWidget(QWidget):
|
|||||||
self.reports.setCurrentRow(current_page)
|
self.reports.setCurrentRow(current_page)
|
||||||
|
|
||||||
def __call__(self, data):
|
def __call__(self, data):
|
||||||
|
jump.clear()
|
||||||
self.files(data)
|
self.files(data)
|
||||||
self.images(data)
|
self.images(data)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user