eric6/MicroPython/MicroPythonReplWidget.py

branch
micropython
changeset 7066
e3d034e65afc
parent 7065
e3d04faced34
child 7067
3fc4082fc6ba
equal deleted inserted replaced
7065:e3d04faced34 7066:e3d034e65afc
12 import re 12 import re
13 13
14 from PyQt5.QtCore import ( 14 from PyQt5.QtCore import (
15 pyqtSlot, pyqtSignal, Qt, QPoint, QEvent, QIODevice, QTimer 15 pyqtSlot, pyqtSignal, Qt, QPoint, QEvent, QIODevice, QTimer
16 ) 16 )
17 from PyQt5.QtGui import QColor, QKeySequence, QTextCursor 17 from PyQt5.QtGui import QColor, QKeySequence, QTextCursor, QBrush
18 from PyQt5.QtWidgets import ( 18 from PyQt5.QtWidgets import (
19 QWidget, QMenu, QApplication, QHBoxLayout, QSpacerItem, QSizePolicy) 19 QWidget, QMenu, QApplication, QHBoxLayout, QSpacerItem, QSizePolicy)
20 try: 20 try:
21 from PyQt5.QtSerialPort import QSerialPort 21 from PyQt5.QtSerialPort import QSerialPort
22 HAS_QTSERIALPORT = True 22 HAS_QTSERIALPORT = True
52 52
53 DeviceTypeRole = Qt.UserRole 53 DeviceTypeRole = Qt.UserRole
54 DevicePortRole = Qt.UserRole + 1 54 DevicePortRole = Qt.UserRole + 1
55 55
56 dataReceived = pyqtSignal(bytes) 56 dataReceived = pyqtSignal(bytes)
57
58 # ANSI Colors
59 AnsiColors = {
60 (1, 30): QBrush(Qt.darkGray),
61 (1, 31): QBrush(Qt.red),
62 (1, 32): QBrush(Qt.green),
63 (1, 33): QBrush(Qt.yellow),
64 (1, 34): QBrush(Qt.blue),
65 (1, 35): QBrush(Qt.magenta),
66 (1, 36): QBrush(Qt.cyan),
67 (1, 37): QBrush(Qt.white),
68 (2, 30): QBrush(Qt.black),
69 (2, 31): QBrush(Qt.darkRed),
70 (2, 32): QBrush(Qt.darkGreen),
71 (2, 33): QBrush(Qt.darkYellow),
72 (2, 34): QBrush(Qt.darkBlue),
73 (2, 35): QBrush(Qt.darkMagenta),
74 (2, 36): QBrush(Qt.darkCyan),
75 (2, 37): QBrush(Qt.lightGray),
76 }
57 77
58 def __init__(self, parent=None): 78 def __init__(self, parent=None):
59 """ 79 """
60 Constructor 80 Constructor
61 81
113 "MicroPython support is deactivated.</h3>")) 133 "MicroPython support is deactivated.</h3>"))
114 self.setEnabled(False) 134 self.setEnabled(False)
115 return 135 return
116 136
117 self.__vt100Re = re.compile( 137 self.__vt100Re = re.compile(
118 r'(?P<count>[\d]*)(;?[\d]*)*(?P<action>[ABCDKm])') 138 r'(?P<count>\d*);?(?P<color>\d*)(?P<action>[ABCDKm])')
119 139
120 self.__populateDeviceTypeComboBox() 140 self.__populateDeviceTypeComboBox()
121 141
122 self.replEdit.setAcceptRichText(False) 142 self.replEdit.setAcceptRichText(False)
123 self.replEdit.setUndoRedoEnabled(False) 143 self.replEdit.setUndoRedoEnabled(False)
125 145
126 self.replEdit.installEventFilter(self) 146 self.replEdit.installEventFilter(self)
127 147
128 self.replEdit.customContextMenuRequested.connect( 148 self.replEdit.customContextMenuRequested.connect(
129 self.__showContextMenu) 149 self.__showContextMenu)
150
151 defaultCharFormat = self.replEdit.textCursor().charFormat()
152 self.DefaultForeground = defaultCharFormat.foreground()
153 self.DefaultBackground = defaultCharFormat.background()
130 154
131 def __populateDeviceTypeComboBox(self): 155 def __populateDeviceTypeComboBox(self):
132 """ 156 """
133 Private method to populate the device type selector. 157 Private method to populate the device type selector.
134 """ 158 """
216 copyKeys = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_C) 240 copyKeys = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_C)
217 pasteKeys = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_V) 241 pasteKeys = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_V)
218 menu = QMenu(self) 242 menu = QMenu(self)
219 menu.addAction(self.tr("Copy"), self.replEdit.copy, copyKeys) 243 menu.addAction(self.tr("Copy"), self.replEdit.copy, copyKeys)
220 menu.addAction(self.tr("Paste"), self.__paste, pasteKeys) 244 menu.addAction(self.tr("Paste"), self.__paste, pasteKeys)
245 menu.addSeparator()
221 menu.exec_(self.replEdit.mapToGlobal(pos)) 246 menu.exec_(self.replEdit.mapToGlobal(pos))
222 247
223 def setConnected(self, connected): 248 def setConnected(self, connected):
224 """ 249 """
225 Public method to set the connection status LED. 250 Public method to set the connection status LED.
307 """ 332 """
308 Private slot to disconnect the serial connection. 333 Private slot to disconnect the serial connection.
309 """ 334 """
310 self.__closeSerialLink() 335 self.__closeSerialLink()
311 self.setConnected(False) 336 self.setConnected(False)
312
313 def __activatePlotter(self):
314 """
315 Private method to activate a data plotter widget.
316 """
317 # TODO: not implemented yet
318
319 def __deactivatePlotter(self):
320 """
321 Private method to deactivate the plotter widget.
322 """
323 # TODO: not implemented yet
324 337
325 @pyqtSlot() 338 @pyqtSlot()
326 def __paste(self): 339 def __paste(self):
327 """ 340 """
328 Private slot to perform a paste operation. 341 Private slot to perform a paste operation.
439 if match.group("count") == "": # delete to eol 452 if match.group("count") == "": # delete to eol
440 tc.movePosition(QTextCursor.EndOfLine, 453 tc.movePosition(QTextCursor.EndOfLine,
441 mode=QTextCursor.KeepAnchor) 454 mode=QTextCursor.KeepAnchor)
442 tc.removeSelectedText() 455 tc.removeSelectedText()
443 self.replEdit.setTextCursor(tc) 456 self.replEdit.setTextCursor(tc)
444 # TODO: add handling of 'm' (colors) 457 elif action == "m":
458 print(match.group("count"), match.group("color"))
459 charFormat = tc.charFormat()
460 if count == 0 and match.group("color") == "":
461 # reset color
462 charFormat.setForeground(self.DefaultForeground)
463 charFormat.setBackground(self.DefaultBackground)
464 elif count in (0, 1, 2):
465 if match.group("color") != "":
466 color = int(match.group("color"))
467 if count == 0:
468 count = 1
469 if 30 <= color <= 37:
470 charFormat.setForeground(
471 self.AnsiColors[(count, color)])
472 elif 40 <= color <= 47:
473 charFormat.setBackground(
474 self.AnsiColors[(count, color - 10)])
475 tc.setCharFormat(charFormat)
476 self.replEdit.setTextCursor(tc)
445 elif data[index] == 10: # \n 477 elif data[index] == 10: # \n
446 tc.movePosition(QTextCursor.End) 478 tc.movePosition(QTextCursor.End)
447 self.replEdit.setTextCursor(tc) 479 self.replEdit.setTextCursor(tc)
448 self.replEdit.insertPlainText(chr(data[index])) 480 self.replEdit.insertPlainText(chr(data[index]))
449 else: 481 else:
631 663
632 if self.__ui is None: 664 if self.__ui is None:
633 self.__ui = e5App().getObject("UserInterface") 665 self.__ui = e5App().getObject("UserInterface")
634 666
635 if self.__plotterRunning: 667 if self.__plotterRunning:
636 if self.__chartWidget.hasData(): 668 if self.__chartWidget.isDirty():
637 res = E5MessageBox.okToClearData( 669 res = E5MessageBox.okToClearData(
638 self, 670 self,
639 self.tr("Unsaved Chart Data"), 671 self.tr("Unsaved Chart Data"),
640 self.tr("""The chart contains unsaved data."""), 672 self.tr("""The chart contains unsaved data."""),
641 self.__chartWidget.saveData) 673 self.__chartWidget.saveData)
666 self.dataReceived.connect(self.__chartWidget.processData) 698 self.dataReceived.connect(self.__chartWidget.processData)
667 self.__chartWidget.dataFlood.connect(self.handleDataFlood) 699 self.__chartWidget.dataFlood.connect(self.handleDataFlood)
668 700
669 self.__ui.addSideWidget(self.__ui.BottomSide, self.__chartWidget, 701 self.__ui.addSideWidget(self.__ui.BottomSide, self.__chartWidget,
670 UI.PixmapCache.getIcon("chart"), 702 UI.PixmapCache.getIcon("chart"),
671 self.tr("Chart")) 703 self.tr("μPy Chart"))
672 self.__ui.showSideWidget(self.__chartWidget) 704 self.__ui.showSideWidget(self.__chartWidget)
673 705
674 if not self.__serial: 706 if not self.__serial:
675 self.__openSerialLink() 707 self.__openSerialLink()
676 if self.__serial: 708 if self.__serial:

eric ide

mercurial