Edit Book: Add buttons to the editor toolbar to make the selected text bold/italic/superscript/etc. when editing HTML files.

This commit is contained in:
Kovid Goyal 2013-12-16 16:51:30 +05:30
parent c61bdecc19
commit 14bba3eadc
4 changed files with 83 additions and 0 deletions

View File

@ -443,6 +443,11 @@ class Boss(QObject):
if ed.has_marked_text:
self.gui.central.search_panel.set_where('selected-text')
def editor_action(self, action):
ed = self.gui.central.current_editor
if hasattr(ed, 'action_triggered'):
ed.action_triggered(action)
def show_find(self):
self.gui.central.show_find()
ed = self.gui.central.current_editor

View File

@ -161,6 +161,7 @@ class TextEdit(QPlainTextEdit):
clipboard.setMimeData(md, clipboard.Selection)
def load_text(self, text, syntax='html', process_template=False):
self.syntax = syntax
self.highlighter = {'html':HTMLHighlighter, 'css':CSSHighlighter, 'xml':XMLHighlighter}.get(syntax, SyntaxHighlighter)(self)
self.highlighter.apply_theme(self.theme)
self.highlighter.setDocument(self.document())
@ -460,3 +461,49 @@ class TextEdit(QPlainTextEdit):
ev.ignore()
# }}}
def get_range_inside_tag(self):
c = self.textCursor()
left = min(c.anchor(), c.position())
right = max(c.anchor(), c.position())
# For speed we use QPlainTextEdit's toPlainText as we dont care about
# spaces in this context
raw = unicode(QPlainTextEdit.toPlainText(self))
# Make sure the left edge is not within a <>
gtpos = raw.find('>', left)
ltpos = raw.find('<', left)
if gtpos < ltpos:
left = gtpos + 1 if gtpos > -1 else left
right = max(left, right)
if right != left:
gtpos = raw.find('>', right)
ltpos = raw.find('<', right)
if ltpos > gtpos:
ltpos = raw.rfind('<', left, right+1)
right = max(ltpos, left)
return left, right
def format_text(self, formatting):
if self.syntax != 'html':
return
prefix, suffix = {
'bold': ('<b>', '</b>'),
'italic': ('<i>', '</i>'),
'underline': ('<u>', '</u>'),
'strikethrough': ('<strike>', '</strike>'),
'superscript': ('<sup>', '</sup>'),
'subscript': ('<sub>', '</sub>'),
}[formatting]
left, right = self.get_range_inside_tag()
c = self.textCursor()
c.setPosition(left)
c.setPosition(right, c.KeepAnchor)
prev_text = unicode(c.selectedText())
c.insertText(prefix + prev_text + suffix)
if prev_text:
right = c.position()
c.setPosition(left)
c.setPosition(right, c.KeepAnchor)
else:
c.setPosition(c.position() - len(suffix))
self.setTextCursor(c)

View File

@ -14,6 +14,23 @@ from calibre.gui2 import error_dialog
from calibre.gui2.tweak_book import actions, current_container
from calibre.gui2.tweak_book.editor.text import TextEdit
def register_text_editor_actions(reg):
ac = reg('format-text-bold', _('&Bold'), ('format_text', 'bold'), 'format-text-bold', 'Ctrl+B', _('Make the selected text bold'))
ac.setToolTip(_('<h3>Bold</h3>Make the selected text bold'))
ac = reg('format-text-italic', _('&Italic'), ('format_text', 'italic'), 'format-text-italic', 'Ctrl+I', _('Make the selected text italic'))
ac.setToolTip(_('<h3>Italic</h3>Make the selected text italic'))
ac = reg('format-text-underline', _('&Underline'), ('format_text', 'underline'), 'format-text-underline', (), _('Underline the selected text'))
ac.setToolTip(_('<h3>Underline</h3>Underline the selected text'))
ac = reg('format-text-strikethrough', _('&Strikethrough'), ('format_text', 'strikethrough'),
'format-text-strikethrough', (), _('Draw a line through the selected text'))
ac.setToolTip(_('<h3>Strikethrough</h3>Draw a line through the selected text'))
ac = reg('format-text-superscript', _('&Superscript'), ('format_text', 'superscript'),
'format-text-superscript', (), _('Make the selected text a superscript'))
ac.setToolTip(_('<h3>Superscript</h3>Set the selected text slightly smaller and above the normal line'))
ac = reg('format-text-subscript', _('&Subscript'), ('format_text', 'subscript'),
'format-text-subscript', (), _('Make the selected text a subscript'))
ac.setToolTip(_('<h3>Subscript</h3>Set the selected text slightly smaller and below the normal line'))
class Editor(QMainWindow):
has_line_numbers = True
@ -83,6 +100,11 @@ class Editor(QMainWindow):
def set_focus(self):
self.editor.setFocus(Qt.OtherFocusReason)
def action_triggered(self, action):
action, args = action[0], action[1:]
func = getattr(self.editor, action)
func(*args)
def undo(self):
self.editor.undo()
@ -135,6 +157,10 @@ class Editor(QMainWindow):
b.addAction(actions['fix-html-current'])
if self.syntax in {'xml', 'html', 'css'}:
b.addAction(actions['pretty-current'])
if self.syntax == 'html':
self.format_bar = b = self.addToolBar(_('Format text'))
for x in ('bold', 'italic', 'underline', 'strikethrough', 'subscript', 'superscript'):
b.addAction(actions['format-text-%s' % x])
def break_cycles(self):
self.modification_state_changed.disconnect()

View File

@ -28,6 +28,7 @@ from calibre.gui2.tweak_book.preview import Preview
from calibre.gui2.tweak_book.search import SearchPanel
from calibre.gui2.tweak_book.check import Check
from calibre.gui2.tweak_book.toc import TOCViewer
from calibre.gui2.tweak_book.editor.widget import register_text_editor_actions
def open_donate():
open_url(QUrl('http://calibre-ebook.com/donate'))
@ -290,6 +291,10 @@ class Main(MainWindow):
self.action_editor_undo.setEnabled(False)
self.action_editor_redo.setEnabled(False)
def ereg(icon, text, target, sid, keys, description):
return reg(icon, text, partial(self.boss.editor_action, target), sid, keys, description)
register_text_editor_actions(ereg)
# Tool actions
group = _('Tools')
self.action_toc = reg('toc.png', _('&Edit Table of Contents'), self.boss.edit_toc, 'edit-toc', (), _('Edit Table of Contents'))