diff --git a/imgsrc/character-set.svg b/imgsrc/character-set.svg new file mode 100644 index 0000000000..e513ec0451 --- /dev/null +++ b/imgsrc/character-set.svg @@ -0,0 +1,201 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/resources/images/character-set.png b/resources/images/character-set.png new file mode 100644 index 0000000000..5831b73882 Binary files /dev/null and b/resources/images/character-set.png differ diff --git a/src/calibre/gui2/tweak_book/boss.py b/src/calibre/gui2/tweak_book/boss.py index 506eaa9599..c05864725d 100644 --- a/src/calibre/gui2/tweak_book/boss.py +++ b/src/calibre/gui2/tweak_book/boss.py @@ -1068,6 +1068,9 @@ class Boss(QObject): if not editors: self.gui.preview.clear() + def insert_character(self): + self.gui.insert_char.show() + # Shutdown {{{ def quit(self): if not self.confirm_quit(): diff --git a/src/calibre/gui2/tweak_book/char_select.py b/src/calibre/gui2/tweak_book/char_select.py index 3338e46d4f..53da28314e 100644 --- a/src/calibre/gui2/tweak_book/char_select.py +++ b/src/calibre/gui2/tweak_book/char_select.py @@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import, __license__ = 'GPL v3' __copyright__ = '2014, Kovid Goyal ' -import unicodedata, re +import unicodedata, re, weakref from bisect import bisect from functools import partial @@ -548,6 +548,7 @@ class CharDelegate(QStyledItemDelegate): class CharView(QListView): show_name = pyqtSignal(object) + char_selected = pyqtSignal(object) def __init__(self, parent=None): self.last_mouse_idx = -1 @@ -564,6 +565,16 @@ class CharView(QListView): self.setContextMenuPolicy(Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.context_menu) self.showing_favorites = False + pi = plugins['progress_indicator'][0] + if hasattr(pi, 'set_no_activate_on_click'): + pi.set_no_activate_on_click(self) + self.activated.connect(self.item_activated) + self.clicked.connect(self.item_activated) + + def item_activated(self, index): + char_code, ok = self.model().data(index, Qt.UserRole).toInt() + if ok: + self.char_selected.emit(chr(char_code)) def set_allow_drag_and_drop(self, enabled): if not enabled: @@ -640,6 +651,8 @@ class CharSelect(Dialog): def __init__(self, parent=None): self.initialized = False Dialog.__init__(self, _('Insert character'), 'charmap_dialog', parent) + self.setWindowIcon(QIcon(I('character-set.png'))) + self.focus_widget = None def setup_ui(self): self.l = l = QGridLayout(self) @@ -650,6 +663,7 @@ class CharSelect(Dialog): b.setCheckable(True) b.setChecked(False) b.setVisible(False) + b.setDefault(True) self.splitter = s = QSplitter(self) s.setChildrenCollapsible(False) @@ -660,6 +674,7 @@ class CharSelect(Dialog): self.rearrange_button.toggled[bool].connect(self.set_allow_drag_and_drop) self.category_view.category_selected.connect(self.show_chars) self.char_view.show_name.connect(self.show_char_info) + self.char_view.char_selected.connect(self.char_selected) s.addWidget(self.category_view), s.addWidget(self.char_view) self.char_info = la = QLabel('\xa0') @@ -701,10 +716,29 @@ class CharSelect(Dialog): self.char_info.clear() def show(self): + try: + self.focus_widget = weakref.ref(QApplication.focusWidget()) + except TypeError: + self.focus_widget = None self.initialize() Dialog.show(self) self.raise_() + def char_selected(self, c): + if QApplication.keyboardModifiers() & Qt.CTRL: + self.hide() + if self.focus_widget is None or self.focus_widget() is None: + QApplication.clipboard().setText(c) + return + w = self.focus_widget() + if hasattr(w, 'textCursor'): + cr = w.textCursor() + cr.insertText(c) + w.setTextCursor(cr) + elif hasattr(w, 'insert'): + w.insert(c) + + if __name__ == '__main__': app = QApplication([]) w = CharSelect() diff --git a/src/calibre/gui2/tweak_book/ui.py b/src/calibre/gui2/tweak_book/ui.py index 8282c9eae7..81f0134c3c 100644 --- a/src/calibre/gui2/tweak_book/ui.py +++ b/src/calibre/gui2/tweak_book/ui.py @@ -29,6 +29,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.char_select import CharSelect from calibre.gui2.tweak_book.editor.widget import register_text_editor_actions from calibre.gui2.tweak_book.editor.insert_resource import InsertImage @@ -217,6 +218,7 @@ class Main(MainWindow): self.check_book = Check(self) self.toc_view = TOCViewer(self) self.image_browser = InsertImage(self, for_browsing=True) + self.insert_char = CharSelect(self) self.create_actions() self.create_toolbars() @@ -321,6 +323,8 @@ class Main(MainWindow): _('Beautify current file')) self.action_pretty_all = reg('format-justify-fill.png', _('&Beautify all files'), partial(self.boss.pretty_print, False), 'pretty-all', (), _('Beautify all files')) + self.action_insert_char = reg('character-set.png', _('&Insert special character'), self.boss.insert_character, 'insert-character', (), + _('Insert special character')) # Polish actions group = _('Polish Book') @@ -423,6 +427,7 @@ class Main(MainWindow): e.addAction(self.action_editor_cut) e.addAction(self.action_editor_copy) e.addAction(self.action_editor_paste) + e.addAction(self.action_insert_char) e.addSeparator() e.addAction(self.action_preferences) @@ -505,6 +510,7 @@ class Main(MainWindow): b.setToolTip(_('Donate to support calibre development')) QTimer.singleShot(10, b.start_animation) self.global_bar.addWidget(w) + self.global_bar.addAction(self.action_insert_char) a(self.action_help) a = create(_('Polish book tool bar'), 'polish').addAction