9 |
9 |
10 from __future__ import unicode_literals |
10 from __future__ import unicode_literals |
11 |
11 |
12 import re |
12 import re |
13 import time |
13 import time |
|
14 import os |
14 |
15 |
15 from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QPoint, QEvent |
16 from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QPoint, QEvent |
16 from PyQt5.QtGui import QColor, QKeySequence, QTextCursor, QBrush |
17 from PyQt5.QtGui import QColor, QKeySequence, QTextCursor, QBrush |
17 from PyQt5.QtWidgets import ( |
18 from PyQt5.QtWidgets import ( |
18 QWidget, QMenu, QApplication, QHBoxLayout, QSpacerItem, QSizePolicy, |
19 QWidget, QMenu, QApplication, QHBoxLayout, QSpacerItem, QSizePolicy, |
20 ) |
21 ) |
21 |
22 |
22 from E5Gui.E5ZoomWidget import E5ZoomWidget |
23 from E5Gui.E5ZoomWidget import E5ZoomWidget |
23 from E5Gui import E5MessageBox, E5FileDialog |
24 from E5Gui import E5MessageBox, E5FileDialog |
24 from E5Gui.E5Application import e5App |
25 from E5Gui.E5Application import e5App |
|
26 from E5Gui.E5ProcessDialog import E5ProcessDialog |
25 |
27 |
26 from .Ui_MicroPythonWidget import Ui_MicroPythonWidget |
28 from .Ui_MicroPythonWidget import Ui_MicroPythonWidget |
27 |
29 |
28 from . import MicroPythonDevices |
30 from . import MicroPythonDevices |
29 try: |
31 try: |
1085 if self.__device: |
1088 if self.__device: |
1086 hasTime = self.__device.hasTimeCommands() |
1089 hasTime = self.__device.hasTimeCommands() |
1087 else: |
1090 else: |
1088 hasTime = False |
1091 hasTime = False |
1089 |
1092 |
1090 # TODO: add menu entry to cross-compile a .py file (using mpy-cross) |
|
1091 act = self.__superMenu.addAction( |
1093 act = self.__superMenu.addAction( |
1092 self.tr("Show Version"), self.__showDeviceVersion) |
1094 self.tr("Show Version"), self.__showDeviceVersion) |
1093 act.setEnabled(self.__connected) |
1095 act.setEnabled(self.__connected) |
1094 act = self.__superMenu.addAction( |
1096 act = self.__superMenu.addAction( |
1095 self.tr("Show Implementation"), self.__showImplementation) |
1097 self.tr("Show Implementation"), self.__showImplementation) |
1102 act = self.__superMenu.addAction( |
1104 act = self.__superMenu.addAction( |
1103 self.tr("Show Device Time"), self.__showDeviceTime) |
1105 self.tr("Show Device Time"), self.__showDeviceTime) |
1104 act.setEnabled(self.__connected) |
1106 act.setEnabled(self.__connected) |
1105 self.__superMenu.addAction( |
1107 self.__superMenu.addAction( |
1106 self.tr("Show Local Time"), self.__showLocalTime) |
1108 self.tr("Show Local Time"), self.__showLocalTime) |
|
1109 self.__superMenu.addSeparator() |
|
1110 if not Globals.isWindowsPlatform(): |
|
1111 self.__superMenu.addAction( |
|
1112 self.tr("Compile Python File"), self.__compileFile2Mpy) |
|
1113 act = self.__superMenu.addAction( |
|
1114 self.tr("Compile Current Editor"), self.__compileEditor2Mpy) |
|
1115 aw = e5App().getObject("ViewManager").activeWindow() |
|
1116 act.setEnabled(bool(aw)) |
1107 self.__superMenu.addSeparator() |
1117 self.__superMenu.addSeparator() |
1108 if self.__device: |
1118 if self.__device: |
1109 self.__device.addDeviceMenuEntries(self.__superMenu) |
1119 self.__device.addDeviceMenuEntries(self.__superMenu) |
1110 |
1120 |
1111 @pyqtSlot() |
1121 @pyqtSlot() |
1259 self, |
1269 self, |
1260 self.tr("Error handling device"), |
1270 self.tr("Error handling device"), |
1261 self.tr("<p>There was an error communicating with the connected" |
1271 self.tr("<p>There was an error communicating with the connected" |
1262 " device.</p><p>Method: {0}</p><p>Message: {1}</p>") |
1272 " device.</p><p>Method: {0}</p><p>Message: {1}</p>") |
1263 .format(method, error)) |
1273 .format(method, error)) |
|
1274 |
|
1275 def __crossCompile(self, pythonFile="", title=""): |
|
1276 """ |
|
1277 Private method to cross compile a Python file to a .mpy file. |
|
1278 |
|
1279 @param pythonFile name of the Python file to be compiled |
|
1280 @type str |
|
1281 @param title title for the various dialogs |
|
1282 @type str |
|
1283 """ |
|
1284 program = Preferences.getMicroPython("MpyCrossCompiler") |
|
1285 if not program: |
|
1286 program = "mpy-cross" |
|
1287 if not Utilities.isinpath(program): |
|
1288 E5MessageBox.critical( |
|
1289 self, |
|
1290 title, |
|
1291 self.tr("""The MicroPython cross compiler""" |
|
1292 """ <b>mpy-cross</b> cannot be found. Ensure it""" |
|
1293 """ is in the search path or configure it on""" |
|
1294 """ the MicroPython configuration page.""")) |
|
1295 return |
|
1296 |
|
1297 if not pythonFile: |
|
1298 defaultDirectory = "" |
|
1299 aw = e5App().getObject("ViewManager").activeWindow() |
|
1300 if aw: |
|
1301 fn = aw.getFileName() |
|
1302 if fn: |
|
1303 defaultDirectory = os.path.dirname(fn) |
|
1304 if not defaultDirectory: |
|
1305 defaultDirectory = Preferences.getMultiProject("Workspace") |
|
1306 pythonFile = E5FileDialog.getOpenFileName( |
|
1307 self, |
|
1308 title, |
|
1309 defaultDirectory, |
|
1310 self.tr("Python Files (*.py);;All Files (*)")) |
|
1311 if not pythonFile: |
|
1312 # user cancelled |
|
1313 return |
|
1314 |
|
1315 if not os.path.exists(pythonFile): |
|
1316 E5MessageBox.critical( |
|
1317 self, |
|
1318 title, |
|
1319 self.tr("""The Python file <b>{0}</b> does not exist.""" |
|
1320 """ Aborting...""").format(pythonFile)) |
|
1321 return |
|
1322 |
|
1323 compileArgs = [ |
|
1324 pythonFile, |
|
1325 ] |
|
1326 dlg = E5ProcessDialog(self.tr("'mpy-cross' Output"), title) |
|
1327 res = dlg.startProcess(program, compileArgs) |
|
1328 if res: |
|
1329 dlg.exec_() |
|
1330 |
|
1331 @pyqtSlot() |
|
1332 def __compileFile2Mpy(self): |
|
1333 """ |
|
1334 Private slot to cross compile a Python file (*.py) to a .mpy file. |
|
1335 """ |
|
1336 self.__crossCompile(title=self.tr("Compile Python File")) |
|
1337 |
|
1338 @pyqtSlot() |
|
1339 def __compileEditor2Mpy(self): |
|
1340 """ |
|
1341 Private slot to cross compile the current editor to a .mpy file. |
|
1342 """ |
|
1343 aw = e5App().getObject("ViewManager").activeWindow() |
|
1344 if not aw.checkDirty(): |
|
1345 # editor still has unsaved changes, abort... |
|
1346 return |
|
1347 if not aw.isPyFile(): |
|
1348 # no Python file |
|
1349 E5MessageBox.critical( |
|
1350 self, |
|
1351 self.tr("Compile Current Editor"), |
|
1352 self.tr("""The current editor does not contain a Python""" |
|
1353 """ file. Aborting...""")) |
|
1354 return |
|
1355 |
|
1356 self.__crossCompile( |
|
1357 pythonFile=aw.getFileName(), |
|
1358 title=self.tr("Compile Current Editor") |
|
1359 ) |