mirror of
https://github.com/wassname/FanFicFare.git
synced 2026-09-11 11:52:07 +08:00
WIP - ini edit, error check and syntax highlighting.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
from __future__ import (unicode_literals, division,
|
||||
print_function)
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2014, Jim Miller'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import re
|
||||
|
||||
try:
|
||||
from PyQt5.Qt import (Qt, QSyntaxHighlighter, QTextCharFormat, QBrush)
|
||||
except ImportError as e:
|
||||
from PyQt4.Qt import (Qt, QSyntaxHighlighter, QTextCharFormat, QBrush)
|
||||
|
||||
class BasicIniHighlighter(QSyntaxHighlighter):
|
||||
'''
|
||||
QSyntaxHighlighter class for use with QTextEdit for highlighting
|
||||
ini config files.
|
||||
|
||||
I looked high and low to find a high lighter for basic ini config
|
||||
format, so I'm leaving this in the project even though I'm not
|
||||
using.
|
||||
'''
|
||||
|
||||
def __init__( self, parent, theme ):
|
||||
QSyntaxHighlighter.__init__( self, parent )
|
||||
self.parent = parent
|
||||
|
||||
self.highlightingRules = []
|
||||
|
||||
# keyword
|
||||
self.highlightingRules.append( HighlightingRule( r"^[^:=\s][^:=]*[:=]",
|
||||
Qt.blue,
|
||||
Qt.SolidPattern ) )
|
||||
|
||||
# section
|
||||
self.highlightingRules.append( HighlightingRule( r"^\[[^\]]+\]",
|
||||
Qt.darkBlue,
|
||||
Qt.SolidPattern ) )
|
||||
|
||||
# comment
|
||||
self.highlightingRules.append( HighlightingRule( r"#[^\n]*" ,
|
||||
Qt.darkYellow,
|
||||
Qt.SolidPattern ) )
|
||||
|
||||
def highlightBlock( self, text ):
|
||||
for rule in self.highlightingRules:
|
||||
for match in rule.pattern.finditer(text):
|
||||
self.setFormat( match.start(), match.end()-match.start(), rule.highlight )
|
||||
self.setCurrentBlockState( 0 )
|
||||
|
||||
class HighlightingRule():
|
||||
def __init__( self, pattern, color, style ):
|
||||
if isinstance(pattern,basestring):
|
||||
self.pattern = re.compile(pattern)
|
||||
else:
|
||||
self.pattern=pattern
|
||||
charfmt = QTextCharFormat()
|
||||
brush = QBrush(color, style)
|
||||
charfmt.setForeground(brush)
|
||||
self.highlight = charfmt
|
||||
|
||||
@@ -13,8 +13,6 @@ logger = logging.getLogger(__name__)
|
||||
import traceback, copy, threading
|
||||
from collections import OrderedDict
|
||||
|
||||
from ConfigParser import ParsingError
|
||||
|
||||
try:
|
||||
from PyQt5.Qt import (QDialog, QWidget, QVBoxLayout, QHBoxLayout, QLabel,
|
||||
QLineEdit, QFont, QWidget, QTextEdit, QComboBox,
|
||||
@@ -75,7 +73,7 @@ no_trans = { 'pini':'personal.ini',
|
||||
from calibre_plugins.fanfictiondownloader_plugin.prefs import prefs, PREFS_NAMESPACE
|
||||
from calibre_plugins.fanfictiondownloader_plugin.dialogs \
|
||||
import (UPDATE, UPDATEALWAYS, collision_order, save_collisions, RejectListDialog,
|
||||
EditTextDialog, RejectUrlEntry, errors_dialog)
|
||||
EditTextDialog, IniTextDialog, RejectUrlEntry, errors_dialog)
|
||||
|
||||
from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.adapters \
|
||||
import getConfigSections
|
||||
@@ -83,7 +81,8 @@ from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.adapters \
|
||||
from calibre_plugins.fanfictiondownloader_plugin.common_utils \
|
||||
import ( KeyboardConfigDialog, PrefsViewerDialog )
|
||||
|
||||
from calibre_plugins.fanfictiondownloader_plugin.ffdl_util import (get_ffdl_config)
|
||||
from calibre_plugins.fanfictiondownloader_plugin.ffdl_util \
|
||||
import (test_config)
|
||||
|
||||
from calibre.gui2.complete2 import EditWithComplete #MultiCompleteLineEdit
|
||||
|
||||
@@ -566,8 +565,7 @@ class BasicTab(QWidget):
|
||||
title=_("Reject Reasons"),
|
||||
label=_("Customize Reject List Reasons"),
|
||||
tooltip=_("Customize the Reasons presented when Rejecting URLs"),
|
||||
save_size_name='ffdl:Reject List Reasons',
|
||||
use_find=True)
|
||||
save_size_name='ffdl:Reject List Reasons')
|
||||
d.exec_()
|
||||
if d.result() == d.Accepted:
|
||||
prefs['rejectreasons'] = d.get_plain_text()
|
||||
@@ -632,7 +630,7 @@ class PersonalIniTab(QWidget):
|
||||
# let edit box fill the space.
|
||||
|
||||
def show_defaults(self):
|
||||
EditTextDialog(self,
|
||||
IniTextDialog(self,
|
||||
get_resources('plugin-defaults.ini'),
|
||||
icon=self.windowIcon(),
|
||||
title=_('Plugin Defaults'),
|
||||
@@ -643,7 +641,7 @@ class PersonalIniTab(QWidget):
|
||||
save_size_name='ffdl:defaults.ini').exec_()
|
||||
|
||||
def add_ini_button(self):
|
||||
d = EditTextDialog(self,
|
||||
d = IniTextDialog(self,
|
||||
self.personalini,
|
||||
icon=self.windowIcon(),
|
||||
title=_("Edit personal.ini"),
|
||||
@@ -658,13 +656,7 @@ class PersonalIniTab(QWidget):
|
||||
if d.result() == d.Accepted:
|
||||
self.personalini = unicode(d.get_plain_text())
|
||||
|
||||
try:
|
||||
configini = get_ffdl_config("test1.com?sid=555",
|
||||
personalini=self.personalini)
|
||||
|
||||
errors = configini.test_config()
|
||||
except ParsingError as pe:
|
||||
errors = pe.errors
|
||||
errors = test_config(self.personalini)
|
||||
|
||||
if errors:
|
||||
error = not errors_dialog(self.plugin_action.gui,
|
||||
|
||||
+75
-147
@@ -7,9 +7,6 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2014, Jim Miller'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
import traceback, re
|
||||
from functools import partial
|
||||
|
||||
@@ -28,8 +25,7 @@ try:
|
||||
QPushButton, QFont, QLabel, QCheckBox, QIcon, QLineEdit,
|
||||
QComboBox, QProgressDialog, QTimer, QDialogButtonBox,
|
||||
QPixmap, Qt, QAbstractItemView, QTextEdit, pyqtSignal,
|
||||
QGroupBox, QFrame, QTextBrowser, QSize, QAction,
|
||||
QSyntaxHighlighter, QTextCharFormat, QBrush )
|
||||
QGroupBox, QFrame, QTextBrowser, QSize, QAction)
|
||||
except ImportError as e:
|
||||
from PyQt4 import QtGui
|
||||
from PyQt4 import QtCore
|
||||
@@ -37,8 +33,7 @@ except ImportError as e:
|
||||
QPushButton, QFont, QLabel, QCheckBox, QIcon, QLineEdit,
|
||||
QComboBox, QProgressDialog, QTimer, QDialogButtonBox,
|
||||
QPixmap, Qt, QAbstractItemView, QTextEdit, pyqtSignal,
|
||||
QGroupBox, QFrame, QTextBrowser, QSize, QAction, QtCore,
|
||||
QSyntaxHighlighter, QTextCharFormat, QBrush )
|
||||
QGroupBox, QFrame, QTextBrowser, QSize, QAction)
|
||||
|
||||
try:
|
||||
from calibre.gui2 import QVariant
|
||||
@@ -72,6 +67,12 @@ from calibre_plugins.fanfictiondownloader_plugin.common_utils \
|
||||
from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.geturls import get_urls_from_html, get_urls_from_text
|
||||
from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.adapters import getNormalStoryURL
|
||||
|
||||
from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.configurable \
|
||||
import (get_valid_sections, get_valid_entries,
|
||||
get_valid_keywords, get_valid_entry_keywords)
|
||||
|
||||
from inihighlighter import IniHighlighter
|
||||
|
||||
SKIP=_('Skip')
|
||||
ADDNEW=_('Add New Book')
|
||||
UPDATE=_('Update EPUB if New Chapters')
|
||||
@@ -1120,15 +1121,73 @@ class EditTextDialog(SizePersistedDialog):
|
||||
def __init__(self, parent, text,
|
||||
icon=None, title=None, label=None, tooltip=None,
|
||||
rejectreasons=[],reasonslabel=None,
|
||||
save_size_name='ffdl:edit text dialog',
|
||||
):
|
||||
SizePersistedDialog.__init__(self, parent, save_size_name)
|
||||
|
||||
self.l = QVBoxLayout()
|
||||
self.setLayout(self.l)
|
||||
self.label = QLabel(label)
|
||||
if title:
|
||||
self.setWindowTitle(title)
|
||||
if icon:
|
||||
self.setWindowIcon(icon)
|
||||
self.l.addWidget(self.label)
|
||||
|
||||
self.textedit = QTextEdit(self)
|
||||
self.textedit.setLineWrapMode(QTextEdit.NoWrap)
|
||||
self.textedit.setText(text)
|
||||
self.l.addWidget(self.textedit)
|
||||
|
||||
if tooltip:
|
||||
self.label.setToolTip(tooltip)
|
||||
self.textedit.setToolTip(tooltip)
|
||||
|
||||
if rejectreasons or reasonslabel:
|
||||
self.reason_edit = EditWithComplete(self,sort_func=lambda x:1)
|
||||
|
||||
items = ['']+rejectreasons
|
||||
self.reason_edit.update_items_cache(items)
|
||||
self.reason_edit.show_initial_value('')
|
||||
self.reason_edit.set_separator(None)
|
||||
self.reason_edit.setToolTip(reasonslabel)
|
||||
|
||||
if reasonslabel:
|
||||
horz = QHBoxLayout()
|
||||
label = QLabel(reasonslabel)
|
||||
label.setToolTip(reasonslabel)
|
||||
horz.addWidget(label)
|
||||
horz.addWidget(self.reason_edit)
|
||||
self.l.addLayout(horz)
|
||||
else:
|
||||
self.l.addWidget(self.reason_edit)
|
||||
|
||||
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
button_box.accepted.connect(self.accept)
|
||||
button_box.rejected.connect(self.reject)
|
||||
self.l.addWidget(button_box)
|
||||
|
||||
# Cause our dialog size to be restored from prefs or created on first usage
|
||||
self.resize_dialog()
|
||||
|
||||
def get_plain_text(self):
|
||||
return unicode(self.textedit.toPlainText())
|
||||
|
||||
def get_reason_text(self):
|
||||
return unicode(self.reason_edit.currentText()).strip()
|
||||
|
||||
class IniTextDialog(SizePersistedDialog):
|
||||
|
||||
def __init__(self, parent, text,
|
||||
icon=None, title=None, label=None, tooltip=None,
|
||||
use_find=False,
|
||||
read_only=False,
|
||||
save_size_name='ffdl:edit text dialog',
|
||||
save_size_name='ffdl:ini text dialog',
|
||||
):
|
||||
SizePersistedDialog.__init__(self, parent, save_size_name)
|
||||
|
||||
self.keys=dict()
|
||||
|
||||
#self.resize(600, 500)
|
||||
self.l = QVBoxLayout()
|
||||
self.setLayout(self.l)
|
||||
self.label = QLabel(label)
|
||||
@@ -1140,7 +1199,12 @@ class EditTextDialog(SizePersistedDialog):
|
||||
|
||||
self.textedit = QTextEdit(self)
|
||||
|
||||
highlighter = IniHighlighter(self.textedit, "Classic")
|
||||
highlighter = IniHighlighter(self.textedit,
|
||||
sections=get_valid_sections(),
|
||||
keywords=get_valid_keywords(),
|
||||
entries=get_valid_entries(),
|
||||
entry_keywords=get_valid_entry_keywords(),
|
||||
)
|
||||
|
||||
self.textedit.setLineWrapMode(QTextEdit.NoWrap)
|
||||
try:
|
||||
@@ -1193,25 +1257,6 @@ class EditTextDialog(SizePersistedDialog):
|
||||
self.label.setToolTip(tooltip)
|
||||
self.textedit.setToolTip(tooltip)
|
||||
|
||||
if rejectreasons or reasonslabel:
|
||||
self.reason_edit = EditWithComplete(self,sort_func=lambda x:1)
|
||||
|
||||
items = ['']+rejectreasons
|
||||
self.reason_edit.update_items_cache(items)
|
||||
self.reason_edit.show_initial_value('')
|
||||
self.reason_edit.set_separator(None)
|
||||
self.reason_edit.setToolTip(reasonslabel)
|
||||
|
||||
if reasonslabel:
|
||||
horz = QHBoxLayout()
|
||||
label = QLabel(reasonslabel)
|
||||
label.setToolTip(reasonslabel)
|
||||
horz.addWidget(label)
|
||||
horz.addWidget(self.reason_edit)
|
||||
self.l.addLayout(horz)
|
||||
else:
|
||||
self.l.addWidget(self.reason_edit)
|
||||
|
||||
button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
||||
button_box.accepted.connect(self.accept)
|
||||
button_box.rejected.connect(self.reject)
|
||||
@@ -1238,9 +1283,6 @@ class EditTextDialog(SizePersistedDialog):
|
||||
def get_plain_text(self):
|
||||
return unicode(self.textedit.toPlainText())
|
||||
|
||||
def get_reason_text(self):
|
||||
return unicode(self.reason_edit.currentText()).strip()
|
||||
|
||||
def findFocus(self):
|
||||
# print("findFocus called")
|
||||
self.findField.setFocus()
|
||||
@@ -1248,7 +1290,7 @@ class EditTextDialog(SizePersistedDialog):
|
||||
|
||||
def find(self):
|
||||
|
||||
print("find self.lastStart:%s"%self.lastStart)
|
||||
#print("find self.lastStart:%s"%self.lastStart)
|
||||
|
||||
# Grab the parent's text
|
||||
text = self.textedit.toPlainText()
|
||||
@@ -1328,117 +1370,3 @@ class ViewLog(QDialog):
|
||||
txt = self.tb.toPlainText()
|
||||
QApplication.clipboard().setText(txt)
|
||||
|
||||
class IniHighlighter(QSyntaxHighlighter):
|
||||
|
||||
def __init__( self, parent, theme ):
|
||||
QSyntaxHighlighter.__init__( self, parent )
|
||||
self.parent = parent
|
||||
keyword = QTextCharFormat()
|
||||
reservedClasses = QTextCharFormat()
|
||||
assignmentOperator = QTextCharFormat()
|
||||
delimiter = QTextCharFormat()
|
||||
specialConstant = QTextCharFormat()
|
||||
boolean = QTextCharFormat()
|
||||
number = QTextCharFormat()
|
||||
comment = QTextCharFormat()
|
||||
string = QTextCharFormat()
|
||||
singleQuotedString = QTextCharFormat()
|
||||
|
||||
self.highlightingRules = []
|
||||
|
||||
# # keyword
|
||||
# brush = QBrush( Qt.darkBlue, Qt.SolidPattern )
|
||||
# keyword.setForeground( brush )
|
||||
# keyword.setFontWeight( QFont.Bold )
|
||||
# keywords = [ "break", "else", "for", "if", "in",
|
||||
# "next", "repeat", "return", "switch",
|
||||
# "try", "while" ]
|
||||
# for word in keywords:
|
||||
# pattern = "\\b" + word + "\\b"
|
||||
# rule = HighlightingRule( pattern, keyword )
|
||||
# self.highlightingRules.append( rule )
|
||||
|
||||
# # reservedClasses
|
||||
# reservedClasses.setForeground( brush )
|
||||
# reservedClasses.setFontWeight( QFont.Bold )
|
||||
# keywords = [ "array", "character", "complex",
|
||||
# "data.frame", "double", "factor",
|
||||
# "function", "integer", "list",
|
||||
# "logical", "matrix", "numeric",
|
||||
# "vector" ]
|
||||
# for word in keywords:
|
||||
# pattern = "\\b" + word + "\\b"
|
||||
# rule = HighlightingRule( pattern, reservedClasses )
|
||||
# self.highlightingRules.append( rule )
|
||||
|
||||
# # assignmentOperator
|
||||
# brush = QBrush( Qt.yellow, Qt.SolidPattern )
|
||||
# pattern = "(<){1,2}-"
|
||||
# assignmentOperator.setForeground( brush )
|
||||
# assignmentOperator.setFontWeight( QFont.Bold )
|
||||
# rule = HighlightingRule( pattern, assignmentOperator )
|
||||
# self.highlightingRules.append( rule )
|
||||
|
||||
# section
|
||||
pattern = r"^\[[^\]]+\]"
|
||||
brush = QBrush( Qt.darkBlue, Qt.SolidPattern )
|
||||
delimiter.setForeground( brush )
|
||||
delimiter.setFontWeight( QFont.Bold )
|
||||
rule = HighlightingRule( pattern, delimiter )
|
||||
self.highlightingRules.append( rule )
|
||||
|
||||
# # specialConstant
|
||||
# brush = QBrush( Qt.green, Qt.SolidPattern )
|
||||
# specialConstant.setForeground( brush )
|
||||
# keywords = [ "Inf", "NA", "NaN", "NULL" ]
|
||||
# for word in keywords:
|
||||
# pattern = "\\b" + word + "\\b"
|
||||
# rule = HighlightingRule( pattern, specialConstant )
|
||||
# self.highlightingRules.append( rule )
|
||||
|
||||
# boolean, case insensitive
|
||||
boolean.setForeground( brush )
|
||||
pattern = r"\b(true|false)\b"
|
||||
rule = HighlightingRule( pattern, boolean )
|
||||
self.highlightingRules.append( rule )
|
||||
|
||||
# # number
|
||||
# pattern = "[-+]?[0-9]*\.?[0-9]+?([eE][-+]?[0-9]+?)?"
|
||||
# number.setForeground( brush )
|
||||
# rule = HighlightingRule( pattern, number )
|
||||
# self.highlightingRules.append( rule )
|
||||
|
||||
# comment
|
||||
brush = QBrush( Qt.darkGray, Qt.SolidPattern )
|
||||
pattern = "#[^\n]*"
|
||||
comment.setForeground( brush )
|
||||
rule = HighlightingRule( pattern, comment )
|
||||
self.highlightingRules.append( rule )
|
||||
|
||||
# string
|
||||
brush = QBrush( Qt.red, Qt.SolidPattern )
|
||||
pattern = "\".*?\""
|
||||
string.setForeground( brush )
|
||||
rule = HighlightingRule( pattern, string )
|
||||
self.highlightingRules.append( rule )
|
||||
|
||||
# singleQuotedString
|
||||
pattern = "\'.*?\'"
|
||||
singleQuotedString.setForeground( brush )
|
||||
rule = HighlightingRule( pattern, singleQuotedString )
|
||||
self.highlightingRules.append( rule )
|
||||
|
||||
def highlightBlock( self, text ):
|
||||
for rule in self.highlightingRules:
|
||||
for match in rule.pattern.finditer(text):
|
||||
self.setFormat( match.start(), match.end()-match.start(), rule.format )
|
||||
self.setCurrentBlockState( 0 )
|
||||
|
||||
class HighlightingRule():
|
||||
def __init__( self, pattern, format ):
|
||||
if isinstance(pattern,basestring):
|
||||
self.pattern = re.compile(pattern)
|
||||
else:
|
||||
self.pattern=pattern
|
||||
self.format = format
|
||||
|
||||
|
||||
@@ -8,10 +8,11 @@ __copyright__ = '2013, Jim Miller'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
from StringIO import StringIO
|
||||
from ConfigParser import ParsingError
|
||||
|
||||
from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader import adapters, exceptions
|
||||
from calibre_plugins.fanfictiondownloader_plugin.fanficdownloader.configurable import Configuration
|
||||
from calibre_plugins.fanfictiondownloader_plugin.prefs import (prefs)
|
||||
from calibre_plugins.fanfictiondownloader_plugin.prefs import prefs
|
||||
|
||||
def get_ffdl_personalini():
|
||||
if prefs['includeimages']:
|
||||
@@ -40,4 +41,15 @@ def get_ffdl_config(url,fileform="epub",personalini=None):
|
||||
|
||||
def get_ffdl_adapter(url,fileform="epub",personalini=None):
|
||||
return adapters.getAdapter(get_ffdl_config(url,fileform,personalini),url)
|
||||
|
||||
def test_config(initext):
|
||||
|
||||
configini = get_ffdl_config("test1.com?sid=555",
|
||||
personalini=initext)
|
||||
try:
|
||||
errors = configini.test_config()
|
||||
except ParsingError as pe:
|
||||
errors = pe.errors
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
from __future__ import (unicode_literals, division,
|
||||
print_function)
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2014, Jim Miller'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import re
|
||||
|
||||
try:
|
||||
from PyQt5.Qt import (Qt, QSyntaxHighlighter, QTextCharFormat, QBrush, QFont)
|
||||
except ImportError as e:
|
||||
from PyQt4.Qt import (Qt, QSyntaxHighlighter, QTextCharFormat, QBrush, QFont)
|
||||
|
||||
# r'add_to_+key
|
||||
|
||||
|
||||
|
||||
class IniHighlighter(QSyntaxHighlighter):
|
||||
'''
|
||||
QSyntaxHighlighter class for use with QTextEdit for highlighting
|
||||
ini config files.
|
||||
'''
|
||||
|
||||
def __init__( self, parent, sections=[], keywords=[], entries=[], entry_keywords=[] ):
|
||||
QSyntaxHighlighter.__init__( self, parent )
|
||||
self.parent = parent
|
||||
|
||||
self.highlightingRules = []
|
||||
|
||||
# *all* keywords -- change known later.
|
||||
self.errorRule = HighlightingRule( r"^[^:=\s][^:=]*[:=]", Qt.red )
|
||||
self.highlightingRules.append( self.errorRule )
|
||||
|
||||
# *all* entry keywords -- change known later.
|
||||
reentrykeywords = r'('+(r'|'.join([ e % r'[a-zA-Z0-9_]+' for e in entry_keywords ]))+r')'
|
||||
self.highlightingRules.append( HighlightingRule( r"^(add_to_)?"+reentrykeywords+r"\s*[:=]", Qt.darkMagenta ) )
|
||||
|
||||
# true/false -- just to be nice.
|
||||
self.highlightingRules.append( HighlightingRule( r"\b(true|false)\b", Qt.darkGreen ) )
|
||||
|
||||
if entries:
|
||||
# *known* entries
|
||||
reentries = r'('+(r'|'.join(entries))+r')'
|
||||
self.highlightingRules.append( HighlightingRule( r"\b"+reentries+r"\b", Qt.darkGreen ) )
|
||||
|
||||
# *known* entry keywords
|
||||
reentrykeywords = r'('+(r'|'.join([ e % reentries for e in entry_keywords ]))+r')'
|
||||
self.highlightingRules.append( HighlightingRule( r"^(add_to_)?"+reentrykeywords+r"\s*[:=]", Qt.blue ) )
|
||||
|
||||
# *known* keywords
|
||||
rekeywords = r'('+(r'|'.join(keywords))+r')'
|
||||
self.highlightingRules.append( HighlightingRule( r"^(add_to_)?"+rekeywords+r"\s*[:=]", Qt.blue ) )
|
||||
|
||||
# *all* sections -- change known later.
|
||||
self.highlightingRules.append( HighlightingRule( r"^\[[^\]]+\].*?$", Qt.red, QFont.Bold, blocknum=1 ) )
|
||||
|
||||
if sections:
|
||||
# *known* sections
|
||||
resections = r'('+(r'|'.join(sections))+r')'
|
||||
resections = resections.replace('.','\.') #escape dots.
|
||||
self.highlightingRules.append( HighlightingRule( r"^\["+resections+r"\]\s*$", Qt.darkBlue, QFont.Bold, blocknum=2 ) )
|
||||
|
||||
# test story sections
|
||||
self.teststoryRule = HighlightingRule( r"^\[teststory:([0-9]+|defaults)\]", Qt.darkCyan, blocknum=3 )
|
||||
self.highlightingRules.append( self.teststoryRule )
|
||||
|
||||
# NOT comments -- but can be custom columns, so don't flag.
|
||||
#self.highlightingRules.append( HighlightingRule( r"(?<!^)#[^\n]*" , Qt.red ) )
|
||||
|
||||
# comments -- comments must start from column 0.
|
||||
self.commentRule = HighlightingRule( r"^#[^\n]*" , Qt.darkYellow )
|
||||
self.highlightingRules.append( self.commentRule )
|
||||
|
||||
def highlightBlock( self, text ):
|
||||
|
||||
is_comment = False
|
||||
blocknum = self.previousBlockState()
|
||||
for rule in self.highlightingRules:
|
||||
for match in rule.pattern.finditer(text):
|
||||
self.setFormat( match.start(), match.end()-match.start(), rule.highlight )
|
||||
if rule == self.commentRule:
|
||||
is_comment = True
|
||||
if rule.blocknum > 0:
|
||||
blocknum = rule.blocknum
|
||||
|
||||
if not is_comment:
|
||||
# unknown section, error all:
|
||||
if blocknum == 1 and blocknum == self.previousBlockState():
|
||||
self.setFormat( 0, len(text), self.errorRule.highlight )
|
||||
|
||||
# teststory section rules:
|
||||
if blocknum == 3:
|
||||
self.setFormat( 0, len(text), self.teststoryRule.highlight )
|
||||
|
||||
self.setCurrentBlockState( blocknum )
|
||||
|
||||
class HighlightingRule():
|
||||
def __init__( self, pattern, color,
|
||||
weight=QFont.Normal,
|
||||
style=Qt.SolidPattern,
|
||||
blocknum=0):
|
||||
if isinstance(pattern,basestring):
|
||||
self.pattern = re.compile(pattern)
|
||||
else:
|
||||
self.pattern=pattern
|
||||
charfmt = QTextCharFormat()
|
||||
brush = QBrush(color, style)
|
||||
charfmt.setForeground(brush)
|
||||
charfmt.setFontWeight(weight)
|
||||
self.highlight = charfmt
|
||||
self.blocknum=blocknum
|
||||
|
||||
Reference in New Issue
Block a user