QGIS/python/plugins/db_manager/highlighter.py
2013-06-09 18:51:47 +02:00

186 lines
5.4 KiB
Python

# -*- coding: utf-8 -*-
"""
/***************************************************************************
Name : DB Manager
Description : Database manager plugin for QGIS
Date : May 23, 2011
copyright : (C) 2011 by Giuseppe Sucameli
email : brush.tyler@gmail.com
The content of this file is based on
- Python Syntax Highlighting Example by Carson J. Q. Farmer (GPLv2 license)
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
"""
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class SqlHighlighter(QSyntaxHighlighter):
COLOR_KEYWORD = QColor(0x00,0x00,0xE6)
COLOR_FUNCTION = QColor(0xCE,0x7B,0x00)
COLOR_COMMENT = QColor(0x96,0x96,0x96)
COLOR_CONSTANT = Qt.magenta
COLOR_IDENTIFIER = QColor(0x00,0x99,0x00)
COLOR_PARAMETER = QColor(0x25,0x9D,0x9D)
def __init__(self, editor, db=None):
QSyntaxHighlighter.__init__(self, editor)
self.editor = editor
self.rules = []
self.styles = {}
# keyword
format = QTextCharFormat()
format.setForeground( QBrush(self.COLOR_KEYWORD, Qt.SolidPattern) )
#format.setFontWeight( QFont.Bold )
self.styles['keyword'] = format
# function and delimiter
format = QTextCharFormat()
format.setForeground( QBrush(self.COLOR_FUNCTION, Qt.SolidPattern) )
self.styles['function'] = format
self.styles['delimiter'] = format
# identifier
format = QTextCharFormat()
format.setForeground( QBrush(self.COLOR_IDENTIFIER, Qt.SolidPattern) )
self.styles['identifier'] = format
# comment
format = QTextCharFormat()
format.setForeground( QBrush(self.COLOR_COMMENT, Qt.SolidPattern) )
self.styles['comment'] = format
# constant (numbers, strings)
format = QTextCharFormat()
format.setForeground( QBrush(self.COLOR_CONSTANT, Qt.SolidPattern) )
self.styles['constant'] = format
if db:
self.load(db)
def highlightBlock(self, text):
index = 0
rule_sel = None
rule_index = -1
while index < len(text):
# search for the rule that matches starting from the less index
rule_sel = None
rule_index = -1
rule_length = 0
for rule in self.rules:
regex = rule.regex()
pos = regex.indexIn(text, index)
if pos >= 0:
if rule_sel == None or rule_index > pos:
rule_sel = rule
rule_index = pos
rule_length = len(regex.cap(0))
if rule_sel == None: # no rule matches
break
# apply the rule found before
self.setFormat(rule_index, rule_length, self.styles[rule_sel.type()])
index = rule_index + rule_length
self.setCurrentBlockState( 0 )
# handle with multiline comments
index = 0
if self.previousBlockState() != 1:
index = self.multiLineCommentStart.indexIn(text, index)
while index >= 0:
# if the last applied rule is a single-line comment,
# then avoid multiline comments that start after it
if rule_sel != None and rule_sel.type() == 'comment' and index >= rule_index:
break
pos = self.multiLineCommentEnd.indexIn(text, index)
comment_length = 0
if pos < 0:
self.setCurrentBlockState(1)
comment_length = len(text) - index;
else:
comment_length = pos - index + len(self.multiLineCommentEnd.cap(0))
self.setFormat(index, comment_length, self.styles['comment'])
index = self.multiLineCommentStart.indexIn(text, index + comment_length)
def load(self, db=None):
self.rules = []
rules = None
if db:
rules = db.connector.getSqlDictionary()
if not rules:
# use the generic sql dictionary
from .sql_dictionary import getSqlDictionary
rules = getSqlDictionary()
for name in self.styles.keys():
if not name in rules:
continue
for value in rules[name]:
regex = QRegExp( u"\\b%s\\b" % QRegExp.escape(value), Qt.CaseInsensitive )
rule = HighlightingRule(name, regex)
self.rules.append( rule )
# delimiter
regex = QRegExp( "[\)\(]" )
rule = HighlightingRule('delimiter', regex)
self.rules.append( rule )
# identifier
regex = QRegExp( r'"[^"\\]*(\\.[^"\\]*)*"' )
regex.setMinimal( True )
rule = HighlightingRule('identifier', regex)
self.rules.append( rule )
# constant (numbers, strings)
# string
regex = QRegExp( r"'[^'\\]*(\\.[^'\\]*)*'" )
regex.setMinimal( True )
rule = HighlightingRule('constant', regex)
self.rules.append( rule )
# number
regex = QRegExp( r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b' )
regex.setMinimal( True )
rule = HighlightingRule('constant', regex)
self.rules.append( rule )
# single-line comment
regex = QRegExp( "--.*$" )
rule = HighlightingRule('comment', regex)
self.rules.append( rule )
# multi-line comment
self.multiLineCommentStart = QRegExp( "/\\*" )
self.multiLineCommentEnd = QRegExp( "\\*/" )
class HighlightingRule:
def __init__(self, typ, regex):
self._type = typ
self._regex = regex
def type(self):
return self._type
def regex(self):
return QRegExp(self._regex)