# -*- 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)