mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Refactor for better code organization
This commit is contained in:
parent
b564245480
commit
08a536ff48
@ -19,7 +19,7 @@ from PyQt5.Qt import (
|
|||||||
from calibre.gui2 import error_dialog
|
from calibre.gui2 import error_dialog
|
||||||
from calibre.gui2.tweak_book.editor import all_text_syntaxes
|
from calibre.gui2.tweak_book.editor import all_text_syntaxes
|
||||||
from calibre.gui2.tweak_book.editor.smarts.utils import get_text_before_cursor
|
from calibre.gui2.tweak_book.editor.smarts.utils import get_text_before_cursor
|
||||||
from calibre.gui2.tweak_book.widgets import Dialog
|
from calibre.gui2.tweak_book.widgets import Dialog, PlainTextEdit
|
||||||
from calibre.utils.config import JSONConfig
|
from calibre.utils.config import JSONConfig
|
||||||
from calibre.utils.icu import string_length as strlen
|
from calibre.utils.icu import string_length as strlen
|
||||||
|
|
||||||
@ -413,6 +413,19 @@ class SnippetManager(QObject):
|
|||||||
|
|
||||||
# Config {{{
|
# Config {{{
|
||||||
|
|
||||||
|
class SnippetTextEdit(PlainTextEdit):
|
||||||
|
|
||||||
|
def __init__(self, text, parent=None):
|
||||||
|
PlainTextEdit.__init__(self, parent)
|
||||||
|
if text:
|
||||||
|
self.setPlainText(text)
|
||||||
|
self.snippet_manager = SnippetManager(self)
|
||||||
|
|
||||||
|
def keyPressEvent(self, ev):
|
||||||
|
if self.snippet_manager.handle_key_press(ev):
|
||||||
|
return
|
||||||
|
PlainTextEdit.keyPressEvent(self, ev)
|
||||||
|
|
||||||
class EditSnippet(QWidget):
|
class EditSnippet(QWidget):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
@ -451,11 +464,10 @@ class EditSnippet(QWidget):
|
|||||||
add_row(_('&File types:'), t)
|
add_row(_('&File types:'), t)
|
||||||
t.setToolTip(_('Which file types this snippet should be active in'))
|
t.setToolTip(_('Which file types this snippet should be active in'))
|
||||||
|
|
||||||
from calibre.gui2.tweak_book.search import TextEdit
|
|
||||||
self.frame = f = QFrame(self)
|
self.frame = f = QFrame(self)
|
||||||
f.setFrameShape(f.HLine)
|
f.setFrameShape(f.HLine)
|
||||||
add_row(f)
|
add_row(f)
|
||||||
self.test = d = TextEdit('', self)
|
self.test = d = SnippetTextEdit('', self)
|
||||||
d.snippet_manager.snip_func = self.snip_func
|
d.snippet_manager.snip_func = self.snip_func
|
||||||
d.setToolTip(_('You can test your snippet here'))
|
d.setToolTip(_('You can test your snippet here'))
|
||||||
d.setMaximumHeight(t.maximumHeight() + 15)
|
d.setMaximumHeight(t.maximumHeight() + 15)
|
||||||
|
@ -13,8 +13,8 @@ from future_builtins import map
|
|||||||
import regex
|
import regex
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QPlainTextEdit, QFontDatabase, QToolTip, QPalette, QFont, QKeySequence,
|
QPlainTextEdit, QFontDatabase, QToolTip, QPalette, QFont, QKeySequence,
|
||||||
QTextEdit, QTextFormat, QWidget, QSize, QPainter, Qt, QRect, pyqtSlot,
|
QTextEdit, QTextFormat, QWidget, QSize, QPainter, Qt, QRect, QColor,
|
||||||
QApplication, QMimeData, QColor, QColorDialog, QTimer, pyqtSignal, QT_VERSION)
|
QColorDialog, QTimer, pyqtSignal, QT_VERSION)
|
||||||
|
|
||||||
from calibre import prepare_string_for_xml
|
from calibre import prepare_string_for_xml
|
||||||
from calibre.constants import isosx
|
from calibre.constants import isosx
|
||||||
@ -26,14 +26,11 @@ from calibre.gui2.tweak_book.editor.themes import get_theme, theme_color, theme_
|
|||||||
from calibre.gui2.tweak_book.editor.syntax.base import SyntaxHighlighter
|
from calibre.gui2.tweak_book.editor.syntax.base import SyntaxHighlighter
|
||||||
from calibre.gui2.tweak_book.editor.smarts import NullSmarts
|
from calibre.gui2.tweak_book.editor.smarts import NullSmarts
|
||||||
from calibre.gui2.tweak_book.editor.snippets import SnippetManager
|
from calibre.gui2.tweak_book.editor.snippets import SnippetManager
|
||||||
|
from calibre.gui2.tweak_book.widgets import PlainTextEdit, PARAGRAPH_SEPARATOR
|
||||||
from calibre.spell.break_iterator import index_of
|
from calibre.spell.break_iterator import index_of
|
||||||
from calibre.utils.icu import safe_chr, string_length, capitalize, upper, lower, swapcase
|
from calibre.utils.icu import safe_chr, string_length, capitalize, upper, lower, swapcase
|
||||||
from calibre.utils.titlecase import titlecase
|
from calibre.utils.titlecase import titlecase
|
||||||
|
|
||||||
PARAGRAPH_SEPARATOR = '\u2029'
|
|
||||||
|
|
||||||
def selected_text_from_cursor(cursor):
|
|
||||||
return unicodedata.normalize('NFC', unicode(cursor.selectedText()).replace(PARAGRAPH_SEPARATOR, '\n').rstrip('\0'))
|
|
||||||
|
|
||||||
def get_highlighter(syntax):
|
def get_highlighter(syntax):
|
||||||
if syntax:
|
if syntax:
|
||||||
@ -76,67 +73,6 @@ class LineNumbers(QWidget): # {{{
|
|||||||
self.parent().paint_line_numbers(ev)
|
self.parent().paint_line_numbers(ev)
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
class PlainTextEdit(QPlainTextEdit):
|
|
||||||
|
|
||||||
''' A class that overrides some methods from QPlainTextEdit to fix handling
|
|
||||||
of the nbsp unicode character. '''
|
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
QPlainTextEdit.__init__(self, parent)
|
|
||||||
self.selectionChanged.connect(self.selection_changed)
|
|
||||||
self.syntax = None
|
|
||||||
|
|
||||||
def toPlainText(self):
|
|
||||||
# QPlainTextEdit's toPlainText implementation replaces nbsp with normal
|
|
||||||
# space, so we re-implement it using QTextCursor, which does not do
|
|
||||||
# that
|
|
||||||
c = self.textCursor()
|
|
||||||
c.clearSelection()
|
|
||||||
c.movePosition(c.Start)
|
|
||||||
c.movePosition(c.End, c.KeepAnchor)
|
|
||||||
ans = c.selectedText().replace(PARAGRAPH_SEPARATOR, '\n')
|
|
||||||
# QTextCursor pads the return value of selectedText with null bytes if
|
|
||||||
# non BMP characters such as 0x1f431 are present.
|
|
||||||
return ans.rstrip('\0')
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def copy(self):
|
|
||||||
# Workaround Qt replacing nbsp with normal spaces on copy
|
|
||||||
c = self.textCursor()
|
|
||||||
if not c.hasSelection():
|
|
||||||
return
|
|
||||||
md = QMimeData()
|
|
||||||
md.setText(self.selected_text)
|
|
||||||
QApplication.clipboard().setMimeData(md)
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def cut(self):
|
|
||||||
# Workaround Qt replacing nbsp with normal spaces on copy
|
|
||||||
self.copy()
|
|
||||||
self.textCursor().removeSelectedText()
|
|
||||||
|
|
||||||
def selected_text_from_cursor(self, cursor):
|
|
||||||
return selected_text_from_cursor(cursor)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def selected_text(self):
|
|
||||||
return self.selected_text_from_cursor(self.textCursor())
|
|
||||||
|
|
||||||
def selection_changed(self):
|
|
||||||
# Workaround Qt replacing nbsp with normal spaces on copy
|
|
||||||
clipboard = QApplication.clipboard()
|
|
||||||
if clipboard.supportsSelection() and self.textCursor().hasSelection():
|
|
||||||
md = QMimeData()
|
|
||||||
md.setText(self.selected_text)
|
|
||||||
clipboard.setMimeData(md, clipboard.Selection)
|
|
||||||
|
|
||||||
def event(self, ev):
|
|
||||||
if ev.type() == ev.ShortcutOverride and ev in (QKeySequence.Copy, QKeySequence.Cut):
|
|
||||||
ev.accept()
|
|
||||||
(self.copy if ev == QKeySequence.Copy else self.cut)()
|
|
||||||
return True
|
|
||||||
return QPlainTextEdit.event(self, ev)
|
|
||||||
|
|
||||||
class TextEdit(PlainTextEdit):
|
class TextEdit(PlainTextEdit):
|
||||||
|
|
||||||
link_clicked = pyqtSignal(object)
|
link_clicked = pyqtSignal(object)
|
||||||
|
@ -26,8 +26,7 @@ from calibre.gui2.tweak_book import tprefs, editors, current_container
|
|||||||
from calibre.gui2.tweak_book.function_replace import (
|
from calibre.gui2.tweak_book.function_replace import (
|
||||||
FunctionBox, functions as replace_functions, FunctionEditor, remove_function, Function)
|
FunctionBox, functions as replace_functions, FunctionEditor, remove_function, Function)
|
||||||
from calibre.gui2.tweak_book.widgets import BusyCursor
|
from calibre.gui2.tweak_book.widgets import BusyCursor
|
||||||
from calibre.gui2.tweak_book.editor.text import PlainTextEdit
|
from calibre.gui2.tweak_book.editor.snippets import find_matching_snip, parse_template, string_length, SnippetTextEdit
|
||||||
from calibre.gui2.tweak_book.editor.snippets import find_matching_snip, parse_template, string_length, SnippetManager
|
|
||||||
|
|
||||||
from calibre.utils.icu import primary_contains
|
from calibre.utils.icu import primary_contains
|
||||||
|
|
||||||
@ -53,19 +52,6 @@ class AnimatablePushButton(QPushButton):
|
|||||||
self.setDown(False)
|
self.setDown(False)
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
class TextEdit(PlainTextEdit):
|
|
||||||
|
|
||||||
def __init__(self, text, parent=None):
|
|
||||||
PlainTextEdit.__init__(self, parent)
|
|
||||||
if text:
|
|
||||||
self.setPlainText(text)
|
|
||||||
self.snippet_manager = SnippetManager(self)
|
|
||||||
|
|
||||||
def keyPressEvent(self, ev):
|
|
||||||
if self.snippet_manager.handle_key_press(ev):
|
|
||||||
return
|
|
||||||
PlainTextEdit.keyPressEvent(self, ev)
|
|
||||||
|
|
||||||
class PushButton(AnimatablePushButton):
|
class PushButton(AnimatablePushButton):
|
||||||
|
|
||||||
def __init__(self, text, action, parent):
|
def __init__(self, text, action, parent):
|
||||||
@ -594,12 +580,12 @@ class EditSearch(QFrame): # {{{
|
|||||||
h.addWidget(la), h.addWidget(n)
|
h.addWidget(la), h.addWidget(n)
|
||||||
l.addLayout(h)
|
l.addLayout(h)
|
||||||
|
|
||||||
self.find = f = TextEdit('', self)
|
self.find = f = SnippetTextEdit('', self)
|
||||||
self.la2 = la = QLabel(_('&Find:'))
|
self.la2 = la = QLabel(_('&Find:'))
|
||||||
la.setBuddy(f)
|
la.setBuddy(f)
|
||||||
l.addWidget(la), l.addWidget(f)
|
l.addWidget(la), l.addWidget(f)
|
||||||
|
|
||||||
self.replace = r = TextEdit('', self)
|
self.replace = r = SnippetTextEdit('', self)
|
||||||
self.la3 = la = QLabel(_('&Replace:'))
|
self.la3 = la = QLabel(_('&Replace:'))
|
||||||
la.setBuddy(r)
|
la.setBuddy(r)
|
||||||
l.addWidget(la), l.addWidget(r)
|
l.addWidget(la), l.addWidget(r)
|
||||||
|
@ -6,7 +6,7 @@ from __future__ import (unicode_literals, division, absolute_import,
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2014, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
|
|
||||||
import os, textwrap
|
import os, textwrap, unicodedata
|
||||||
from itertools import izip
|
from itertools import izip
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ from PyQt5.Qt import (
|
|||||||
QPainter, QStaticText, pyqtSignal, QTextOption, QAbstractListModel,
|
QPainter, QStaticText, pyqtSignal, QTextOption, QAbstractListModel,
|
||||||
QModelIndex, QStyledItemDelegate, QStyle, QCheckBox, QListView,
|
QModelIndex, QStyledItemDelegate, QStyle, QCheckBox, QListView,
|
||||||
QTextDocument, QSize, QComboBox, QFrame, QCursor, QGroupBox, QSplitter,
|
QTextDocument, QSize, QComboBox, QFrame, QCursor, QGroupBox, QSplitter,
|
||||||
QPixmap, QRect)
|
QPixmap, QRect, QPlainTextEdit, pyqtSlot, QMimeData, QKeySequence)
|
||||||
|
|
||||||
from calibre import prepare_string_for_xml, human_readable
|
from calibre import prepare_string_for_xml, human_readable
|
||||||
from calibre.ebooks.oeb.polish.utils import lead_text, guess_type
|
from calibre.ebooks.oeb.polish.utils import lead_text, guess_type
|
||||||
@ -28,6 +28,7 @@ from calibre.utils.matcher import get_char, Matcher
|
|||||||
from calibre.gui2.complete2 import EditWithComplete
|
from calibre.gui2.complete2 import EditWithComplete
|
||||||
|
|
||||||
ROOT = QModelIndex()
|
ROOT = QModelIndex()
|
||||||
|
PARAGRAPH_SEPARATOR = '\u2029'
|
||||||
|
|
||||||
class BusyCursor(object):
|
class BusyCursor(object):
|
||||||
|
|
||||||
@ -1111,6 +1112,68 @@ class AddCover(Dialog):
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
class PlainTextEdit(QPlainTextEdit): # {{{
|
||||||
|
|
||||||
|
''' A class that overrides some methods from QPlainTextEdit to fix handling
|
||||||
|
of the nbsp unicode character. '''
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
QPlainTextEdit.__init__(self, parent)
|
||||||
|
self.selectionChanged.connect(self.selection_changed)
|
||||||
|
self.syntax = None
|
||||||
|
|
||||||
|
def toPlainText(self):
|
||||||
|
# QPlainTextEdit's toPlainText implementation replaces nbsp with normal
|
||||||
|
# space, so we re-implement it using QTextCursor, which does not do
|
||||||
|
# that
|
||||||
|
c = self.textCursor()
|
||||||
|
c.clearSelection()
|
||||||
|
c.movePosition(c.Start)
|
||||||
|
c.movePosition(c.End, c.KeepAnchor)
|
||||||
|
ans = c.selectedText().replace(PARAGRAPH_SEPARATOR, '\n')
|
||||||
|
# QTextCursor pads the return value of selectedText with null bytes if
|
||||||
|
# non BMP characters such as 0x1f431 are present.
|
||||||
|
return ans.rstrip('\0')
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def copy(self):
|
||||||
|
# Workaround Qt replacing nbsp with normal spaces on copy
|
||||||
|
c = self.textCursor()
|
||||||
|
if not c.hasSelection():
|
||||||
|
return
|
||||||
|
md = QMimeData()
|
||||||
|
md.setText(self.selected_text)
|
||||||
|
QApplication.clipboard().setMimeData(md)
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def cut(self):
|
||||||
|
# Workaround Qt replacing nbsp with normal spaces on copy
|
||||||
|
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 self.selected_text_from_cursor(self.textCursor())
|
||||||
|
|
||||||
|
def selection_changed(self):
|
||||||
|
# Workaround Qt replacing nbsp with normal spaces on copy
|
||||||
|
clipboard = QApplication.clipboard()
|
||||||
|
if clipboard.supportsSelection() and self.textCursor().hasSelection():
|
||||||
|
md = QMimeData()
|
||||||
|
md.setText(self.selected_text)
|
||||||
|
clipboard.setMimeData(md, clipboard.Selection)
|
||||||
|
|
||||||
|
def event(self, ev):
|
||||||
|
if ev.type() == ev.ShortcutOverride and ev in (QKeySequence.Copy, QKeySequence.Cut):
|
||||||
|
ev.accept()
|
||||||
|
(self.copy if ev == QKeySequence.Copy else self.cut)()
|
||||||
|
return True
|
||||||
|
return QPlainTextEdit.event(self, ev)
|
||||||
|
# }}}
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = QApplication([])
|
app = QApplication([])
|
||||||
AddCover.test()
|
AddCover.test()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user