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