Project/Project.py

branch
make_support
changeset 6254
88cb0838c90d
parent 6252
5e5e57bf09ed
child 6265
56bd09c4c297
equal deleted inserted replaced
6252:5e5e57bf09ed 6254:88cb0838c90d
20 import fnmatch 20 import fnmatch
21 import copy 21 import copy
22 import zipfile 22 import zipfile
23 23
24 from PyQt5.QtCore import pyqtSlot, QFile, QFileInfo, pyqtSignal, \ 24 from PyQt5.QtCore import pyqtSlot, QFile, QFileInfo, pyqtSignal, \
25 QCryptographicHash, QIODevice, QByteArray, QObject, Qt 25 QCryptographicHash, QIODevice, QByteArray, QObject, Qt, QProcess
26 from PyQt5.QtGui import QCursor, QKeySequence 26 from PyQt5.QtGui import QCursor, QKeySequence
27 from PyQt5.QtWidgets import QLineEdit, QToolBar, QDialog, QInputDialog, \ 27 from PyQt5.QtWidgets import QLineEdit, QToolBar, QDialog, QInputDialog, \
28 QApplication, QMenu, QAction 28 QApplication, QMenu, QAction
29 from PyQt5.Qsci import QsciScintilla 29 from PyQt5.Qsci import QsciScintilla
30 30
177 "Python3 Files (*.py *.py3);;" 177 "Python3 Files (*.py *.py3);;"
178 "Python3 GUI Files (*.pyw *.pyw3);;"), 178 "Python3 GUI Files (*.pyw *.pyw3);;"),
179 } 179 }
180 180
181 self.vcsMenu = None 181 self.vcsMenu = None
182 self.__makeProcess = None
182 183
183 self.__initProjectTypes() 184 self.__initProjectTypes()
184 185
185 self.__initData() 186 self.__initData()
186 187
4153 self.makeTestAct.setWhatsThis(self.tr( 4154 self.makeTestAct.setWhatsThis(self.tr(
4154 """<b>Test for Changes</b>""" 4155 """<b>Test for Changes</b>"""
4155 """<p>This questions 'make', if a rebuild of the configured""" 4156 """<p>This questions 'make', if a rebuild of the configured"""
4156 """ target is necessary.</p>""" 4157 """ target is necessary.</p>"""
4157 )) 4158 ))
4158 self.makeTestAct.triggered.connect(self.__questionMake) 4159 self.makeTestAct.triggered.connect(
4160 lambda: self.__executeMake(questionOnly=True))
4159 self.actions.append(self.makeTestAct) 4161 self.actions.append(self.makeTestAct)
4160 4162
4161 self.closeAct.setEnabled(False) 4163 self.closeAct.setEnabled(False)
4162 self.saveAct.setEnabled(False) 4164 self.saveAct.setEnabled(False)
4163 self.saveasAct.setEnabled(False) 4165 self.saveasAct.setEnabled(False)
5405 """ 5407 """
5406 Private slot called before the make menu is shown. 5408 Private slot called before the make menu is shown.
5407 """ 5409 """
5408 self.showMenu.emit("Make", self.makeMenu) 5410 self.showMenu.emit("Make", self.makeMenu)
5409 5411
5410 @pyqtSlot()
5411 def executeMake(self):
5412 """
5413 Public slot to execute a project specific make run (auto-run).
5414 """
5415 self.__executeMake(automatic=True)
5416
5417 @pyqtSlot()
5418 def __executeMake(self, automatic=False):
5419 """
5420 Private method to execute a project specific make run.
5421
5422 @param automatic flag indicating a non-user invoked execution
5423 @type bool
5424 """
5425 # TODO: implement this
5426 pass
5427
5428 @pyqtSlot()
5429 def __questionMake(self):
5430 """
5431 Private method to question make for changes.
5432 """
5433 # TODO: implement this
5434 pass
5435
5436 def hasDefaultMakeParameters(self): 5412 def hasDefaultMakeParameters(self):
5437 """ 5413 """
5438 Private method to test, if the project contains the default make 5414 Private method to test, if the project contains the default make
5439 parameters. 5415 parameters.
5440 5416
5456 5432
5457 @return flag indicating enabled make support 5433 @return flag indicating enabled make support
5458 @rtype bool 5434 @rtype bool
5459 """ 5435 """
5460 return self.pdata["MAKEPARAMS"]["MakeEnabled"] 5436 return self.pdata["MAKEPARAMS"]["MakeEnabled"]
5437
5438 @pyqtSlot()
5439 def executeMake(self):
5440 """
5441 Public slot to execute a project specific make run (auto-run)
5442 (execute or question).
5443 """
5444 self.__executeMake(
5445 questionOnly=self.pdata["MAKEPARAMS"]["MakeTestOnly"],
5446 interactive=False)
5447
5448 @pyqtSlot()
5449 def __executeMake(self, questionOnly=False, interactive=True):
5450 """
5451 Private method to execute a project specific make run.
5452
5453 @param questionOnly flag indicating to ask make for changes only
5454 @type bool
5455 @param interactive flag indicating an interactive invocation (i.e.
5456 through a menu action)
5457 @type bool
5458 """
5459 if not self.pdata["MAKEPARAMS"]["MakeEnabled"] or \
5460 self.__makeProcess is not None:
5461 return
5462
5463 if self.pdata["MAKEPARAMS"]["MakeExecutable"]:
5464 prog = self.pdata["MAKEPARAMS"]["MakeExecutable"]
5465 else:
5466 prog = Project.DefaultMake
5467
5468 args = []
5469 if self.pdata["MAKEPARAMS"]["MakeParameters"]:
5470 args.extend(Utilities.parseOptionString(
5471 self.pdata["MAKEPARAMS"]["MakeParameters"]))
5472
5473 if self.pdata["MAKEPARAMS"]["MakeFile"]:
5474 args.append("--makefile={0}".format(
5475 self.pdata["MAKEPARAMS"]["MakeFile"]))
5476
5477 if questionOnly:
5478 args.append("--question")
5479
5480 if self.pdata["MAKEPARAMS"]["MakeTarget"]:
5481 args.append(self.pdata["MAKEPARAMS"]["MakeTarget"])
5482
5483 self.__makeProcess = QProcess(self)
5484 self.__makeProcess.readyReadStandardOutput.connect(
5485 self.__makeReadStdOut)
5486 self.__makeProcess.readyReadStandardError.connect(
5487 self.__makeReadStdErr)
5488 self.__makeProcess.finished.connect(
5489 lambda exitCode, exitStatus: self.__makeFinished(
5490 exitCode, exitStatus, questionOnly, interactive))
5491 self.__makeProcess.setWorkingDirectory(self.getProjectPath())
5492 self.__makeProcess.start(prog, args)
5493
5494 if not self.__makeProcess.waitForStarted():
5495 E5MessageBox.critical(
5496 self.ui,
5497 self.tr("Execute Make"),
5498 self.tr("""The make process did not start."""))
5499
5500 self.__cleanupMake()
5501
5502 @pyqtSlot()
5503 def __makeReadStdOut(self):
5504 """
5505 Private slot to process process output received via stdout.
5506 """
5507 if self.__makeProcess is not None:
5508 output = str(self.__makeProcess.readAllStandardOutput(),
5509 Preferences.getSystem("IOEncoding"),
5510 'replace')
5511 self.appendStdout.emit(output)
5512
5513 @pyqtSlot()
5514 def __makeReadStdErr(self):
5515 """
5516 Private slot to process process output received via stderr.
5517 """
5518 if self.__makeProcess is not None:
5519 error = str(self.__makeProcess.readAllStandardError(),
5520 Preferences.getSystem("IOEncoding"),
5521 'replace')
5522 self.appendStderr.emit(error)
5523
5524 def __makeFinished(self, exitCode, exitStatus, questionOnly,
5525 interactive=True):
5526 """
5527 Private slot handling the make process finished signal.
5528
5529 @param exitCode exit code of the make process
5530 @type int
5531 @param exitStatus exit status of the make process
5532 @type QProcess.ExitStatus
5533 @param questionOnly flag indicating a test only run
5534 @type bool
5535 @param interactive flag indicating an interactive invocation (i.e.
5536 through a menu action)
5537 @type bool
5538 """
5539 if exitStatus == QProcess.CrashExit:
5540 E5MessageBox.critical(
5541 self.ui,
5542 self.tr("Execute Make"),
5543 self.tr("""The make process crashed."""))
5544 else:
5545 if questionOnly and exitCode == 1:
5546 # a rebuild is needed
5547 title = self.tr("Test for Changes")
5548
5549 if self.pdata["MAKEPARAMS"]["MakeTarget"]:
5550 message = self.tr(
5551 """<p>There are changes that require the configured"""
5552 """ make target <b>{0}</b> to be rebuilt.</p>""")\
5553 .format(self.pdata["MAKEPARAMS"]["MakeTarget"])
5554 else:
5555 message = self.tr(
5556 """<p>There are changes that require the default"""
5557 """ make target to be rebuilt.</p>""")
5558
5559 if self.ui.notificationsEnabled() and not interactive:
5560 self.ui.showNotification(
5561 UI.PixmapCache.getPixmap("makefile48.png"),
5562 title,
5563 message)
5564 else:
5565 E5MessageBox.information(self.ui, title, message)
5566 elif exitCode > 1:
5567 E5MessageBox.critical(
5568 self.ui,
5569 self.tr("Execute Make"),
5570 self.tr("""The makefile contains errors."""))
5571
5572 self.__cleanupMake()
5573
5574 def __cleanupMake(self):
5575 """
5576 Private method to clean up make related stuff.
5577 """
5578 self.__makeProcess.readyReadStandardOutput.disconnect()
5579 self.__makeProcess.readyReadStandardError.disconnect()
5580 self.__makeProcess.finished.disconnect()
5581 self.__makeProcess.deleteLater()
5582 self.__makeProcess = None

eric ide

mercurial