mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Edit Book: When inserting hyperlinks, allow specifying the text for the hyperlink in the insert hyperlink dialog
This commit is contained in:
parent
b5dba545cd
commit
82e1000626
@ -643,9 +643,9 @@ class Boss(QObject):
|
||||
ed.insert_image(href)
|
||||
elif action[0] == 'insert_hyperlink':
|
||||
self.commit_all_editors_to_container()
|
||||
d = InsertLink(current_container(), edname, parent=self.gui)
|
||||
d = InsertLink(current_container(), edname, initial_text=ed.get_smart_selection(), parent=self.gui)
|
||||
if d.exec_() == d.Accepted:
|
||||
ed.insert_hyperlink(d.href)
|
||||
ed.insert_hyperlink(d.href, d.text)
|
||||
else:
|
||||
ed.action_triggered(action)
|
||||
|
||||
|
@ -14,3 +14,6 @@ class NullSmarts(object):
|
||||
def get_extra_selections(self, editor):
|
||||
return ()
|
||||
|
||||
def get_smart_selection(self, editor, update=True):
|
||||
return editor.selected_text
|
||||
|
||||
|
@ -129,7 +129,7 @@ def rename_tag(cursor, opening_tag, closing_tag, new_name, insert=False):
|
||||
cursor.insertText(text)
|
||||
cursor.endEditBlock()
|
||||
|
||||
def ensure_not_within_tag_definition(cursor):
|
||||
def ensure_not_within_tag_definition(cursor, forward=True):
|
||||
''' Ensure the cursor is not inside a tag definition <>. Returns True iff the cursor was moved. '''
|
||||
block, offset = cursor.block(), cursor.positionInBlock()
|
||||
b, boundary = next_tag_boundary(block, offset, forward=False)
|
||||
@ -137,10 +137,15 @@ def ensure_not_within_tag_definition(cursor):
|
||||
return False
|
||||
if boundary.is_start:
|
||||
# We are inside a tag
|
||||
if forward:
|
||||
block, boundary = next_tag_boundary(block, offset)
|
||||
if block is not None:
|
||||
cursor.setPosition(block.position() + boundary.offset + 1)
|
||||
return True
|
||||
else:
|
||||
cursor.setPosition(b.position() + boundary.offset)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
class HTMLSmarts(NullSmarts):
|
||||
@ -195,7 +200,27 @@ class HTMLSmarts(NullSmarts):
|
||||
return error_dialog(editor, _('No found'), _(
|
||||
'No suitable block level tag was found to rename'), show=True)
|
||||
|
||||
def insert_hyperlink(self, editor, target):
|
||||
def get_smart_selection(self, editor, update=True):
|
||||
cursor = editor.textCursor()
|
||||
if not cursor.hasSelection():
|
||||
return ''
|
||||
left = min(cursor.anchor(), cursor.position())
|
||||
right = max(cursor.anchor(), cursor.position())
|
||||
|
||||
cursor.setPosition(left)
|
||||
ensure_not_within_tag_definition(cursor)
|
||||
left = cursor.position()
|
||||
|
||||
cursor.setPosition(right)
|
||||
ensure_not_within_tag_definition(cursor, forward=False)
|
||||
right = cursor.position()
|
||||
|
||||
cursor.setPosition(left), cursor.setPosition(right, cursor.KeepAnchor)
|
||||
if update:
|
||||
editor.setTextCursor(cursor)
|
||||
return editor.selected_text_from_cursor(cursor)
|
||||
|
||||
def insert_hyperlink(self, editor, target, text):
|
||||
c = editor.textCursor()
|
||||
if c.hasSelection():
|
||||
c.insertText('') # delete any existing selected text
|
||||
@ -204,4 +229,6 @@ class HTMLSmarts(NullSmarts):
|
||||
p = c.position()
|
||||
c.insertText('</a>')
|
||||
c.setPosition(p) # ensure cursor is positioned inside the newly created tag
|
||||
if text:
|
||||
c.insertText(text)
|
||||
editor.setTextCursor(c)
|
||||
|
@ -101,9 +101,12 @@ class PlainTextEdit(QPlainTextEdit):
|
||||
self.copy()
|
||||
self.textCursor().removeSelectedText()
|
||||
|
||||
def selected_text_from_cursor(self, cursor):
|
||||
return unicodedata.normalize('NFC', unicode(cursor.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0'))
|
||||
|
||||
@property
|
||||
def selected_text(self):
|
||||
return unicodedata.normalize('NFC', unicode(self.textCursor().selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0'))
|
||||
return self.selected_text_from_cursor(self.textCursor())
|
||||
|
||||
def selection_changed(self):
|
||||
# Workaround Qt replacing nbsp with normal spaces on copy
|
||||
@ -602,9 +605,9 @@ class TextEdit(PlainTextEdit):
|
||||
c.setPosition(left + len(text), c.KeepAnchor)
|
||||
self.setTextCursor(c)
|
||||
|
||||
def insert_hyperlink(self, target):
|
||||
def insert_hyperlink(self, target, text):
|
||||
if hasattr(self.smarts, 'insert_hyperlink'):
|
||||
self.smarts.insert_hyperlink(self, target)
|
||||
self.smarts.insert_hyperlink(self, target, text)
|
||||
|
||||
def keyPressEvent(self, ev):
|
||||
if ev.key() == Qt.Key_X and ev.modifiers() == Qt.AltModifier:
|
||||
|
@ -144,8 +144,8 @@ class Editor(QMainWindow):
|
||||
def insert_image(self, href):
|
||||
self.editor.insert_image(href)
|
||||
|
||||
def insert_hyperlink(self, href):
|
||||
self.editor.insert_hyperlink(href)
|
||||
def insert_hyperlink(self, href, text):
|
||||
self.editor.insert_hyperlink(href, text)
|
||||
|
||||
def undo(self):
|
||||
self.editor.undo()
|
||||
@ -157,6 +157,9 @@ class Editor(QMainWindow):
|
||||
def selected_text(self):
|
||||
return self.editor.selected_text
|
||||
|
||||
def get_smart_selection(self, update=True):
|
||||
return self.editor.smarts.get_smart_selection(self.editor, update=update)
|
||||
|
||||
# Search and replace {{{
|
||||
def mark_selected_text(self):
|
||||
self.editor.mark_selected_text()
|
||||
|
@ -537,9 +537,10 @@ def create_filterable_names_list(names, filter_text=None, parent=None):
|
||||
# Insert Link {{{
|
||||
class InsertLink(Dialog):
|
||||
|
||||
def __init__(self, container, source_name, parent=None):
|
||||
def __init__(self, container, source_name, initial_text=None, parent=None):
|
||||
self.container = container
|
||||
self.source_name = source_name
|
||||
self.initial_text = initial_text
|
||||
Dialog.__init__(self, _('Insert Hyperlink'), 'insert-hyperlink', parent=parent)
|
||||
self.anchor_cache = {}
|
||||
|
||||
@ -573,14 +574,18 @@ class InsertLink(Dialog):
|
||||
fnl.addWidget(la), fnl.addWidget(f), fnl.addWidget(fn)
|
||||
h.addLayout(fnl), h.setStretch(1, 1)
|
||||
|
||||
self.tl = tl = QHBoxLayout()
|
||||
self.la3 = la = QLabel(_('&Target:'))
|
||||
tl.addWidget(la)
|
||||
self.tl = tl = QFormLayout()
|
||||
self.target = t = QLineEdit(self)
|
||||
la.setBuddy(t)
|
||||
tl.addWidget(t)
|
||||
t.setPlaceholderText(_('The destination (href) for the link'))
|
||||
tl.addRow(_('&Target:'), t)
|
||||
l.addLayout(tl)
|
||||
|
||||
self.text_edit = t = QLineEdit(self)
|
||||
la.setBuddy(t)
|
||||
tl.addRow(_('Te&xt:'), t)
|
||||
t.setText(self.initial_text or '')
|
||||
t.setPlaceholderText(_('The (optional) text for the link'))
|
||||
|
||||
l.addWidget(self.bb)
|
||||
|
||||
def selected_file_changed(self, *args):
|
||||
@ -622,6 +627,10 @@ class InsertLink(Dialog):
|
||||
def href(self):
|
||||
return unicode(self.target.text()).strip()
|
||||
|
||||
@property
|
||||
def text(self):
|
||||
return unicode(self.text_edit.text()).strip()
|
||||
|
||||
@classmethod
|
||||
def test(cls):
|
||||
import sys
|
||||
@ -629,7 +638,7 @@ class InsertLink(Dialog):
|
||||
c = get_container(sys.argv[-1], tweak_mode=True)
|
||||
d = cls(c, next(c.spine_names)[0])
|
||||
if d.exec_() == d.Accepted:
|
||||
print (d.href)
|
||||
print (d.href, d.text)
|
||||
|
||||
# }}}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user