mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Implement support for images and links
This commit is contained in:
parent
ba28b2e5f7
commit
8abe395507
@ -20,7 +20,7 @@ from PyQt5.Qt import (
|
|||||||
QVBoxLayout, QWidget, pyqtSignal, pyqtSlot
|
QVBoxLayout, QWidget, pyqtSignal, pyqtSlot
|
||||||
)
|
)
|
||||||
|
|
||||||
from calibre import prepare_string_for_xml, xml_replace_entities
|
from calibre import xml_replace_entities
|
||||||
from calibre.ebooks.chardet import xml_to_unicode
|
from calibre.ebooks.chardet import xml_to_unicode
|
||||||
from calibre.gui2 import NO_URL_FORMATTING, choose_files, error_dialog, gprefs
|
from calibre.gui2 import NO_URL_FORMATTING, choose_files, error_dialog, gprefs
|
||||||
from calibre.gui2.widgets import LineEditECM
|
from calibre.gui2.widgets import LineEditECM
|
||||||
@ -121,6 +121,16 @@ def use_implicit_styling_for_span(span, style):
|
|||||||
span.tag = 'sub' if style.pop('vertical-align') == 'sub' else 'sup'
|
span.tag = 'sub' if style.pop('vertical-align') == 'sub' else 'sup'
|
||||||
|
|
||||||
|
|
||||||
|
def use_implicit_styling_for_a(a, style_map):
|
||||||
|
for span in a.iterchildren('span'):
|
||||||
|
style = style_map[span]
|
||||||
|
if style.get('text-decoration') == 'underline':
|
||||||
|
del style['text-decoration']
|
||||||
|
if style.get('color') == '#0000ff':
|
||||||
|
del style['color']
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
def cleanup_qt_markup(root):
|
def cleanup_qt_markup(root):
|
||||||
from calibre.ebooks.docx.cleanup import lift
|
from calibre.ebooks.docx.cleanup import lift
|
||||||
style_map = defaultdict(dict)
|
style_map = defaultdict(dict)
|
||||||
@ -134,6 +144,8 @@ def cleanup_qt_markup(root):
|
|||||||
remove_zero_indents(tag_style)
|
remove_zero_indents(tag_style)
|
||||||
if tag.tag.startswith('h') and tag.tag[1:] in '123456':
|
if tag.tag.startswith('h') and tag.tag[1:] in '123456':
|
||||||
remove_heading_font_styles(tag, tag_style)
|
remove_heading_font_styles(tag, tag_style)
|
||||||
|
for child in tag.iterdescendants('a'):
|
||||||
|
use_implicit_styling_for_a(child, style_map)
|
||||||
for child in tag.iterdescendants('span'):
|
for child in tag.iterdescendants('span'):
|
||||||
use_implicit_styling_for_span(child, style_map[child])
|
use_implicit_styling_for_span(child, style_map[child])
|
||||||
for style in itervalues(style_map):
|
for style in itervalues(style_map):
|
||||||
@ -517,24 +529,40 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
|
|||||||
url = self.parse_link(link)
|
url = self.parse_link(link)
|
||||||
if url.isValid():
|
if url.isValid():
|
||||||
url = unicode_type(url.toString(NO_URL_FORMATTING))
|
url = unicode_type(url.toString(NO_URL_FORMATTING))
|
||||||
self.setFocus(Qt.OtherFocusReason)
|
self.focus_self()
|
||||||
raise NotImplementedError('TODO')
|
with self.editing_cursor() as c:
|
||||||
if is_image:
|
if is_image:
|
||||||
self.exec_command('insertHTML',
|
c.insertImage(url)
|
||||||
'<img src="%s" alt="%s"></img>'%(prepare_string_for_xml(url, True),
|
else:
|
||||||
prepare_string_for_xml(name or _('Image'), True)))
|
name = name or url
|
||||||
elif name:
|
fmt = QTextCharFormat()
|
||||||
self.exec_command('insertHTML',
|
fmt.setAnchor(True)
|
||||||
'<a href="%s">%s</a>'%(prepare_string_for_xml(url, True),
|
fmt.setAnchorHref(url)
|
||||||
prepare_string_for_xml(name)))
|
fmt.setFontUnderline(True)
|
||||||
else:
|
fmt.setForeground(QBrush(QColor('blue')))
|
||||||
self.exec_command('createLink', url)
|
prev_fmt = c.charFormat()
|
||||||
|
c.mergeCharFormat(fmt)
|
||||||
|
c.insertText(url)
|
||||||
|
c.setCharFormat(prev_fmt)
|
||||||
else:
|
else:
|
||||||
error_dialog(self, _('Invalid URL'),
|
error_dialog(self, _('Invalid URL'),
|
||||||
_('The url %r is invalid') % link, show=True)
|
_('The url %r is invalid') % link, show=True)
|
||||||
|
|
||||||
def ask_link(self):
|
def ask_link(self):
|
||||||
d = QDialog(self)
|
|
||||||
|
class Ask(QDialog):
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
if self.treat_as_image.isChecked():
|
||||||
|
url = self.url.text()
|
||||||
|
if url.lower().split(':', 1)[0] in ('http', 'https'):
|
||||||
|
error_dialog(self, _('Remote images not supported'), _(
|
||||||
|
'You must download the image to you computer, URLs pointing'
|
||||||
|
' to remote images are not supported.'), show=True)
|
||||||
|
return
|
||||||
|
QDialog.accept(self)
|
||||||
|
|
||||||
|
d = Ask(self)
|
||||||
d.setWindowTitle(_('Create link'))
|
d.setWindowTitle(_('Create link'))
|
||||||
l = QFormLayout()
|
l = QFormLayout()
|
||||||
l.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
|
l.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
|
||||||
@ -548,7 +576,8 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
|
|||||||
b.setIcon(QIcon(I('document_open.png')))
|
b.setIcon(QIcon(I('document_open.png')))
|
||||||
|
|
||||||
def cf():
|
def cf():
|
||||||
files = choose_files(d, 'select link file', _('Choose file'), select_only_single_file=True)
|
files = choose_files(d, 'select link file', _('Choose file'), [
|
||||||
|
(_('Images'), 'png jpeg jpg gif'.split())], select_only_single_file=True)
|
||||||
if files:
|
if files:
|
||||||
path = files[0]
|
path = files[0]
|
||||||
d.url.setText(path)
|
d.url.setText(path)
|
||||||
@ -669,14 +698,11 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
|
|||||||
if not allow_undo or self.readonly:
|
if not allow_undo or self.readonly:
|
||||||
self.html = val
|
self.html = val
|
||||||
return
|
return
|
||||||
c = self.textCursor()
|
with self.editing_cursor() as c:
|
||||||
c.beginEditBlock()
|
c.movePosition(QTextCursor.Start, QTextCursor.MoveAnchor)
|
||||||
c.movePosition(QTextCursor.Start, QTextCursor.MoveAnchor)
|
c.movePosition(QTextCursor.End, QTextCursor.KeepAnchor)
|
||||||
c.movePosition(QTextCursor.End, QTextCursor.KeepAnchor)
|
c.removeSelectedText()
|
||||||
c.removeSelectedText()
|
c.insertHTML(val)
|
||||||
c.insertHTML(val)
|
|
||||||
c.endEditBlock()
|
|
||||||
self.setTextCursor(c)
|
|
||||||
|
|
||||||
def text(self):
|
def text(self):
|
||||||
return self.textCursor().selectedText()
|
return self.textCursor().selectedText()
|
||||||
@ -687,6 +713,7 @@ class EditorWidget(QTextEdit, LineEditECM): # {{{
|
|||||||
self.setTextCursor(c)
|
self.setTextCursor(c)
|
||||||
|
|
||||||
def contextMenuEvent(self, ev):
|
def contextMenuEvent(self, ev):
|
||||||
|
raise NotImplementedError('TODO')
|
||||||
menu = self.createStandardContextMenu()
|
menu = self.createStandardContextMenu()
|
||||||
# paste = self.pageAction(QWebPage.Paste)
|
# paste = self.pageAction(QWebPage.Paste)
|
||||||
for action in menu.actions():
|
for action in menu.actions():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user