class TextFilesProxyModel(QSortFilterProxyModel): def __init__(self, parent=None): super().__init__(parent) self._filter = QRegularExpression() def setFilter(self, filesFilter: QRegularExpression): if self._filter == filesFilter: return self._filter = filesFilter self.invalidateFilter() def setUseRegExp(self, useRegExp: bool): self._useRegExp = useRegExp self.invalidateFilter() def filterAcceptsRow(self, sourceRow: int, sourceParent: QModelIndex): if self._filter.pattern() == "": return True index: QModelIndex = self.sourceModel().index(sourceRow, 0, sourceParent) file: TextFile = self.sourceModel().data(index, Qt.UserRole).value() return file.contains(self._filter, self._useRegExp) def filteredFiles(self) -> List[TextFile]: files = [] for i in range(0, self.rowCount()): index: QModelIndex = self.mapToSource(self.index(i, 0, QModelIndex())) file: TextFile = self.sourceModel().data(index, Qt.UserRole).value() files.append(file) return files
def highlight(self, regex: QRegularExpression, color: QColor = QColor(Qt.yellow)): if regex.pattern() == "": return self.moveCursor(QTextCursor.Start) matches = [] it: QRegularExpressionMatchIterator = regex.globalMatch(self.toPlainText()) while it.hasNext(): match: QRegularExpressionMatch = it.next() if not match.hasMatch(): continue begin = match.capturedStart() end = match.capturedEnd() matchSelection: QTextEdit.ExtraSelection = QTextEdit.ExtraSelection() fmt: QTextCharFormat = matchSelection.format fmt.setBackground(color) matchSelection.cursor = self.textCursor() matchSelection.cursor.setPosition(begin, QTextCursor.MoveAnchor) matchSelection.cursor.setPosition(end, QTextCursor.KeepAnchor) matches.append(matchSelection) self.setExtraSelections(matches) self.moveCursor(QTextCursor.Start)
def contains(self, regex: QRegularExpression, useRegExp=True) -> bool: if useRegExp: match: QRegularExpressionMatch = regex.match(self._content) return match.hasMatch() else: return regex.pattern().lower() in self._contentLower
class SyntaxHighlighter(QSyntaxHighlighter): """ Syntax highlighter for python """ def __init__(self, parent: QTextDocument = None, *args, **kwargs): super().__init__(parent, *args, **kwargs) # private members self._comment_start_expression = None self._comment_end_expression = None self._keyword_format = QTextCharFormat() self._class_format = QTextCharFormat() self._single_line_comment_format = QTextCharFormat() self._multi_line_comment_format = QTextCharFormat() self._quotation_format = QTextCharFormat() self._function_format = QTextCharFormat() self._highlighting_rules = list() # highlighting rules self._keyword_format.setForeground(Qt.darkBlue) self._keyword_format.setFontWeight(QFont.Bold) keywords = [ 'class', 'def', 'return' 'self', 'float', 'int', 'list', 'dict', 'if', 'else', 'elif', 'pass', 'None', 'object', 'for', 'while', 'is', 'in', 'print', 'round', 'min', 'max', 'abs', 'lambda', 'import', 'as', 'from', 'and', 'or' ] keyword_patterns = ['\\b{}\\b'.format(keyword) for keyword in keywords] for pattern in keyword_patterns: rule = HighlightingRule() rule.pattern = QRegularExpression(pattern) rule.format = self._keyword_format self._highlighting_rules.append(rule) self._class_format.setFontWeight(QFont.Bold) self._class_format.setForeground(Qt.darkMagenta) rule = HighlightingRule() rule.pattern = QRegularExpression('\\bQ[A-Za-z+\\b]') rule.format = self._class_format self._highlighting_rules.append(rule) self._quotation_format.setFontWeight(QFont.Bold) self._quotation_format.setForeground(Qt.darkGreen) rule = HighlightingRule() rule.pattern = QRegularExpression('".*"') rule.format = self._quotation_format self._highlighting_rules.append(rule) rule = HighlightingRule() rule.pattern = QRegularExpression("'.*'") rule.format = self._quotation_format self._highlighting_rules.append(rule) self._function_format.setForeground(Qt.blue) rule = HighlightingRule() rule.pattern = QRegularExpression('\\b[A-Za-z0-9_]+(?=\\())') rule.format = self._function_format self._highlighting_rules.append(rule) self._single_line_comment_format.setForeground(Qt.gray) rule = HighlightingRule() rule.pattern = QRegularExpression('#[^\n]*') rule.format = self._single_line_comment_format self._highlighting_rules.append(rule) self._multi_line_comment_format.setForeground(Qt.gray) self._comment_start_expression = QRegularExpression('"""*') self._comment_end_expression = QRegularExpression('*"""') def highlightBlock(self, p_str): for rule in self._highlighting_rules: match_iterator = rule.pattern.globalMatch(p_str) while match_iterator.hasNext(): match = match_iterator.next() self.setFormat(match.capturedStart(), match.capturedLength(), rule.format) self.setCurrentBlockState(0) start_index = 0 if self.previousBlockState() != 1: start_index = index_in_str( p_str, self._comment_start_expression.pattern()) while start_index >= 0: match = self._comment_end_expression.match(p_str, start_index) end_index = match.capturedStart() comment_length = 0 if end_index == -1: self.setCurrentBlockState(1) comment_length = len(p_str) - start_index else: comment_length = end_index - start_index + match.capturedLength( ) self.setFormat(start_index, comment_length, self._multi_line_comment_format) start_index = index_in_str( p_str, self._comment_start_expression.pattern(), start_index + comment_length)
class CxxHighlighter(QSyntaxHighlighter): def __init__(self, parent): super().__init__(parent) self.rules = [] keywordFormat = QTextCharFormat() keywordFormat.setForeground(QColor("#0016ba")) keywordFormat.setFontWeight(QFont.Bold) keywordPatterns = [ "\\bchar\\b", "\\bclass\\b", "\\bconst\\b", "\\bdouble\\b", "\\benum\\b", "\\bexplicit\\b", "\\bfriend\\b", "\\binline\\b", "\\bint\\b", "\\blong\\b", "\\bnamespace\\b", "\\boperator\\b", "\\bprivate\\b", "\\bprotected\\b", "\\bpublic\\b", "\\bshort\\b", "\\bsignals\\b", "\\bsigned\\b", "\\bslots\\b", "\\bstatic\\b", "\\bstruct\\b", "\\btemplate\\b", "\\btypedef\\b", "\\btypename\\b", "\\bunion\\b", "\\bunsigned\\b", "\\bvirtual\\b", "\\bvoid\\b", "\\bvolatile\\b", "\\bbool\\b", "\\bchar8_t\\b", "\\bchar16_t\\b", "\\bchar32_t\\b", ] for pattern in keywordPatterns: rule = { 'pattern': QRegularExpression(pattern), 'format': keywordFormat } self.rules.append(rule) keyword2Format = QTextCharFormat() keyword2Format.setForeground(QColor("#0016ba")) keyword2Format.setFontWeight(QFont.Bold) keyword2Patterns = [ "\\balignas\\b", "\\balignof\\b", "\\band\\b", "\\band_eq\\b", "\\basm\\b", "\\batomic_cancel\\b", "\\batomic_commit\\b", "\\batomic_noexcept\\b", "\\bauto\\b", "\\bbitand\\b", "\\bbitor\\b", "\\bbreak\\b", "\\bcase\\b", "\\bcatch\\b", "\\bcompl\\b", "\\bconcept\\b", "\\bconsteval\\b", "\\bconstexpr\\b", "\\bconstinit\\b", "\\bconst_cast\\b", "\\bcontinue\\b", "\\bco_await\\b", "\\bco_return\\b", "\\bco_yield\\b", "\\bdecltype\\b", "\\bdefault\\b", ] for pattern in keyword2Patterns: rule = { 'pattern': QRegularExpression(pattern), 'format': keyword2Format } self.rules.append(rule) classFormat = QTextCharFormat() classFormat.setFontWeight(QFont.Bold) classFormat.setForeground(Qt.darkMagenta) rule = { 'pattern': QRegularExpression("\\bQ[A-Za-z]+\\b"), 'format': classFormat } self.rules.append(rule) quotationFormat = QTextCharFormat() quotationFormat.setForeground(QColor("#c90000")) rule = { 'pattern': QRegularExpression("\".*\""), 'format': quotationFormat } self.rules.append(rule) directiveFormat = QTextCharFormat() directiveFormat.setForeground(QColor("#c95508")) rule = { 'pattern': QRegularExpression("#.*"), 'format': directiveFormat } self.rules.append(rule) stdFormat = QTextCharFormat() stdFormat.setForeground(QColor("#8c8c8c")) rule = { 'pattern': QRegularExpression("std::[A-Za-z]+"), 'format': stdFormat } self.rules.append(rule) # functionFormat = QTextCharFormat() # functionFormat.setForeground(Qt.blue) # rule = {'pattern':QRegularExpression("\\b[A-Za-z0-9_]+(?=\\()"), # 'format':functionFormat} # self.rules.append(rule) singleLineCommentFormat = QTextCharFormat() singleLineCommentFormat.setForeground(Qt.darkGreen) rule = { 'pattern': QRegularExpression("//[^\n]*"), 'format': singleLineCommentFormat } self.rules.append(rule) self.multiLineCommentFormat = QTextCharFormat() self.multiLineCommentFormat.setForeground(Qt.red) self.commentStartExpression = QRegularExpression("/\\*") self.commentEndExpression = QRegularExpression("\\*/") def highlightBlock(self, text): for rule in self.rules: matchIter = rule['pattern'].globalMatch(text) while matchIter.hasNext(): match = matchIter.next() self.setFormat(match.capturedStart(), match.capturedLength(), rule['format']) self.setCurrentBlockState(0) startIdx = 0 if self.previousBlockState() != 1: startIdx = text.find(self.commentStartExpression.pattern()) while startIdx >= 0: match = self.commentEndExpression.match(text, startIdx) endIdx = match.capturedStart() commentLength = 0 if endIdx == -1: self.setCurrentBlockState(1) commentLength = len(text) - startIdx else: commentLength = endIdx - startIdx + match.capturedLength() self.setFormat(startIdx, commentLength, self.multiLineCommentFormat) startIdx = text.find(self.commentStartExpression.pattern(), start=startIdx + commentLength)