Package nukescripts :: Module blinkscripteditor
[hide private]
[frames] | no frames]

Source Code for Module nukescripts.blinkscripteditor

  1  import PySide2 
  2  import re, sys, traceback, os 
  3  import rlcompleter 
  4  from StringIO import StringIO 
  5  import nuke 
  6   
  7  #Syntax highlighting colour definitions 
  8  kwdsFgColour = PySide2.QtGui.QColor(122, 136, 53) 
  9  stringLiteralsFgColourDQ = PySide2.QtGui.QColor(226, 138, 138) 
 10  stringLiteralsFgColourSQ = PySide2.QtGui.QColor(110, 160, 121) 
 11  commentsFgColour = PySide2.QtGui.QColor(188, 179, 84) 
 12  blinkTypesColour = PySide2.QtGui.QColor(25, 25, 80) 
 13  blinkFuncsColour = PySide2.QtGui.QColor(3, 185, 191) 
 14   
 15   
 16  #Need to add in the proper methods here 
17 -class ScriptInputArea(PySide2.QtWidgets.QPlainTextEdit, PySide2.QtCore.QObject) :
18 19 #Signal that will be emitted when the user has changed the text 20 userChangedEvent = PySide2.QtCore.Signal() 21
22 - def __init__(self, output, editor, parent=None):
23 super(ScriptInputArea, self).__init__(parent) 24 25 # Font will be setup by showEvent function, reading settings from preferences 26 27 #Setup vars 28 self._output = output 29 self._editor = editor 30 self._errorLine = 0 31 self._showErrorHighlight = True 32 self._completer = None 33 self._currentCompletion = None 34 self._completerShowing = False 35 self._showLineNumbers = True 36 37 self.setStyleSheet("background-color: rgb(81, 81, 81);") 38 39 #Setup completer 40 self._completer = PySide2.QtWidgets.QCompleter(self) 41 self._completer.setWidget(self) 42 self._completer.setCompletionMode(PySide2.QtWidgets.QCompleter.UnfilteredPopupCompletion) 43 self._completer.setCaseSensitivity(PySide2.QtCore.Qt.CaseSensitive) 44 self._completer.setModel(PySide2.QtCore.QStringListModel()) 45 46 #Setup line numbers 47 self._lineNumberArea = LineNumberArea(self, parent=self) 48 49 #Add highlighter 50 self._highlighterInput = InputHighlighter(self.document(), parent=self) 51 52 #Setup connections 53 self.cursorPositionChanged.connect(self.highlightCurrentLine) 54 self._completer.activated.connect(self.insertCompletion) 55 self._completer.highlighted.connect(self.completerHighlightChanged) 56 self.blockCountChanged.connect(self.updateLineNumberAreaWidth) 57 self.updateRequest.connect(self.updateLineNumberArea) 58 59 self.updateLineNumberAreaWidth() 60 self._lineNumberArea.setVisible( self._showLineNumbers ) 61 self.setCursorWidth(PySide2.QtGui.QFontMetricsF(self.font()).width(' '))
62 63 64
65 - def lineNumberAreaWidth(self) :
66 67 if not self._showLineNumbers : 68 return 0 69 70 digits = 1 71 maxNum = max(1, self.blockCount()) 72 while (maxNum >= 10) : 73 maxNum /= 10 74 digits += 1 75 76 space = 5 + self.fontMetrics().width('9') * digits 77 return space
78 79
80 - def updateLineNumberAreaWidth(self) :
81 self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0)
82 83
84 - def updateLineNumberArea(self, rect, dy) :
85 if (dy) : 86 self._lineNumberArea.scroll(0, dy) 87 else : 88 self._lineNumberArea.update(0, rect.y(), self._lineNumberArea.width(), rect.height()) 89 90 if (rect.contains(self.viewport().rect())) : 91 self.updateLineNumberAreaWidth()
92 93
94 - def resizeEvent(self, event) :
95 PySide2.QtWidgets.QPlainTextEdit.resizeEvent(self, event) 96 97 cr = self.contentsRect() 98 self._lineNumberArea.setGeometry(PySide2.QtCore.QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(), cr.height()))
99
100 - def getFontFromHieroPrefs(self):
101 # May raise an ImportError in Nuke standalone 102 from hiero.core import ApplicationSettings 103 fontStr = ApplicationSettings().value("scripteditor/font") 104 105 # Setup new font and copy settings 106 font = PySide2.QtGui.QFont() 107 font.fromString(fontStr) 108 return font
109 110
111 - def getFontFromNukePrefs(self):
112 # Get the font from the preferences for Nuke's Script Editor 113 font = PySide2.QtGui.QFont(nuke.toNode("preferences").knob("ScriptEditorFont").value()) 114 # Set the size, also according to the Script Editor Preferences 115 fontSize = nuke.toNode("preferences").knob("ScriptEditorFontSize").getValue() 116 font.setPixelSize(fontSize); 117 return font
118 119
120 - def setFontFromPrefs(self):
121 try: 122 font = self.getFontFromHieroPrefs() 123 except ImportError: 124 font = self.getFontFromNukePrefs() 125 126 # Set the font for the text editor 127 self.setFont(font); 128 # Make sure the font used for the line numbers matches the text 129 self._lineNumberArea.setFont(font);
130 131
132 - def showEvent(self, event):
133 PySide2.QtWidgets.QPlainTextEdit.showEvent(self, event) 134 self.setFontFromPrefs()
135 136
137 - def lineNumberAreaPaintEvent(self, event) :
138 139 painter = PySide2.QtGui.QPainter(self._lineNumberArea) 140 painter.fillRect(event.rect(), self.palette().base()) 141 142 block = self.firstVisibleBlock() 143 blockNumber = block.blockNumber() 144 top = int( self.blockBoundingGeometry(block).translated(self.contentOffset()).top() ) 145 bottom = top + int( self.blockBoundingRect(block).height() ) 146 currentLine = self.document().findBlock(self.textCursor().position()).blockNumber() 147 148 font = painter.font() 149 pen = painter.pen() 150 painter.setPen( self.palette().color(PySide2.QtGui.QPalette.Text) ) 151 152 while (block.isValid() and top <= event.rect().bottom()) : 153 154 if (block.isVisible() and bottom >= event.rect().top()) : 155 156 if ( blockNumber == currentLine ) : 157 painter.setPen(PySide2.QtGui.QColor(255, 255, 255)) 158 font.setBold(True) 159 painter.setFont(font) 160 161 elif ( blockNumber == int(self._errorLine) - 1 ) : 162 painter.setPen(PySide2.QtGui.QColor(127, 0, 0)) 163 font.setBold(True) 164 painter.setFont(font) 165 166 else : 167 painter.setPen(PySide2.QtGui.QColor(35, 35, 35)) 168 font.setBold(False) 169 painter.setFont(font) 170 171 number = "%s" % str(blockNumber + 1) 172 painter.drawText(0, top, self._lineNumberArea.width(), self.fontMetrics().height(), PySide2.QtCore.Qt.AlignRight, number) 173 174 #Move to the next block 175 block = block.next() 176 top = bottom 177 bottom = top + int(self.blockBoundingRect(block).height()) 178 blockNumber += 1
179 180
181 - def highlightCurrentLine(self) :
182 183 extraSelections = [] 184 185 if (self._showErrorHighlight and not self.isReadOnly()) : 186 selection = PySide2.QtWidgets.QTextEdit.ExtraSelection() 187 188 lineColor = PySide2.QtGui.QColor(255, 255, 255, 40) 189 190 selection.format.setBackground(lineColor) 191 selection.format.setProperty(PySide2.QtGui.QTextFormat.FullWidthSelection, True) 192 selection.cursor = self.textCursor() 193 selection.cursor.clearSelection() 194 195 extraSelections.append(selection) 196 197 self.setExtraSelections(extraSelections) 198 self._errorLine = 0
199 200
201 - def highlightErrorLine(self) :
202 203 extraSelections = [] 204 205 if (self._showErrorHighlight and not self.isReadOnly()) : 206 if (self._errorLine != 0) : 207 selection = PySide2.QtWidgets.QTextEdit.ExtraSelection() 208 209 selection.format.setBackground(PySide2.QtGui.QColor(255, 0, 0, 40)) 210 selection.format.setProperty(PySide2.QtGui.QTextFormat.OutlinePen, PySide2.QtGui.QPen(PySide2.QtGui.QColor(127, 0, 0, 0))) 211 selection.format.setProperty(PySide2.QtGui.QTextFormat.FullWidthSelection, True) 212 213 pos = self.document().findBlockByLineNumber(int(self._errorLine)-1).position() 214 cursor = self.textCursor() 215 cursor.setPosition(pos) 216 217 selection.cursor = cursor 218 selection.cursor.clearSelection() 219 extraSelections.append(selection) 220 221 self.setExtraSelections(extraSelections)
222
223 - def keyPressEvent(self, event) :
224 225 lScriptEditorMod = ((event.modifiers() and (PySide2.QtCore.Qt.ControlModifier or PySide2.QtCore.Qt.AltModifier)) == PySide2.QtCore.Qt.ControlModifier) 226 lScriptEditorShift = ((event.modifiers() and (PySide2.QtCore.Qt.ShiftModifier)) != 0) 227 lKey = event.key() 228 229 #TODO Query Completer Showing 230 self._completerShowing = self._completer.popup().isVisible() 231 232 if not self._completerShowing : 233 if (lScriptEditorMod and (lKey == PySide2.QtCore.Qt.Key_Return or lKey == PySide2.QtCore.Qt.Key_Enter)) : 234 if (self._editor) : 235 self._editor.runScript() 236 return 237 #elif lScriptEditorMod and lScriptEditorShift and lKey == PySide2.QtCore.Qt.Key_BraceLeft : 238 # self.decreaseIndentationSelected() 239 # return 240 #elif lScriptEditorMod and lScriptEditorShift and lKey == PySide2.QtCore.Qt.Key_BraceRight : 241 # self.increaseIndentationSelected() 242 # return 243 elif lScriptEditorMod and lKey == PySide2.QtCore.Qt.Key_Slash : 244 self.commentSelected() 245 return 246 elif lScriptEditorMod and lKey == PySide2.QtCore.Qt.Key_Backspace : 247 self._editor.clearOutput() 248 return 249 elif lKey == PySide2.QtCore.Qt.Key_Tab or (lScriptEditorMod and lKey == PySide2.QtCore.Qt.Key_Space) : 250 #Ok. 251 #If you have a selection you should indent 252 #ElIf line is blank it should always pass through the key event 253 #Else get the last 254 tc = self.textCursor() 255 if tc.hasSelection() : 256 print "Indenting" 257 self.increaseIndentationSelected() 258 else : 259 #Show completion 260 colNum = tc.columnNumber() 261 posNum = tc.position() 262 inputText = self.toPlainText() 263 inputTextToCursor = self.toPlainText()[0:posNum] 264 inputTextSplit = inputText.splitlines() 265 inputTextToCursorSplit = inputTextToCursor.splitlines() 266 runningLength = 0 267 currentLine = None 268 269 for line in inputTextToCursorSplit : 270 length = len(line) 271 runningLength += length 272 if runningLength >= posNum : 273 currentLine = line 274 break 275 runningLength += 1 276 277 if currentLine : 278 279 if len(currentLine.strip()) == 0 : 280 tc = self.textCursor() 281 tc.insertText(" ") 282 return 283 284 token = currentLine.split(" ")[-1] 285 if "(" in token : 286 token = token.split("(")[-1] 287 288 if len(token)>0: 289 self.completeTokenUnderCursor(token) 290 else : 291 tc = self.textCursor() 292 tc.insertText(" ") 293 else : 294 tc = self.textCursor() 295 tc.insertText(" ") 296 297 #print mid(tc.position() - tc.columnNumber(), tc.columnNumber()) 298 299 else : 300 PySide2.QtWidgets.QPlainTextEdit.keyPressEvent(self, event) 301 return 302 else : 303 tc = self.textCursor() 304 if lKey == PySide2.QtCore.Qt.Key_Return or lKey == PySide2.QtCore.Qt.Key_Enter : 305 self.insertCompletion(self._currentCompletion) 306 self._currentCompletion = "" 307 self._completer.popup().hide() 308 self._completerShowing = False 309 elif lKey == PySide2.QtCore.Qt.Key_Right or lKey == PySide2.QtCore.Qt.Key_Escape: 310 self._completer.popup().hide() 311 self._completerShowing = False 312 elif lKey == PySide2.QtCore.Qt.Key_Tab or (lScriptEditorMod and lKey == PySide2.QtCore.Qt.Key_Space) : 313 self._currentCompletion = "" 314 self._completer.popup().hide() 315 else : 316 PySide2.QtWidgets.QPlainTextEdit.keyPressEvent(self, event) 317 #Edit completion model 318 colNum = tc.columnNumber() 319 posNum = tc.position() 320 inputText = self.toPlainText() 321 inputTextSplit = inputText.splitlines() 322 runningLength = 0 323 currentLine = None 324 for line in inputTextSplit : 325 length = len(line) 326 runningLength += length 327 if runningLength >= posNum : 328 currentLine = line 329 break 330 runningLength += 1 331 if currentLine : 332 token = currentLine.split(" ")[-1] 333 if "(" in token : 334 token = token.split("(")[-1] 335 self.completeTokenUnderCursor(token) 336 #PySide2.QtWidgets.QPlainTextEdit.keyPressEvent(self, event) 337 return
338
339 - def focusOutEvent(self, event):
340 self.userChangedEvent.emit() 341 return
342 343 344
345 - def insertIndent(self, tc) :
346 347 tc.beginEditBlock() 348 tc.insertText("\t") 349 tc.endEditBlock
350
351 - def commentSelected(self) :
352 353 return 354 355 tc = self.textCursor(); 356 if tc.hasSelection() : 357 358 tc.beginEditBlock() 359 self.ExtendSelectionToCompleteLines(tc) 360 start = tc.selectionStart() 361 end = tc.selectionEnd() 362 tc.setPosition(start) 363 364 365 if self.document().characterAt(start) == '#' : 366 367 #Comment 368 print "Uncommenting" 369 # prevPosition = end 370 # while tc.position() != prevPosition : 371 # tc.insertText("#"); 372 # prevPosition = tc.position() 373 # tc.movePosition(PySide2.QtGui.QTextCursor.NextBlock, PySide2.QtGui.QTextCursorMoveAnchor) 374 375 else : 376 377 #Uncomment 378 print "Commenting"
379 # prevPosition = end 380 # while tc.position() != prevPosition : 381 # if self.document().characterAt(tc.position()) == '#' : 382 # tc.deleteChar() 383 # prevPosition = tc.position() 384 # tc.movePosition(PySide2.QtGui.QTextCursor.NextBlock, PySide2.QtGui.QTextCursor.MoveAnchor) 385 386 #self.select(start, tc.position()) 387 #tc.endEditBlock() 388 #self.ensureCursorVisible() 389
390 - def ExtendSelectionToCompleteLines(self, tc) :
391 392 lPos = tc.position() 393 lAnchor = tc.anchor() 394 tc.setPosition(tc.anchor()); 395 396 if (lPos >= lAnchor) : 397 print "Moving to start of line" 398 #Position was after the anchor. Move to the start of the line, 399 tc.movePosition(PySide2.QtGui.QTextCursor.StartOfLine) 400 tc.setPosition(lPos, PySide2.QtGui.QTextCursor.KeepAnchor) 401 #Don't extend if the position was at the beginning of a new line 402 lSelected = tc.selectedText() 403 if lSelected != "" and lSelected[-2:-1] != "\n" : 404 tc.movePosition(PySide2.QtGui.QTextCursor.EndOfLine, PySide2.QtGui.QTextCursor.KeepAnchor) 405 406 else : 407 print "Moving to end of line" 408 #Position was before the anchor. Move to the end of the line, 409 #then select to the start of the line where the position was. 410 #Don't select to the end of the current line if the anchor was at the beginning 411 tc.movePosition(PySide2.QtGui.QTextCursor.PreviousCharacter,PySide2.QtGui.QTextCursor.KeepAnchor) 412 lSelected = tc.selectedText() 413 tc.movePosition(PySide2.QtGui.QTextCursor.NextCharacter) 414 if lSelected != "" and lSelected[-2:-1] != "\n" : 415 tc.movePosition(PySide2.QtGui.QTextCursor.EndOfLine) 416 tc.setPosition(lPos, PySide2.QtGui.QTextCursor.KeepAnchor) 417 tc.movePosition(PySide2.QtGui.QTextCursor.StartOfLine, PySide2.QtGui.QTextCursor.KeepAnchor)
418 419
421 422 print "Need to fix indenting" 423 424 return 425 426 tc = self.textCursor() 427 if tc.hasSelection() : 428 start = tc.selectionStart() 429 self.ExtendSelectionToCompleteLines(tc) 430 selected = tc.selectedText() 431 432 self.insertIndent(tc) 433 434 #replace paragraph things here 435 paraReplace = "\n" + ("\t") 436 indentedParas = selected.replace('\n', paraReplace) 437 438 textSplit = selected.splitlines() 439 indentedText = paraReplace.join(textSplit) 440 441 tc.beginEditBlock() 442 tc.removeSelectedText() 443 tc.insertText(indentedText) 444 tc.endEditBlock() 445 446 print "Need to fix selection after indenting" 447 448 self.setTextCursor(tc) 449 450 451 452 end = tc.selectionEnd() 453 454 tc.setPosition(start) 455 tc.setPosition(end, PySide2.QtGui.QTextCursor.KeepAnchor) 456 457 458 459 self.ensureCursorVisible()
460
462 print "Need to fix unindenting" 463 return 464 465 tc = self.textCursor() 466 if (tc.hasSelection()) : 467 start = tc.selectionStart() 468 self.ExtendSelectionToCompleteLines(tc) 469 return 470 selected = tc.selectedText() 471 472 #Get rid of indents 473 textSplit = selected.splitlines() 474 unsplitLines = [] 475 unindentedText = selected 476 477 for line in textSplit : 478 print type(line) 479 unsplitLines.append(line.replace('\t', '', 1)) 480 481 unindentedText = "\n".join(unsplitLines) 482 483 tc.beginEditBlock() 484 tc.removeSelectedText() 485 tc.insertText(unindentedText) 486 tc.endEditBlock() 487 end = tc.selectionEnd() 488 489 tc.setPosition(start) 490 tc.setPosition(end, PySide2.QtGui.QTextCursor.KeepAnchor) 491 492 #tc.select(start, tc.position()) 493 494 self.setTextCursor(tc) 495 496 self.ensureCursorVisible()
497
498 - def completionsForToken(self, token):
499 comp = rlcompleter.Completer() 500 completions = [] 501 completion = 1 502 for x in range(0, 1000): 503 completion = comp.complete(token, x) 504 if completion is not None: 505 completions.append(completion) 506 else : 507 break 508 return completions
509
510 - def completeTokenUnderCursor(self, token) :
511 512 #Clean token 513 token = token.lstrip().rstrip() 514 515 completionList = self.completionsForToken(token) 516 if len(completionList) == 0 : 517 return 518 519 #Set model for _completer to completion list 520 self._completer.model().setStringList(completionList) 521 522 #Set the prefix 523 self._completer.setCompletionPrefix(token) 524 525 #Check if we need to make it visible 526 if self._completer.popup().isVisible() : 527 rect = self.cursorRect(); 528 rect.setWidth(self._completer.popup().sizeHintForColumn(0) + self._completer.popup().verticalScrollBar().sizeHint().width()) 529 self._completer.complete(rect) 530 return 531 532 #Make it visible 533 if len(completionList) == 1 : 534 self.insertCompletion(completionList[0]); 535 else : 536 rect = self.cursorRect(); 537 rect.setWidth(self._completer.popup().sizeHintForColumn(0) + self._completer.popup().verticalScrollBar().sizeHint().width()) 538 self._completer.complete(rect) 539 540 return
541
542 - def insertCompletion(self, completion):
543 if completion : 544 completionNoToken = completion[len(self._completer.completionPrefix()):] 545 lCursor = self.textCursor() 546 lCursor.insertText(completionNoToken) 547 return
548
549 - def completerHighlightChanged(self, highlighted):
550 self._currentCompletion = highlighted
551 552 # void ScriptInputArea::insertCompletion(const QString& completion) 553 # { 554 # QString suffix = completion; 555 # suffix.remove(0, _completer->completionPrefix().length()); 556 # QTextCursor lCursor = textCursor(); 557 # lCursor.insertText(suffix); 558 # } 559
560 - def getErrorLineFromTraceback(self, tracebackStr) :
561 finalLine = None 562 for line in tracebackStr.split('\n') : 563 if 'File "<string>", line' in line : 564 finalLine = line 565 if finalLine == None : 566 return 0 567 try : 568 errorLine = finalLine.split(',')[1].split(' ')[2] 569 return errorLine 570 except : 571 return 0
572
573 - def runScript(self):
574 _selection = False; 575 self.highlightCurrentLine() 576 577 #Get text 578 text = self.toPlainText() 579 580 #Check if we've got some text selected. If so, replace text with selected text 581 tc = self.textCursor() 582 if tc.hasSelection() : 583 _selection = True 584 rawtext = tc.selectedText() 585 rawSplit = rawtext.splitlines() 586 rawJoined = '\n'.join(rawSplit) 587 text = rawJoined.lstrip().rstrip() 588 589 #Fix syntax error if last line is a comment with no new line 590 if not text.endswith('\n') : 591 text = text + '\n' 592 593 #JERRY has a lock here 594 595 #Compile 596 result = None 597 compileSuccess = False 598 runError = False 599 600 try : 601 compiled = compile(text, '<string>', 'exec') 602 compileSuccess = True 603 except Exception,e: 604 result = traceback.format_exc() 605 runError = True 606 compileSuccess = False 607 608 oldStdOut = sys.stdout 609 if compileSuccess : 610 #Override stdout to capture exec results 611 buffer = StringIO() 612 sys.stdout = buffer 613 try : 614 exec(compiled, globals()) 615 except Exception,e: 616 runError = True 617 result = traceback.format_exc() 618 else : 619 result = buffer.getvalue() 620 sys.stdout = oldStdOut 621 #print "STDOUT Restored" 622 623 #Update output 624 self._output.updateOutput( text ) 625 self._output.updateOutput( "\n# Result: \n" ) 626 self._output.updateOutput( result ) 627 self._output.updateOutput( "\n" ) 628 629 if runError : 630 #print "There was an error" 631 #print "result is %s " % result 632 self._errorLine = self.getErrorLineFromTraceback(result) 633 self.highlightErrorLine()
634 635 #Need to add in the proper methods here
636 -class InputHighlighter(PySide2.QtGui.QSyntaxHighlighter) :
637 - def __init__(self, doc, parent=None):
638 639 super(InputHighlighter, self).__init__(parent) 640 641 self.setDocument(doc) 642 643 self._rules = [] 644 self._keywords = PySide2.QtGui.QTextCharFormat() 645 self._strings = PySide2.QtGui.QTextCharFormat() 646 self._stringSingleQuotes = PySide2.QtGui.QTextCharFormat() 647 self._comment = PySide2.QtGui.QTextCharFormat() 648 self._blinkFuncs = PySide2.QtGui.QTextCharFormat() 649 self._blinkTypes = PySide2.QtGui.QTextCharFormat() 650 651 self._keywords.setForeground(kwdsFgColour) 652 self._keywords.setFontWeight(PySide2.QtGui.QFont.Bold) 653 654 #Construct rules for C++ keywords 655 #keywordPatterns = ["\\bchar\\b" , "\\bclass\\b" , "\\bconst\\b" 656 # , "\\bdouble\\b" , "\\benum\\b" , "\\bexplicit\\b" 657 # , "\\bfriend\\b" , "\\binline\\b" , "\\bint\\b" 658 # , "\\blong\\b" , "\\bnamespace\\b" , "\\boperator\\b" 659 # , "\\bprivate\\b" , "\\bprotected\\b" , "\\bpublic\\b" 660 # , "\\bshort\\b" , "\\bsignals\\b" , "\\bsigned\\b" 661 # , "\\bslots\\b" , "\\bstatic\\b" , "\\bstruct\\b" 662 # , "\\btemplate\\b" , "\\btypedef\\b" , "\\btypename\\b" 663 # , "\\bunion\\b" , "\\bunsigned\\b" , "\\bvirtual\\b" 664 # , "\\bvoid\\b" , "\\bvolatile\\b"] 665 #Construct rules for RIP++ keywords 666 keywordPatterns = ["\\bchar\\b" , 667 "\\bclass\\b" , 668 "\\bconst\\b" , 669 "\\bdouble\\b" , 670 "\\benum\\b" , 671 "\\bexplicit\\b" , 672 "\\bfriend\\b" , 673 "\\binline\\b" , 674 "\\bint\\b" , 675 "\\blong\\b" , 676 "\\bnamespace\\b" , 677 "\\boperator\\b" , 678 "\\bprivate\\b" , 679 "\\bprotected\\b" , 680 "\\bpublic\\b" , 681 "\\bshort\\b" , 682 "\\bsigned\\b" , 683 "\\bstatic\\b" , 684 "\\bstruct\\b" , 685 "\\btemplate\\b" , 686 "\\btypedef\\b" , 687 "\\btypename\\b" , 688 "\\bunion\\b" , 689 "\\bunsigned\\b" , 690 "\\bvirtual\\b" , 691 "\\bvoid\\b" , 692 "\\bvolatile\\b", 693 "\\blocal\\b", 694 "\\bparam\\b", 695 "\\bkernel\\b", 696 ] 697 698 for pattern in keywordPatterns: 699 rule = {} 700 rule['pattern'] = pattern 701 rule['format'] = self._keywords 702 self._rules.append(rule) 703 704 #Blink funcs 705 self._blinkFuncs.setForeground(blinkFuncsColour) 706 #self._blinkFuncs.setFontWeight(PySide2.QtGui.QFont.Bold) 707 blinkFuncPatterns = ["\\bdefine\\b" , 708 "\\bdefineParam\\b" , 709 "\\bprocess\\b" , 710 "\\binit\\b" , 711 "\\bsetRange\\b" , 712 "\\bsetAxis\\b" , 713 "\\bmedian\\b" , 714 "\\bbilinear\\b" , 715 ] 716 for pattern in blinkFuncPatterns: 717 rule = {} 718 rule['pattern'] = pattern 719 rule['format'] = self._blinkFuncs 720 self._rules.append(rule) 721 722 #Blink types 723 self._blinkTypes.setForeground(blinkTypesColour) 724 #self._blinkTypes.setFontWeight(PySide2.QtGui.QFont.Bold) 725 blinkTypesPatterns = ["\\bImage\\b" , 726 "\\beRead\\b" , 727 "\\beWrite\\b" , 728 "\\beEdgeClamped\\b" , 729 "\\beEdgeConstant\\b" , 730 "\\beEdgeNull\\b" , 731 "\\beAccessPoint\\b" , 732 "\\beAccessRanged1D\\b" , 733 "\\beAccessRanged2D\\b" , 734 "\\beAccessRandom\\b" , 735 "\\beComponentWise\\b" , 736 "\\bePixelWise\\b" , 737 "\\bImageComputationKernel\\b" , 738 "\\bint\\b" , 739 "\\bint2\\b" , 740 "\\bint3\\b" , 741 "\\bint4\\b" , 742 "\\bfloat\\b" , 743 "\\bfloat2\\b" , 744 "\\bfloat3\\b" , 745 "\\bfloat4\\b" , 746 "\\bfloat3x3\\b" , 747 "\\bfloat4x4\\b" , 748 "\\bbool\\b" , 749 ] 750 for pattern in blinkTypesPatterns: 751 rule = {} 752 rule['pattern'] = pattern 753 rule['format'] = self._blinkTypes 754 self._rules.append(rule) 755 756 #String Literals 757 self._strings.setForeground(stringLiteralsFgColourDQ) 758 rule = {} 759 rule['pattern'] = "\"([^\"\\\\]|\\\\.)*\"" 760 rule['format'] = self._strings 761 self._rules.append(rule) 762 763 #String single quotes 764 self._stringSingleQuotes.setForeground(stringLiteralsFgColourSQ) 765 rule = {} 766 rule['pattern'] = "'([^'\\\\]|\\\\.)*'" 767 rule['format'] = self._stringSingleQuotes 768 self._rules.append(rule) 769 770 #Comments 771 self._comment.setForeground(commentsFgColour) 772 rule = {} 773 rule['pattern'] = "//[^\n]*" 774 rule['format'] = self._comment 775 self._rules.append(rule)
776 777 778
779 - def highlightBlock(self, text) :
780 781 text = str(text) 782 783 for rule in self._rules : 784 expression = rule['pattern'] 785 786 if len(text) > 0 : 787 results = re.finditer(expression, text) 788 789 #Loop through all results 790 for result in results : 791 index = result.start() 792 length = result.end() - result.start() 793 self.setFormat(index, length, rule['format'])
794
795 -class LineNumberArea(PySide2.QtWidgets.QWidget):
796 - def __init__(self, scriptInputWidget, parent=None):
797 super(LineNumberArea, self).__init__(parent) 798 799 self._scriptInputWidget = scriptInputWidget 800 #self.setStyleSheet("QWidget { background-color: blue; }"); 801 self.setStyleSheet("text-align: center;")
802
803 - def sizeHint(self) :
804 return PySide2.QtCore.QSize(self._scriptInputWidget.lineNumberAreaWidth(), 0)
805
806 - def paintEvent(self, event) :
807 self._scriptInputWidget.lineNumberAreaPaintEvent(event) 808 return
809