This commit is contained in:
Kovid Goyal 2021-11-11 08:57:49 +05:30
parent 7ac7932f39
commit add6a6e8d9
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 50 additions and 131 deletions

View File

@ -195,12 +195,17 @@ class Tester(Dialog): # {{{
DIALOG_TITLE = _('Test style transform rules') DIALOG_TITLE = _('Test style transform rules')
PREFS_NAME = 'test-style-transform-rules' PREFS_NAME = 'test-style-transform-rules'
LABEL = _('Enter a CSS stylesheet below to test') LABEL = _('Enter a CSS stylesheet below and click the "Test" button')
SYNTAX = 'css'
RESULTS = '/* %s */\n\n' % _('Resulting stylesheet')
def __init__(self, rules, parent=None): def __init__(self, rules, parent=None):
self.rules = compile_rules(rules) self.rules = self.compile_rules(rules)
Dialog.__init__(self, self.DIALOG_TITLE, self.PREFS_NAME, parent=parent) Dialog.__init__(self, self.DIALOG_TITLE, self.PREFS_NAME, parent=parent)
def compile_rules(self, rules):
return compile_rules(rules)
def setup_ui(self): def setup_ui(self):
from calibre.gui2.tweak_book.editor.text import TextEdit from calibre.gui2.tweak_book.editor.text import TextEdit
self.l = l = QVBoxLayout(self) self.l = l = QVBoxLayout(self)
@ -208,7 +213,7 @@ class Tester(Dialog): # {{{
self.la = la = QLabel(self.LABEL) self.la = la = QLabel(self.LABEL)
l.addWidget(la) l.addWidget(la)
self.css = t = TextEdit(self) self.css = t = TextEdit(self)
t.load_text('/* %s */\n' % _('Enter CSS rules below and click the "Test" button'), 'css') t.load_text('', self.SYNTAX)
la.setBuddy(t) la.setBuddy(t)
c = t.textCursor() c = t.textCursor()
c.movePosition(QTextCursor.MoveOperation.End) c.movePosition(QTextCursor.MoveOperation.End)
@ -234,7 +239,10 @@ class Tester(Dialog): # {{{
css = decl.cssText css = decl.cssText
if isinstance(css, bytes): if isinstance(css, bytes):
css = css.decode('utf-8') css = css.decode('utf-8')
self.result.load_text('/* %s */\n\n%s' % (_('Resulting stylesheet'), css), 'css') self.set_result(css)
def set_result(self, css):
self.result.load_text(self.RESULTS + css, self.SYNTAX)
def sizeHint(self): def sizeHint(self):
return QSize(800, 600) return QSize(800, 600)
@ -259,13 +267,20 @@ class RulesDialog(RulesDialogBase): # {{{
class RulesWidget(QWidget, SaveLoadMixin): # {{{ class RulesWidget(QWidget, SaveLoadMixin): # {{{
changed = pyqtSignal() changed = pyqtSignal()
PREFS_NAME = 'style-transform-rules'
INITIAL_FILE_NAME = 'css-rules.txt'
DIR_SAVE_NAME = 'export-style-transform-rules'
export_func = export_rules
import_func = import_rules
TesterClass = Tester
RulesClass = Rules
def __init__(self, parent=None): def __init__(self, parent=None):
self.loaded_ruleset = None self.loaded_ruleset = None
QWidget.__init__(self, parent) QWidget.__init__(self, parent)
self.PREFS_OBJECT = JSONConfig('style-transform-rules') self.PREFS_OBJECT = JSONConfig(self.PREFS_NAME)
l = QVBoxLayout(self) l = QVBoxLayout(self)
self.rules_widget = w = Rules(self) self.rules_widget = w = self.RulesClass(self)
w.changed.connect(self.changed.emit) w.changed.connect(self.changed.emit)
l.addWidget(w) l.addWidget(w)
self.h = h = QHBoxLayout() self.h = h = QHBoxLayout()
@ -286,7 +301,7 @@ class RulesWidget(QWidget, SaveLoadMixin): # {{{
b.setToolTip(_('Save this ruleset for later re-use')) b.setToolTip(_('Save this ruleset for later re-use'))
b.clicked.connect(self.save_ruleset) b.clicked.connect(self.save_ruleset)
h.addWidget(b) h.addWidget(b)
self.export_button = b = QPushButton(_('&Load'), self) self.load_button = b = QPushButton(_('&Load'), self)
self.load_menu = QMenu(self) self.load_menu = QMenu(self)
b.setMenu(self.load_menu) b.setMenu(self.load_menu)
b.setToolTip(_('Load a previously saved ruleset')) b.setToolTip(_('Load a previously saved ruleset'))
@ -299,17 +314,17 @@ class RulesWidget(QWidget, SaveLoadMixin): # {{{
if not rules: if not rules:
return error_dialog(self, _('No rules'), _( return error_dialog(self, _('No rules'), _(
'There are no rules to export'), show=True) 'There are no rules to export'), show=True)
path = choose_save_file(self, 'export-style-transform-rules', _('Choose file for exported rules'), initial_filename='rules.txt') path = choose_save_file(self, self.DIR_SAVE_NAME, _('Choose file for exported rules'), initial_filename=self.INITIAL_FILE_NAME)
if path: if path:
raw = export_rules(rules) raw = self.export_func(rules)
with open(path, 'wb') as f: with open(path, 'wb') as f:
f.write(raw) f.write(raw)
def import_rules(self): def import_rules(self):
paths = choose_files(self, 'export-style-transform-rules', _('Choose file to import rules from'), select_only_single_file=True) paths = choose_files(self, self.DIR_SAVE_NAME, _('Choose file to import rules from'), select_only_single_file=True)
if paths: if paths:
with open(paths[0], 'rb') as f: with open(paths[0], 'rb') as f:
rules = import_rules(f.read()) rules = self.import_func(f.read())
self.rules_widget.rules = list(rules) + list(self.rules_widget.rules) self.rules_widget.rules = list(rules) + list(self.rules_widget.rules)
self.changed.emit() self.changed.emit()
@ -318,7 +333,7 @@ class RulesWidget(QWidget, SaveLoadMixin): # {{{
self.changed.emit() self.changed.emit()
def test_rules(self): def test_rules(self):
Tester(self.rules_widget.rules, self).exec_() self.TesterClass(self.rules_widget.rules, self).exec_()
@property @property
def rules(self): def rules(self):

View File

@ -4,9 +4,8 @@
from qt.core import ( from qt.core import (
QComboBox, QDialogButtonBox, QFrame, QHBoxLayout, QIcon, QLabel, QLineEdit, QComboBox, QFrame, QHBoxLayout, QIcon, QLabel, QLineEdit, QPushButton,
QMenu, QPushButton, QScrollArea, QSize, Qt, QTextCursor, QToolButton, QScrollArea, Qt, QToolButton, QVBoxLayout, QWidget, pyqtSignal
QVBoxLayout, QWidget, pyqtSignal
) )
from calibre import prepare_string_for_xml from calibre import prepare_string_for_xml
@ -14,18 +13,20 @@ from calibre.ebooks.html_transform_rules import (
ACTION_MAP, MATCH_TYPE_MAP, export_rules, import_rules, transform_html, ACTION_MAP, MATCH_TYPE_MAP, export_rules, import_rules, transform_html,
validate_rule validate_rule
) )
from calibre.gui2 import choose_files, choose_save_file, elided_text, error_dialog from calibre.gui2 import elided_text, error_dialog
from calibre.gui2.convert.xpath_wizard import XPathEdit from calibre.gui2.convert.xpath_wizard import XPathEdit
from calibre.gui2.css_transform_rules import (
RulesWidget as RulesWidgetBase, Tester as TesterBase
)
from calibre.gui2.tag_mapper import ( from calibre.gui2.tag_mapper import (
RuleEditDialog as RuleEditDialogBase, RuleItem as RuleItemBase, RuleEditDialog as RuleEditDialogBase, RuleItem as RuleItemBase,
Rules as RulesBase, RulesDialog as RulesDialogBase, SaveLoadMixin Rules as RulesBase, RulesDialog as RulesDialogBase
) )
from calibre.gui2.widgets2 import Dialog
from calibre.utils.config import JSONConfig from calibre.utils.config import JSONConfig
# Classes for rule edit widget {{{ # Classes for rule edit widget {{{
class TagAction(QWidget): class TagAction(QWidget):
remove_action = pyqtSignal(object) remove_action = pyqtSignal(object)
@ -312,49 +313,20 @@ class Rules(RulesBase): # {{{
# }}} # }}}
class Tester(Dialog): # {{{ class Tester(TesterBase): # {{{
DIALOG_TITLE = _('Test HTML transform rules') DIALOG_TITLE = _('Test HTML transform rules')
PREFS_NAME = 'test-html-transform-rules' PREFS_NAME = 'test-html-transform-rules'
LABEL = _('Enter an HTML document below to test') LABEL = _('Enter an HTML document below and click the "Test" button')
SYNTAX = 'html'
RESULTS = '<!-- %s -->\n\n' % _('Resulting HTML')
def __init__(self, rules, parent=None): def compile_rules(self, rules):
self.rules = rules return rules
Dialog.__init__(self, self.DIALOG_TITLE, self.PREFS_NAME, parent=parent)
def setup_ui(self):
from calibre.gui2.tweak_book.editor.text import TextEdit
self.l = l = QVBoxLayout(self)
self.bb.setStandardButtons(QDialogButtonBox.StandardButton.Close)
self.la = la = QLabel(self.LABEL)
l.addWidget(la)
self.html = t = TextEdit(self)
t.load_text('<!-- %s -->\n' % _('Enter the HTML below and click the "Test" button'), 'html')
la.setBuddy(t)
c = t.textCursor()
c.movePosition(QTextCursor.MoveOperation.End)
t.setTextCursor(c)
self.h = h = QHBoxLayout()
l.addLayout(h)
h.addWidget(t)
self.test_button = b = QPushButton(_('&Test'), self)
b.clicked.connect(self.do_test)
h.addWidget(b)
self.result = la = TextEdit(self)
la.setReadOnly(True)
l.addWidget(la)
l.addWidget(self.bb)
@property
def value(self):
return self.html.toPlainText()
def do_test(self): def do_test(self):
changed, html = transform_html('\n' + self.value + '\n', self.rules) changed, html = transform_html('\n' + self.value + '\n', self.rules)
self.result.load_text('<!-- %s -->\n\n%s' % (_('Resulting HTML'), html), 'html') self.set_result(html)
def sizeHint(self):
return QSize(800, 600)
# }}} # }}}
@ -373,82 +345,14 @@ class RulesDialog(RulesDialogBase): # {{{
# }}} # }}}
class RulesWidget(QWidget, SaveLoadMixin): # {{{ class RulesWidget(RulesWidgetBase): # {{{
PREFS_NAME = 'html-transform-rules'
changed = pyqtSignal() INITIAL_FILE_NAME = 'html-rules.txt'
DIR_SAVE_NAME = 'export-html-transform-rules'
def __init__(self, parent=None): export_func = export_rules
self.loaded_ruleset = None import_func = import_rules
QWidget.__init__(self, parent) TesterClass = Tester
self.PREFS_OBJECT = JSONConfig('html-transform-rules') RulesClass = Rules
l = QVBoxLayout(self)
self.rules_widget = w = Rules(self)
w.changed.connect(self.changed.emit)
l.addWidget(w)
self.h = h = QHBoxLayout()
l.addLayout(h)
self.export_button = b = QPushButton(_('E&xport'), self)
b.setToolTip(_('Export these rules to a file'))
b.clicked.connect(self.export_rules)
h.addWidget(b)
self.import_button = b = QPushButton(_('&Import'), self)
b.setToolTip(_('Import previously exported rules'))
b.clicked.connect(self.import_rules)
h.addWidget(b)
self.test_button = b = QPushButton(_('&Test rules'), self)
b.clicked.connect(self.test_rules)
h.addWidget(b)
h.addStretch(10)
self.save_button = b = QPushButton(_('&Save'), self)
b.setToolTip(_('Save this ruleset for later re-use'))
b.clicked.connect(self.save_ruleset)
h.addWidget(b)
self.export_button = b = QPushButton(_('&Load'), self)
self.load_menu = QMenu(self)
b.setMenu(self.load_menu)
b.setToolTip(_('Load a previously saved ruleset'))
b.clicked.connect(self.load_ruleset)
h.addWidget(b)
self.build_load_menu()
def export_rules(self):
rules = self.rules_widget.rules
if not rules:
return error_dialog(self, _('No rules'), _(
'There are no rules to export'), show=True)
path = choose_save_file(self, 'export-html-transform-rules', _('Choose file for exported rules'), initial_filename='html-rules.json')
if path:
raw = export_rules(rules)
with open(path, 'wb') as f:
f.write(raw)
def import_rules(self):
paths = choose_files(self, 'export-html-transform-rules', _('Choose file to import rules from'), select_only_single_file=True)
if paths:
with open(paths[0], 'rb') as f:
rules = import_rules(f.read())
self.rules_widget.rules = list(rules) + list(self.rules_widget.rules)
self.changed.emit()
def load_ruleset(self, name):
SaveLoadMixin.load_ruleset(self, name)
self.changed.emit()
def test_rules(self):
Tester(self.rules_widget.rules, self).exec_()
@property
def rules(self):
return self.rules_widget.rules
@rules.setter
def rules(self, val):
try:
self.rules_widget.rules = val or []
except Exception:
import traceback
traceback.print_exc()
self.rules_widget.rules = []
# }}} # }}}