/highlighter.py
https://github.com/netconstructor/db_manager · Python · 182 lines · 109 code · 32 blank · 41 comment · 21 complexity · 205737c7246039261ce7d55c385d7264 MD5 · raw file
- # -*- coding: utf-8 -*-
- """
- /***************************************************************************
- Name : DB Manager
- Description : Database manager plugin for QuantumGIS
- 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
- Copyright (C) 2009 Carson J. Q. Farmer
- ***************************************************************************/
- /***************************************************************************
- * *
- * 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):
- 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
- def highlightBlock(self, text):
- text = text.toLower()
- index = 0
- rule_sel = None
- rule_index = -1
- while index < text.length():
- # 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 = regex.cap(0).length()
- 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 = text.length() - index;
- else:
- comment_length = pos - index + self.multiLineCommentEnd.cap(0).length()
- self.setFormat(index, comment_length, self.styles['comment'])
- index = self.multiLineCommentStart.indexIn(text, index + comment_length)
- def load(self, db=None):
- self.rules = []
- if False and db:
- rules = db.connector.getSqlDictionary()
- else:
- from .sql_dictionary import getSqlDictionary
- rules = getSqlDictionary( db.connection().typeName() if db else None )
- for name in self.styles.keys():
- if not rules.has_key(name):
- continue
- for value in rules[name]:
- regex = QRegExp( u"\\b%s\\b" % QRegExp.escape(value) )
- 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)