コード例 #1
0
class ThreadDNSspoofNF(QObject):
    DnsReq = pyqtSignal(object)
    def __init__(self,domains,interface,redirect,APmode=True,parent=None):
        super(ThreadDNSspoofNF, self).__init__(parent)
        self.domains    = domains
        self.interface  = interface
        self.redirect   = redirect
        self.APmode     = APmode
        self.desc       = 'DNS spoof Module::NetFilter'

    @pyqtSlot()
    def readProcessOutput(self):
        self.data = str(self.procThreadDNS.readAllStandardOutput())
        self.DnsReq.emit(self.data)

    def start(self):
        self.setIptables(self.APmode,option='A')
        self.procThreadDNS = QProcess(self)
        self.procThreadDNS.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procThreadDNS, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()'))
        self.procThreadDNS.start('python',['core/packets/dnsspoofNF.py','-r',self.redirect,
        '-d',','.join(self.domains)])

    def setIptables(self,APMode=True, option=str()):
        if APMode:
            system('iptables -{} INPUT -i {} -p udp --dport 53 -s {} -j ACCEPT'.format(option,self.interface,self.redirect))
            system('iptables -{} INPUT -i {} -p udp --dport 53 -j DROP'.format(option,self.interface))
            system('iptables -t nat -{} PREROUTING -p udp --dport 53 -j NFQUEUE'.format(option))

    def stop(self):
        self.setIptables(self.APmode,option='D')
        if hasattr(self,'procThreadDNS'):
            self.procThreadDNS.terminate()
            self.procThreadDNS.waitForFinished()
            self.procThreadDNS.kill()
コード例 #2
0
ファイル: threads.py プロジェクト: ihebski/WiFi-Pumpkin
class ProcessThread(QObject):
    _ProcssOutput = pyqtSignal(object)
    def __init__(self,cmd,):
        QObject.__init__(self)
        self.cmd = cmd

    def getNameThread(self):
        return '[New Thread {} ({})]'.format(self.procThread.pid(),self.objectName())

    @pyqtSlot()
    def readProcessOutput(self):
        self.data = str(self.procThread.readAllStandardOutput())
        self._ProcssOutput.emit(self.data)

    def start(self):
        self.procThread = QProcess(self)
        self.procThread.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procThread, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()'))
        self.procThread.start(self.cmd.keys()[0],self.cmd[self.cmd.keys()[0]])
        print '[New Thread {} ({})]'.format(self.procThread.pid(),self.objectName())

    def stop(self):
        print 'Thread::[{}] successfully stopped.'.format(self.objectName())
        if hasattr(self,'procThread'):
            self.procThread.terminate()
            self.procThread.waitForFinished()
            self.procThread.kill()
コード例 #3
0
ファイル: network.py プロジェクト: acelectic/WiFi-Pumpkin
class ThreadDNSspoofNF(QObject):
    DnsReq = pyqtSignal(object)
    def __init__(self,domains,interface,redirect,APmode=True,parent=None):
        super(ThreadDNSspoofNF, self).__init__(parent)
        self.domains    = domains
        self.interface  = interface
        self.redirect   = redirect
        self.APmode     = APmode
        self.desc       = 'DNS spoof Module::NetFilter'

    @pyqtSlot()
    def readProcessOutput(self):
        self.data = str(self.procThreadDNS.readAllStandardOutput())
        self.DnsReq.emit(self.data)

    def start(self):
        self.setIptables(self.APmode,option='A')
        self.procThreadDNS = QProcess(self)
        self.procThreadDNS.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procThreadDNS, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()'))
        self.procThreadDNS.start('python',['Core/packets/dnsspoofNF.py','-r',self.redirect,
        '-d',','.join(self.domains)])

    def setIptables(self,APMode=True, option=str()):
        if APMode:
            system('iptables -{} INPUT -i {} -p udp --dport 53 -s {} -j ACCEPT'.format(option,self.interface,self.redirect))
            system('iptables -{} INPUT -i {} -p udp --dport 53 -j DROP'.format(option,self.interface))
            system('iptables -t nat -{} PREROUTING -p udp --dport 53 -j NFQUEUE'.format(option))

    def stop(self):
        self.setIptables(self.APmode,option='D')
        if hasattr(self,'procThreadDNS'):
            self.procThreadDNS.terminate()
            self.procThreadDNS.waitForFinished()
            self.procThreadDNS.kill()
コード例 #4
0
class ThreadLogger(QObject):
    def __init__(self, logger_path=str):
        QObject.__init__(self)
        self.logger_path = logger_path

    @pyqtSlot()
    def readProcessOutput(self):
        try:
            self.emit(
                SIGNAL('Activated( QString )'),
                str(self.procLogger.readAllStandardOutput()).rstrip().split(
                    ' : ')[1])
        except Exception:
            pass

    def start(self):
        self.procLogger = QProcess(self)
        self.procLogger.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procLogger, SIGNAL('readyReadStandardOutput()'),
                        self, SLOT('readProcessOutput()'))
        self.procLogger.start('tail', ['-f', self.logger_path])

    def stop(self):
        if hasattr(self, 'procLogger'):
            self.procLogger.terminate()
            self.procLogger.waitForFinished()
            self.procLogger.kill()
コード例 #5
0
class ProcessThread(QObject):
    _ProcssOutput = pyqtSignal(object)

    def __init__(
        self,
        cmd,
    ):
        QObject.__init__(self)
        self.cmd = cmd

    def getNameThread(self):
        return '[New Thread {} ({})]'.format(self.procThread.pid(),
                                             self.objectName())

    @pyqtSlot()
    def readProcessOutput(self):
        self.data = str(self.procThread.readAllStandardOutput())
        self._ProcssOutput.emit(self.data)

    def start(self):
        self.procThread = QProcess(self)
        self.procThread.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procThread, SIGNAL('readyReadStandardOutput()'),
                        self, SLOT('readProcessOutput()'))
        self.procThread.start(self.cmd.keys()[0], self.cmd[self.cmd.keys()[0]])
        print '[New Thread {} ({})]'.format(self.procThread.pid(),
                                            self.objectName())

    def stop(self):
        print 'Thread::[{}] successfully stopped.'.format(self.objectName())
        if hasattr(self, 'procThread'):
            self.procThread.terminate()
            self.procThread.waitForFinished()
            self.procThread.kill()
コード例 #6
0
ファイル: threads.py プロジェクト: laykatz/WiFi-Pumpkin
class ProcessHostapd(QObject):
    statusAP_connected = pyqtSignal(object)
    def __init__(self,cmd):
        QObject.__init__(self)
        self.cmd = cmd

    def getNameThread(self):
        return '[New Thread {} ({})]'.format(self.procHostapd.pid(),self.objectName())

    @pyqtSlot()
    def read_OutputCommand(self):
        self.data = str(self.procHostapd.readAllStandardOutput())
        if 'AP-STA-DISCONNECTED' in self.data.rstrip() or 'inactivity (timer DEAUTH/REMOVE)' in self.data.rstrip():
            self.statusAP_connected.emit(self.data.split()[2])

    def start(self):
        self.makeLogger()
        self.procHostapd = QProcess(self)
        self.procHostapd.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procHostapd, SIGNAL('readyReadStandardOutput()'), self, SLOT('read_OutputCommand()'));
        self.procHostapd.start(self.cmd.keys()[0],self.cmd[self.cmd.keys()[0]])
        print '[New Thread {} ({})]'.format(self.procHostapd.pid(),self.objectName())

    def makeLogger(self):
        setup_logger('hostapd', './Logs/AccessPoint/requestAP.log')
        self.log_hostapd = logging.getLogger('hostapd')

    def stop(self):
        print 'Thread::[{}] successfully stopped.'.format(self.objectName())
        if hasattr(self,'procHostapd'):
            self.procHostapd.terminate()
            self.procHostapd.waitForFinished()
            self.procHostapd.kill()
コード例 #7
0
ファイル: threads.py プロジェクト: srbakb/WiFi-Pumpkin
class ProcessThread(QObject):
    def __init__(self,cmd,):
        QObject.__init__(self)
        self.cmd = cmd

    def getNameThread(self):
        return 'Starting Thread:' + self.objectName()

    @pyqtSlot()
    def readProcessOutput(self):
        self.data = str(self.procThread.readAllStandardOutput())

    def start(self):
        print 'Starting Thread:' + self.objectName()
        self.procThread = QProcess(self)
        self.procThread.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procThread, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()'))
        self.procThread.start(self.cmd.keys()[0],self.cmd[self.cmd.keys()[0]])

    def stop(self):
        print 'Stop thread:' + self.objectName()
        if hasattr(self,'procThread'):
            self.procThread.terminate()
            self.procThread.waitForFinished()
            self.procThread.kill()
コード例 #8
0
class PROCESS(QObject):
    queue_finished = pyqtSignal(int)
    prog_finished = pyqtSignal(tuple)
    stoped = pyqtSignal(int, int)  # 1: start, 0: finished, 2: error | queue
    state = pyqtSignal(int, str)

    def __init__(self, parent=None):
        QObject.__init__(self, parent)
        self.process = QProcess()
        self.process.setProcessChannelMode(QProcess.MergedChannels)
        self.process.finished.connect(self.emit_finished)
        self.process.stateChanged.connect(self.emit_state)
        self.process_type = 0  # 0 process, 1 runnable
        self.threadpool = QThreadPool()
        self.worker = Worker()
        self.worker.signals.state.connect(self.emit_state)
        self.queue = None

    def emit_state(self, state):
        self.state.emit(state, self.prog_name)

    def emit_finished(self, exitcode, exitstatus):
        self.prog_finished.emit((self.prog_name, exitcode, exitstatus))

    def set_queue(self, queue):
        self.queue = queue

    def start_process(self):
        try:
            obj = self.queue.get(False)
            self.prog_name = obj.keys()[0]
            if callable(obj.values()[0][0]):
                self.process_type = 1
                funct = obj.values()[0][0]
                args = obj.values()[0][1]
                self.worker.insert_function(funct, args, self.prog_name)
                self.threadpool.start(self.worker)
            else:
                self.process_type = 0
                self.process.start(obj.values()[0][0], obj.values()[0][1])
        except Queue.Empty:
            self.queue_finished.emit(self.queue.name)

    def force_finished(self):
        # for process (programs)
        self.stoped.emit(1, self.queue.name)
        if self.process_type == 0:
            self.process.terminate()
            if not self.process.waitForFinished(1000):
                self.process.kill()
        else:
            if self.threadpool.activeThreadCount():
                self.threadpool.clear()
                self.threadpool.waitForDone()
        with self.queue.mutex:
            self.queue.queue.clear()
        self.stoped.emit(0, self.queue.name)
コード例 #9
0
class ProcessHostapd(QObject):
    statusAP_connected = pyqtSignal(object)
    statusAPError = pyqtSignal(object)

    def __init__(self, cmd, session):
        QObject.__init__(self)
        self.cmd = cmd
        self.session = session
        self.errorAPDriver = ('AP-DISABLED', 'Failed to initialize interface',
                              'nl80211 driver initialization failed.',
                              'errors found in configuration file')

    def getNameThread(self):
        return '[New Thread {} ({})]'.format(self.procHostapd.pid(),
                                             self.objectName())

    @pyqtSlot()
    def read_OutputCommand(self):
        self.data = str(self.procHostapd.readAllStandardOutput())
        if 'AP-STA-DISCONNECTED' in self.data.rstrip(
        ) or 'inactivity (timer DEAUTH/REMOVE)' in self.data.rstrip():
            self.statusAP_connected.emit(self.data.split()[2])
        self.log_hostapd.info(self.data)
        for error in self.errorAPDriver:
            if self.data.find(error) != -1:
                return self.statusAPError.emit(self.data)

    def start(self):
        self.makeLogger()
        self.procHostapd = QProcess(self)
        self.procHostapd.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procHostapd, SIGNAL('readyReadStandardOutput()'),
                        self, SLOT('read_OutputCommand()'))
        self.procHostapd.start(self.cmd.keys()[0],
                               self.cmd[self.cmd.keys()[0]])
        print '[New Thread {} ({})]'.format(self.procHostapd.pid(),
                                            self.objectName())

    def makeLogger(self):
        setup_logger('hostapd', C.LOG_HOSTAPD, self.session)
        self.log_hostapd = logging.getLogger('hostapd')

    def stop(self):
        print 'Thread::[{}] successfully stopped.'.format(self.objectName())
        if hasattr(self, 'procHostapd'):
            QObject.disconnect(self.procHostapd,
                               SIGNAL('readyReadStandardOutput()'), self,
                               SLOT('read_OutputCommand()'))
            self.procHostapd.terminate()
            self.procHostapd.waitForFinished()
            self.procHostapd.kill()
コード例 #10
0
ファイル: threads.py プロジェクト: ihebski/WiFi-Pumpkin
class ProcessHostapd(QObject):
    statusAP_connected = pyqtSignal(object)
    statusAPError = pyqtSignal(object)
    def __init__(self,cmd,session):
        QObject.__init__(self)
        self.cmd         = cmd
        self.session     = session
        self.errorAPDriver = ('AP-DISABLED',
        'Failed to initialize interface',
        'nl80211 driver initialization failed.',
        'errors found in configuration file')

    def getNameThread(self):
        return '[New Thread {} ({})]'.format(self.procHostapd.pid(),self.objectName())

    @pyqtSlot()
    def read_OutputCommand(self):
        self.data = str(self.procHostapd.readAllStandardOutput())
        if 'AP-STA-DISCONNECTED' in self.data.rstrip() or 'inactivity (timer DEAUTH/REMOVE)' in self.data.rstrip():
            self.statusAP_connected.emit(self.data.split()[2])
        self.log_hostapd.info(self.data)
        for error in self.errorAPDriver:
            if self.data.find(error) != -1:
                return self.statusAPError.emit(self.data)

    def start(self):
        self.makeLogger()
        self.procHostapd = QProcess(self)
        self.procHostapd.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procHostapd, SIGNAL('readyReadStandardOutput()'), self, SLOT('read_OutputCommand()'));
        self.procHostapd.start(self.cmd.keys()[0],self.cmd[self.cmd.keys()[0]])
        print '[New Thread {} ({})]'.format(self.procHostapd.pid(),self.objectName())

    def makeLogger(self):
        setup_logger('hostapd', './logs/AccessPoint/hostapd.log',self.session)
        self.log_hostapd = logging.getLogger('hostapd')

    def stop(self):
        print 'Thread::[{}] successfully stopped.'.format(self.objectName())
        if hasattr(self,'procHostapd'):
            QObject.disconnect(self.procHostapd,
            SIGNAL('readyReadStandardOutput()'), self, SLOT('read_OutputCommand()'))
            self.procHostapd.terminate()
            self.procHostapd.waitForFinished()
            self.procHostapd.kill()
コード例 #11
0
ファイル: music_son_base_sox.py プロジェクト: Ptaah/Ekd
class checkSoxEncoding(QObject) :
	"""checkSoxEncoding est une class pour vérifier les possibilités de Sox pour l'encodage du format mp2/mp3. Si ce n'est pas le cas, retourne 0 -> adaptation de l'interface pour supprimer ces possibilités"""
	def __init__(self, listeformat, parent=None) :
		super(checkSoxEncoding, self).__init__(parent)
		#self.hide()
		self.listeFormat = listeformat
		self.parent = parent
		self.index = 0
		self.checkListeFormat = []

	def run(self) :
		self.soxP = QProcess(self.parent)
		self.connect(self.soxP, SIGNAL('finished(int)'), self.finProcess)
		self.write = 0
		commande = u"sox -n -t %s \"%s\" trim 00:00:00.000 00:00:01.000" % (self.listeFormat[self.index], os.path.expanduser("~")+os.sep+u"checkSoxEssai."+self.listeFormat[self.index])
		### Debug
		print commande
		self.soxP.setProcessChannelMode(QProcess.MergedChannels)
		self.soxP.start(commande)

	def finProcess(self,statut) :
		# Test si la commande a été exécutée correctement
		print "statut de sortie : %d" % (statut)
		if not statut :
			# Si OK -> Ajout de l'extension dans la liste des formats supportés par Sox en encodage
			self.checkListeFormat.append((self.listeFormat[self.index],True))
			os.remove(os.path.expanduser("~")+os.sep+u"checkSoxEssai."+self.listeFormat[self.index])
		else :
			# Sinon, déclaré le format comme non utilisable et donc pas présent dans la liste des formats supportés
			self.checkListeFormat.append((self.listeFormat[self.index],False))
		# Incrémentation du compteur pour explorer tous les formats à tester
		self.index += 1
		### Debug
		print "index = %d" % (self.index)
		print "longueur liste = %d" % (len(self.listeFormat))
		# Si l'index est égal au nombre de format à tester, la class émet le signal de fin de vérification + liste des formats avec info sur le support
		if self.index == len(self.listeFormat) :
			### Debug : print self.checkListeFormat
			self.emit(SIGNAL("checkSox"), self.checkListeFormat)
		else :
			self.run()
コード例 #12
0
ファイル: threads.py プロジェクト: leoshan/WiFi-Pumpkin
class ProcessHostapd(QObject):
    statusAP_connected = pyqtSignal(object)

    def __init__(self, cmd, session):
        QObject.__init__(self)
        self.cmd = cmd
        self.session = session

    def getNameThread(self):
        return '[New Thread {} ({})]'.format(self.procHostapd.pid(),
                                             self.objectName())

    @pyqtSlot()
    def read_OutputCommand(self):
        self.data = str(self.procHostapd.readAllStandardOutput())
        if 'AP-STA-DISCONNECTED' in self.data.rstrip(
        ) or 'inactivity (timer DEAUTH/REMOVE)' in self.data.rstrip():
            self.statusAP_connected.emit(self.data.split()[2])
        self.log_hostapd.info(self.data)

    def start(self):
        self.makeLogger()
        self.procHostapd = QProcess(self)
        self.procHostapd.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procHostapd, SIGNAL('readyReadStandardOutput()'),
                        self, SLOT('read_OutputCommand()'))
        self.procHostapd.start(self.cmd.keys()[0],
                               self.cmd[self.cmd.keys()[0]])
        print '[New Thread {} ({})]'.format(self.procHostapd.pid(),
                                            self.objectName())

    def makeLogger(self):
        setup_logger('hostapd', './Logs/AccessPoint/hostapd.log', self.session)
        self.log_hostapd = logging.getLogger('hostapd')

    def stop(self):
        print 'Thread::[{}] successfully stopped.'.format(self.objectName())
        if hasattr(self, 'procHostapd'):
            self.procHostapd.terminate()
            self.procHostapd.waitForFinished()
            self.procHostapd.kill()
コード例 #13
0
ファイル: dockmonitor.py プロジェクト: ihebski/WiFi-Pumpkin
class ThreadLogger(QObject):
    def __init__(self,logger_path=str):
        QObject.__init__(self)
        self.logger_path = logger_path

    @pyqtSlot()
    def readProcessOutput(self):
        try:
            self.emit(SIGNAL('Activated( QString )'),
            str(self.procLogger.readAllStandardOutput()).rstrip().split(' : ')[1])
        except Exception: pass

    def start(self):
        self.procLogger = QProcess(self)
        self.procLogger.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self.procLogger, SIGNAL('readyReadStandardOutput()'), self, SLOT('readProcessOutput()'))
        self.procLogger.start('tail',['-f',self.logger_path])

    def stop(self):
        if hasattr(self,'procLogger'):
            self.procLogger.terminate()
            self.procLogger.waitForFinished()
            self.procLogger.kill()
コード例 #14
0
class FrD_NukeBatchRender(QtGui.QMainWindow, form_class):
    def __init__(self, parent=None):

        QtGui.QMainWindow.__init__(self, parent)

        self.setupUi(self)
        self.setWindowTitle('FrD Nuke Batch Render' + PROGRAM_VERSION)
        self.output_LW.setEnabled(0)
    # ============================ STYLE ======================= #
        # Progress Bar Style
        PB_STYLE = """
        QProgressBar
        {
            border: 2px solid grey;
            border-radius: 5px;
            text-align: center;
        }

        QProgressBar::chunk
        {
            background-color: #d7801a;
            width: 3px;
            margin: 1.5px;
        }
        """
        # self.PB.setStyleSheet(PB_STYLE)

        # QMenuBar Style
        MB_STYLE = """
        QMenuBar::item
        {
            background: transparent;
        }

        QMenuBar::item:selected
        {
            background: background-color: rgb(49,49,49);
            border: 1px solid #000;
        }

        QMenuBar::item:pressed
        {
            background: #444;
            border: 1px solid #000;
            background-color: QLinearGradient(
                x1:0, y1:0,
                x2:0, y2:1,
                stop:1 #212121,
                stop:0.4 #343434/*,
                stop:0.2 #343434,
                stop:0.1 #ffaa00*/
            );
            margin-bottom:-1px;
            padding-bottom:1px;
        }

        """
        self.menuFiles.setStyleSheet(MB_STYLE)
    # ============================ STYLE ======================= #

        # Enable Drah and Drop
        self.Queue_TW.setAcceptDrops(True)
        # Set up handlers for the TableWidget
        self.Queue_TW.dragEnterEvent = self.twDragEnterEvent
        self.Queue_TW.dragMoveEvent = self.twDragMoveEvent
        self.Queue_TW.dropEvent = self.twDropEvent

        # Size of Table Columns
        self.Queue_TW.setColumnWidth(0, 250)
        self.Queue_TW.setColumnWidth(1, 300)
        self.Queue_TW.setColumnWidth(2, 100)
        self.Queue_TW.setColumnWidth(3, 100)
        self.Queue_TW.setColumnWidth(4, 310)
        self.Queue_TW.setColumnWidth(5, 110)

        # operation ALL
        self.Clear_BN.clicked.connect(self.ClearQueue)
        self.Update_BN.clicked.connect(self.UpdateQueue)
        # Render
        self.Render_BN.clicked.connect(self.NBR_render)

    # ============ Drag and Drop Event) ============ #
    def twDragEnterEvent(self, event):
        if event.mimeData().hasUrls:
            event.accept()
        else:
            event.ignore()

    def twDragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
        else:
            event.ignore()

    def twDropEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(QtCore.Qt.CopyAction)
            event.accept()
            links = []
            for url in event.mimeData().urls():
                links.append(str(url.toLocalFile()))
            # print links
            self.nukeProjDropped(links)
        else:
            event.ignore()
    # ============  Drag and Drop Ends  ============ #
    # ============ Clear and Update All ============ #

    def NBR_askMsg(self, title, text):
        qmsgBox = QtGui.QMessageBox()
        qmsgBox.setStyleSheet('QMessageBox {background-color: #333; font-size: 12pt; font-family: Trebuchet MS}\nQLabel{color:white;}')  # 585858
        return QtGui.QMessageBox.question(qmsgBox, title, text, QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel)  # | QtGui.QMessageBox.No

    def ClearQueue(self):
        global folderQueue
        if self.Queue_TW.rowCount() > 0:
            if (self.NBR_askMsg('Clear Render Queue', 'Are you sure you want to clear the whole Render Queue?') == QtGui.QMessageBox.Yes):
                self.Queue_TW.setRowCount(0)
                folderQueue = []
                QtGui.QApplication.processEvents()

    def UpdateQueue(self):
        global folderQueue
        for project in xrange(len(folderQueue)):
            pass
    # ========== Clear and Update All Ends ========== #

    def nukeProjDropped(self, arg):
        global folderQueue
        appendedList = []

        for url in sorted(arg):
            if os.path.exists(url) and os.path.isfile(url) and url.lower().endswith('.nk'):
                if url in folderQueue:
                    pass
                else:
                    appendedList.append(url)
                    folderQueue.append(url)
                    # Add table row
                    rowPosition = self.Queue_TW.rowCount()
                    self.Queue_TW.insertRow(rowPosition)
                    # get All Write Node from .nk
                    # QProcess for nuke
                    self.nukeProcess = QProcess(self)
                    self.nukeProcess.setProcessChannelMode(QProcess.MergedChannels)
                    args = self.createCmdArg(str(url))
                    self.nukeProcess.start(NUKE_EXE, args)
                    # For debug: read output lines
                    self.nukeProcess.readyRead.connect(self.NBR_debug)
                    self.nukeProcess.waitForFinished()
                    self.nukeProcess.close()
                    # Add row and info to table
                    self.NBR_createCheckBoxItemTableWidget(rowPosition, 0, os.path.splitext(os.path.basename(url))[0])
                    # Get the write nodes from text files (D:/Temp/nukeBatch)
                    layout = QtGui.QVBoxLayout()
                    layout.setAlignment(QtCore.Qt.AlignLeft)
                    with open("D:\\Temp\\nukeBatch\\" + os.path.basename(url) + ".txt", "r") as ins:
                        bframe = False
                        bCount = 0
                        for line in ins:
                            if 'FrameRange:' in line:
                                bframe = True
                                continue
                            if (bframe is False):
                                item = QtGui.QCheckBox(str(line).strip())
                                item.setChecked(True)
                                item.setFont(QtGui.QFont('meiryo', 9))
                                layout.addWidget(item)
                            elif (bframe is True):
                                self.NBR_createEditTextItemTableWidget(rowPosition, 2 + bCount, int(str(line).strip()))
                                bCount += 1

                    cellWidget = QtGui.QWidget()
                    cellWidget.setLayout(layout)
                    self.Queue_TW.setCellWidget(rowPosition, 1, cellWidget)
        self.Queue_TW.resizeRowsToContents()
        self.Queue_TW.scrollToBottom()
        QtGui.QApplication.processEvents()

    def createCmdArg(self, nk):  # nk = url
        return ["-ti", CHECKING_NK, nk]

    def createCmdArg2(self, nk, start, end, wnode=[]):
        return ["-ti", RENDER_NK, nk, wnode, start, end]

    def NBR_debug(self):
        while (self.nukeProcess.canReadLine()):
            print (str(self.nukeProcess.readLine()))

    def NBR_createCheckBoxItemTableWidget(self, row, col, text, color='#4c4c4c'):
        layout = QtGui.QVBoxLayout()
        layout.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)

        item = QtGui.QCheckBox(text)
        item.setChecked(True)
        item.setFont(QtGui.QFont('meiryo', 9))

        layout.addWidget(item)
        cellWidget = QtGui.QWidget()
        cellWidget.setStyleSheet('color:white; background-color:' + color)

        cellWidget.setLayout(layout)
        self.Queue_TW.setCellWidget(row, col, cellWidget)
        # self.Queue_TW.setItem(row, 0, QtGui.QTableWidgetItem(str(text)))

    def NBR_createEditTextItemTableWidget(self, row, col, text, color='#4c4c4c'):
        layout = QtGui.QVBoxLayout()
        layout.setAlignment(QtCore.Qt.AlignCenter)

        item = QtGui.QSpinBox()
        item.setMaximum(9999)
        item.setValue(text)
        item.setFont(QtGui.QFont('meiryo', 9))

        layout.addWidget(item)
        cellWidget = QtGui.QWidget()
        cellWidget.setStyleSheet('color:white; background-color:' + color)

        cellWidget.setLayout(layout)
        self.Queue_TW.setCellWidget(row, col, cellWidget)

    def NBR_getCellData(self, row, col, key):
        cellDict = {}
        target = self.Queue_TW.cellWidget(row, col)
        if target:
            lay = target.layout()
            if lay:
                for k in xrange(lay.count()):
                    w = lay.itemAt(k).widget()

                    if isinstance(w, QtGui.QCheckBox):
                        cellDict[key] = w.checkState()  # 0 false, > 0 true
                    elif isinstance(w, QtGui.QSpinBox):
                        cellDict[key] = w.value()
        return cellDict

    def NBR_getCellNodeData(self, row, col):
        target = self.Queue_TW.cellWidget(row, col)
        cellUserInputList = []
        if target:
            lay = target.layout()
            if lay:
                for k in xrange(lay.count()):
                    w = lay.itemAt(k).widget()

                    if isinstance(w, QtGui.QCheckBox):
                        cellUserInputList.append([str(w.text()), w.checkState()])
                    else:
                        cellUserInputList.append(-1)
        return cellUserInputList

    def NBR_render(self):
        global folderQueue
        for nk in xrange(len(folderQueue)):
            renderNode = []
            # proj = os.path.splitext(os.path.basename(folderQueue[nk]))[0]
            projDict = self.NBR_getCellData(nk, 0, 'Project')
            if int(projDict['Project']) > 0:
                nodeArr = self.NBR_getCellNodeData(nk, 1)
                startDict = self.NBR_getCellData(nk, 2, 'Start')
                endDict = self.NBR_getCellData(nk, 3, 'End')
                # Write nodes loop
                for node in xrange(len(nodeArr)):
                    if nodeArr[node][1] > 0:  # get each node check state (0/2), selected write node (render)
                        renderNode.append(nodeArr[node][0].split(":")[0])
                # Debug
                print str(renderNode)
                # print nodeArr
                self.nukeProcess = QProcess(self)    # QProcess for nuke
                print nodeArr[node][0].split(":")[0]  # get each node from array
                self.nukeProcess.setProcessChannelMode(QProcess.MergedChannels)
                args = self.createCmdArg2(str(folderQueue[nk]), renderNode, startDict['Start'], endDict['End'])
                self.nukeProcess.start(NUKE_EXE, str(args))
                self.nukeProcess.readyRead.connect(self.NBR_debug)
                self.nukeProcess.waitForFinished()
                self.nukeProcess.close()
コード例 #15
0
ファイル: pythonshell.py プロジェクト: cheesinglee/spyder
class ExternalPythonShell(ExternalShellBase):
    """External Shell widget: execute Python script in a separate process"""
    SHELL_CLASS = ExtPythonShellWidget
    def __init__(self, parent=None, fname=None, wdir=None, commands=[],
                 interact=False, debug=False, path=[],
                 ipython=False, arguments=None, stand_alone=True,
                 umd_enabled=True, umd_namelist=[], umd_verbose=True):
        self.namespacebrowser = None # namespace browser widget!
        
        self.fname = startup.__file__ if fname is None else fname
        
        self.stand_alone = stand_alone
        
        self.umd_enabled = umd_enabled
        self.umd_namelist = umd_namelist
        self.umd_verbose = umd_verbose
        
        self.namespacebrowser_button = None
        self.cwd_button = None
        self.terminate_button = None
        
        ExternalShellBase.__init__(self, parent, wdir,
                                   history_filename='.history.py')

        self.nsb_timer = QTimer(self) # Namespace browser auto-refresh timer
        self.nsb_timer.setInterval(3000)
        
        if arguments is not None:
            assert isinstance(arguments, basestring)
            self.arguments = arguments
        
        self.ipython = ipython
        if self.ipython:
            interact = False
        
        self.shell.set_externalshell(self)

        self.toggle_globals_explorer(False)
        self.interact_action.setChecked(interact)
        self.debug_action.setChecked(debug)
        
        self.monitor_socket = None
        self.interpreter = fname is None
        
        if self.interpreter:
            self.terminate_button.hide()
        
        self.commands = ["import sys", "sys.path.insert(0, '')"] + commands
        
        # Additional python path list
        self.path = path
        
    def closeEvent(self, event):
        ExternalShellBase.closeEvent(self, event)
        self.disconnect(self.nsb_timer, SIGNAL("timeout()"),
                        self.namespacebrowser.refresh_table)
        
    def get_toolbar_buttons(self):
        ExternalShellBase.get_toolbar_buttons(self)
        if self.namespacebrowser_button is None and self.stand_alone:
            self.namespacebrowser_button = create_toolbutton(self,
                          get_icon('dictedit.png'), self.tr("Variables"),
                          tip=self.tr("Show/hide global variables explorer"),
                          toggled=self.toggle_globals_explorer)
        if self.cwd_button is None:
            self.cwd_button = create_toolbutton(self,
                          get_std_icon('DirOpenIcon'), self.tr("Working directory"),
                          tip=self.tr("Set current working directory"),
                          triggered=self.set_current_working_directory)
        if self.terminate_button is None:
            self.terminate_button = create_toolbutton(self,
                          get_icon('terminate.png'), self.tr("Terminate"),
                          tip=self.tr("Attempts to terminate the process.\n"
                                      "The process may not exit as a result of "
                                      "clicking this button\n"
                                      "(it is given the chance to prompt "
                                      "the user for any unsaved files, etc)."))        
        buttons = [self.cwd_button]
        if self.namespacebrowser_button is not None:
            buttons.append(self.namespacebrowser_button)
        buttons += [self.run_button, self.options_button,
                    self.terminate_button, self.kill_button]
        return buttons

    def get_options_menu(self):
        self.interact_action = create_action(self, self.tr("Interact"))
        self.interact_action.setCheckable(True)
        self.debug_action = create_action(self, self.tr("Debug"))
        self.debug_action.setCheckable(True)
        self.args_action = create_action(self, self.tr("Arguments..."),
                                         triggered=self.get_arguments)
        return [self.interact_action, self.debug_action, self.args_action]

    def is_interpreter(self):
        """Return True if shellwidget is a Python/IPython interpreter"""
        return self.interpreter
        
    def set_namespacebrowser(self, namespacebrowser):
        """Set namespace browser *widget*"""
        self.namespacebrowser = namespacebrowser
        
    def get_shell_widget(self):
        if self.stand_alone:
            self.namespacebrowser = NamespaceBrowser(self)
            self.namespacebrowser.set_shellwidget(self)
            self.connect(self.namespacebrowser, SIGNAL('collapse()'),
                         lambda: self.toggle_globals_explorer(False))
            # Shell splitter
            self.splitter = splitter = QSplitter(Qt.Vertical, self)
            self.connect(self.splitter, SIGNAL('splitterMoved(int, int)'),
                         self.splitter_moved)
            splitter.addWidget(self.shell)
            splitter.setCollapsible(0, False)
            splitter.addWidget(self.namespacebrowser)
            splitter.setStretchFactor(0, 1)
            splitter.setStretchFactor(1, 0)
            splitter.setHandleWidth(5)
            splitter.setSizes([2, 1])
            return splitter
        else:
            return self.shell
    
    def get_icon(self):
        return get_icon('python.png')

    def set_buttons_runnning_state(self, state):
        ExternalShellBase.set_buttons_runnning_state(self, state)
        self.interact_action.setEnabled(not state and not self.interpreter)
        self.debug_action.setEnabled(not state and not self.interpreter)
        self.args_action.setEnabled(not state and
                                    (not self.interpreter or self.ipython))
        if state:
            if self.arguments:
                argstr = self.tr("Arguments: %1").arg(self.arguments)
            else:
                argstr = self.tr("No argument")
        else:
            argstr = self.tr("Arguments...")
        self.args_action.setText(argstr)
        self.terminate_button.setEnabled(state)
        if not state:
            self.toggle_globals_explorer(False)
        self.cwd_button.setEnabled(state)
        if self.namespacebrowser_button is not None:
            self.namespacebrowser_button.setEnabled(state)
    
    def create_process(self):
        self.shell.clear()
            
        self.process = QProcess(self)
        if self.ipython:
            self.process.setProcessChannelMode(QProcess.MergedChannels)
        else:
            self.process.setProcessChannelMode(QProcess.SeparateChannels)
        self.connect(self.shell, SIGNAL("wait_for_ready_read()"),
                     lambda: self.process.waitForReadyRead(250))
        
        # Working directory
        if self.wdir is not None:
            self.process.setWorkingDirectory(self.wdir)

        #-------------------------Python specific-------------------------------
        # Python arguments
        p_args = ['-u']
        if self.interact_action.isChecked():
            p_args.append('-i')
        if self.debug_action.isChecked():
            p_args.extend(['-m', 'pdb'])
        if os.name == 'nt':
            # When calling pdb on Windows, one has to double the backslashes 
            # to help Python escaping these characters (otherwise, for example,
            # '\t' will be interpreted as a tabulation):
            p_args.append(self.fname.replace(os.sep, os.sep*2))
        else:
            p_args.append(self.fname)
        
        env = self.process.systemEnvironment()
        
        # Monitor
        env.append('SHELL_ID=%s' % id(self))
        from spyderlib.widgets.externalshell.monitor import start_server
        server, port = start_server()
        self.notification_thread = server.register(str(id(self)), self)
        self.connect(self.notification_thread, SIGNAL('refresh()'),
                     self.namespacebrowser.refresh_table)
        env.append('SPYDER_PORT=%d' % port)
        
        # Python init commands (interpreter only)
        if self.commands and self.interpreter:
            env.append('PYTHONINITCOMMANDS=%s' % ';'.join(self.commands))
            self.process.setEnvironment(env)
        
        # User Module Deleter
        if self.interpreter:
            env.append('UMD_ENABLED=%r' % self.umd_enabled)
            env.append('UMD_NAMELIST=%s' % ','.join(self.umd_namelist))
            env.append('UMD_VERBOSE=%r' % self.umd_verbose)
        
        # IPython related configuration
        if self.ipython:
            env.append('IPYTHON=True')
            # Do not call msvcrt.getch in IPython.genutils.page_more:
            env.append('TERM=emacs')
            
        pathlist = []

        # Fix encoding with custom "sitecustomize.py"
        scpath = osp.dirname(osp.abspath(__file__))
        pathlist.append(scpath)
        
        # Adding Spyder path
        pathlist += self.path
        
        # Adding path list to PYTHONPATH environment variable
        add_pathlist_to_PYTHONPATH(env, pathlist)
        
        self.process.setEnvironment(env)
        #-------------------------Python specific-------------------------------
            
        if self.arguments:
            p_args.extend( self.arguments.split(' ') )
                        
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.write_output)
        self.connect(self.process, SIGNAL("readyReadStandardError()"),
                     self.write_error)
        self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)

        self.connect(self.terminate_button, SIGNAL("clicked()"),
                     self.process.terminate)
        self.connect(self.kill_button, SIGNAL("clicked()"),
                     self.process.kill)
        
        #-------------------------Python specific-------------------------------
        self.process.start(sys.executable, p_args)
        #-------------------------Python specific-------------------------------
            
        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, self.tr("Error"),
                                 self.tr("Process failed to start"))
        else:
            self.shell.setFocus()
            self.emit(SIGNAL('started()'))
            self.connect(self.nsb_timer, SIGNAL("timeout()"),
                         self.namespacebrowser.auto_refresh)
            self.nsb_timer.start()
            
        return self.process
    
#===============================================================================
#    Input/Output
#===============================================================================
    def write_error(self):
        #---This is apparently necessary only on Windows (not sure though):
        #   emptying standard output buffer before writing error output
        self.process.setReadChannel(QProcess.StandardOutput)
        if self.process.waitForReadyRead(1):
            self.write_output()
            
        self.shell.write_error(self.get_stderr())
        QApplication.processEvents()
        
    def send_to_process(self, qstr):
        if not isinstance(qstr, QString):
            qstr = QString(qstr)
        if not qstr.endsWith('\n'):
            qstr.append('\n')
        self.process.write(qstr.toLocal8Bit())
        self.process.waitForBytesWritten(-1)
        
        # Eventually write prompt faster (when hitting Enter continuously)
        # -- necessary/working on Windows only:
        if os.name == 'nt':
            self.write_error()
        
    def keyboard_interrupt(self):
        communicate(self.monitor_socket, "thread.interrupt_main()")
            
#===============================================================================
#    Globals explorer
#===============================================================================
    def toggle_globals_explorer(self, state):
        if self.stand_alone:
            self.splitter.setSizes([1, 1 if state else 0])
            self.namespacebrowser_button.setChecked(state)
            if state:
                self.namespacebrowser.refresh_table()
        
    def splitter_moved(self, pos, index):
        self.namespacebrowser_button.setChecked( self.splitter.sizes()[1] )

#===============================================================================
#    Current working directory
#===============================================================================
    def set_current_working_directory(self):
        cwd = self.shell.get_cwd()
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        directory = QFileDialog.getExistingDirectory(self,
                                             self.tr("Select directory"), cwd)
        if not directory.isEmpty():
            self.shell.set_cwd(unicode(directory))
        self.emit(SIGNAL('redirect_stdio(bool)'), True)
コード例 #16
0
class ExternalPythonShell(ExternalShellBase):
    """External Shell widget: execute Python script in a separate process"""
    SHELL_CLASS = ExtPyQsciShell

    def __init__(self,
                 parent=None,
                 fname=None,
                 wdir=None,
                 commands=[],
                 interact=False,
                 debug=False,
                 path=[]):
        ExternalShellBase.__init__(self,
                                   parent,
                                   wdir,
                                   history_filename='.history_ec.py')

        self.shell.set_externalshell(self)

        self.toggle_globals_explorer(False)
        self.interact_check.setChecked(interact)
        self.debug_check.setChecked(debug)

        self.monitor_socket = None
        self.interpreter = fname is None
        self.fname = startup.__file__ if fname is None else fname

        if self.interpreter:
            self.interact_check.hide()
            self.debug_check.hide()
            self.terminate_button.hide()

        self.commands = ["import sys", "sys.path.insert(0, '')"] + commands

        # Additional python path list
        self.path = path

    def get_toolbar_buttons(self):
        ExternalShellBase.get_toolbar_buttons(self)
        self.globalsexplorer_button = create_toolbutton(
            self,
            get_icon('dictedit.png'),
            self.tr("Variables"),
            tip=self.tr("Show/hide global variables explorer"),
            toggled=self.toggle_globals_explorer)
        self.terminate_button = create_toolbutton(
            self,
            get_icon('terminate.png'),
            self.tr("Terminate"),
            tip=self.tr("Attempts to terminate the process.\n"
                        "The process may not exit as a result of clicking "
                        "this button\n(it is given the chance to prompt "
                        "the user for any unsaved files, etc)."))
        self.interact_check = QCheckBox(self.tr("Interact"), self)
        self.debug_check = QCheckBox(self.tr("Debug"), self)
        return [
            self.interact_check, self.debug_check, self.globalsexplorer_button,
            self.run_button, self.terminate_button, self.kill_button
        ]

    def get_shell_widget(self):
        # Globals explorer
        self.globalsexplorer = GlobalsExplorer(self)
        self.connect(self.globalsexplorer, SIGNAL('collapse()'),
                     lambda: self.toggle_globals_explorer(False))

        # Shell splitter
        self.splitter = splitter = QSplitter(Qt.Vertical, self)
        self.connect(self.splitter, SIGNAL('splitterMoved(int, int)'),
                     self.splitter_moved)
        splitter.addWidget(self.shell)
        splitter.setCollapsible(0, False)
        splitter.addWidget(self.globalsexplorer)
        splitter.setStretchFactor(0, 2)
        splitter.setStretchFactor(1, 1)
        return splitter

    def get_icon(self):
        return get_icon('python.png')

    def set_buttons_runnning_state(self, state):
        ExternalShellBase.set_buttons_runnning_state(self, state)
        self.interact_check.setEnabled(not state)
        self.debug_check.setEnabled(not state)
        self.terminate_button.setEnabled(state)
        if not state:
            self.toggle_globals_explorer(False)
        self.globalsexplorer_button.setEnabled(state)

    def create_process(self):
        self.shell.clear()

        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.MergedChannels)
        self.connect(self.shell, SIGNAL("wait_for_ready_read()"),
                     lambda: self.process.waitForReadyRead(250))

        # Working directory
        if self.wdir is not None:
            self.process.setWorkingDirectory(self.wdir)

        #-------------------------Python specific-------------------------------
        # Python arguments
        p_args = ['-u']
        if self.interact_check.isChecked():
            p_args.append('-i')
        if self.debug_check.isChecked():
            p_args.extend(['-m', 'pdb'])
        p_args.append(self.fname)

        env = self.process.systemEnvironment()

        # Monitor
        env.append('SHELL_ID=%s' % id(self))
        from spyderlib.widgets.externalshell.monitor import start_server
        server, port = start_server()
        self.notification_thread = server.register(str(id(self)), self)
        self.connect(self.notification_thread, SIGNAL('refresh()'),
                     self.globalsexplorer.refresh_table)
        env.append('SPYDER_PORT=%d' % port)

        # Python init commands (interpreter only)
        if self.commands and self.interpreter:
            env.append('PYTHONINITCOMMANDS=%s' % ';'.join(self.commands))
            self.process.setEnvironment(env)

        pathlist = []

        # Fix encoding with custom "sitecustomize.py"
        scpath = osp.dirname(osp.abspath(__file__))
        pathlist.append(scpath)

        # Adding Spyder path
        pathlist += self.path

        # Adding path list to PYTHONPATH environment variable
        pypath = "PYTHONPATH"
        pathstr = os.pathsep.join(pathlist)
        if os.environ.get(pypath) is not None:
            env.replaceInStrings(pypath + '=',
                                 pypath + '=' + pathstr + os.pathsep,
                                 Qt.CaseSensitive)
        else:
            env.append(pypath + '=' + pathstr)
        self.process.setEnvironment(env)
        #-------------------------Python specific-------------------------------

        if self.arguments:
            p_args.extend(self.arguments.split(' '))

        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.write_output)
        self.connect(self.process,
                     SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)

        self.connect(self.terminate_button, SIGNAL("clicked()"),
                     self.process.terminate)
        self.connect(self.kill_button, SIGNAL("clicked()"), self.process.kill)

        #-------------------------Python specific-------------------------------
        self.process.start(sys.executable, p_args)
        #-------------------------Python specific-------------------------------

        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, self.tr("Error"),
                                 self.tr("Process failed to start"))
        else:
            self.shell.setFocus()
            self.emit(SIGNAL('started()'))

        return self.process

#===============================================================================
#    Input/Output
#===============================================================================

    def _write_error(self, text, findstr):
        pos = text.find(findstr)
        if pos != -1:
            self.shell.write(text[:pos])
            if text.endswith(">>> "):
                self.shell.write_error(text[pos:-5])
                self.shell.write(text[-5:], flush=True)
            else:
                self.shell.write_error(text[pos:])
            return True
        return False

    def write_output(self):
        text = self.get_stdout()
        if not self._write_error(text, 'Traceback (most recent call last):') \
           and not self._write_error(text, 'File "<stdin>", line 1'):
            self.shell.write(text)
        QApplication.processEvents()

    def send_to_process(self, qstr):
        if not isinstance(qstr, QString):
            qstr = QString(qstr)
        if not qstr.endsWith('\n'):
            qstr.append('\n')
        self.process.write(qstr.toLocal8Bit())
        self.process.waitForBytesWritten(-1)

    def keyboard_interrupt(self):
        communicate(self.monitor_socket, "thread.interrupt_main()")

#===============================================================================
#    Globals explorer
#===============================================================================

    def toggle_globals_explorer(self, state):
        self.splitter.setSizes([1, 1 if state else 0])
        self.globalsexplorer_button.setChecked(state)
        if state:
            self.globalsexplorer.refresh_table()

    def splitter_moved(self, pos, index):
        self.globalsexplorer_button.setChecked(self.splitter.sizes()[1])
コード例 #17
0
class ExternalSystemShell(ExternalShellBase):
    """External Shell widget: execute Python script in a separate process"""
    SHELL_CLASS = TerminalWidget
    def __init__(self, parent=None, wdir=None):
        ExternalShellBase.__init__(self, parent, wdir,
                                   history_filename='.history_ec')

    def get_icon(self):
        return get_icon('cmdprompt.png')
    
    def create_process(self):
        self.shell.clear()
            
        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.MergedChannels)
        
        # Working directory
        if self.wdir is not None:
            self.process.setWorkingDirectory(self.wdir)
            
        # Shell arguments
        if os.name == 'nt':
            p_args = ['/Q']
        else:
            p_args = ['-i']
            
        if self.arguments:
            p_args.extend( self.arguments.split(' ') )
                        
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.write_output)
        self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)
        
        self.connect(self.kill_button, SIGNAL("clicked()"),
                     self.process.kill)
        
        if os.name == 'nt':
            self.process.start('cmd.exe', p_args)
        else:
            # Using bash:
            self.process.start('bash', p_args)
            self.send_to_process("""PS1="\u@\h:\w> "\n""")
            
        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, self.tr("Error"),
                                 self.tr("Process failed to start"))
        else:
            self.shell.setFocus()
            self.emit(SIGNAL('started()'))
            
        return self.process
    
#===============================================================================
#    Input/Output
#===============================================================================
    def transcode(self, bytes):
        if os.name == 'nt':
            return encoding.transcode(str(bytes.data()), 'cp850')
        else:
            return ExternalShellBase.transcode(self, bytes)
    
    def send_to_process(self, qstr):
        if not isinstance(qstr, QString):
            qstr = QString(qstr)
        if qstr[:-1] in ["clear", "cls", "CLS"]:
            self.shell.clear()
            self.send_to_process(QString(os.linesep))
            return
        if not qstr.endsWith('\n'):
            qstr.append('\n')
        if os.name == 'nt':
            self.process.write(unicode(qstr).encode('cp850'))
        else:
            self.process.write(qstr.toLocal8Bit())
        self.process.waitForBytesWritten(-1)
        
    def keyboard_interrupt(self):
        # This does not work on Windows:
        # (unfortunately there is no easy way to send a Ctrl+C to cmd.exe)
        self.send_ctrl_to_process('c')

#        # The following code will soon be removed:
#        # (last attempt to send a Ctrl+C on Windows)
#        if os.name == 'nt':
#            pid = int(self.process.pid())
#            import ctypes, win32api, win32con
#            class _PROCESS_INFORMATION(ctypes.Structure):
#                _fields_ = [("hProcess", ctypes.c_int),
#                            ("hThread", ctypes.c_int),
#                            ("dwProcessID", ctypes.c_int),
#                            ("dwThreadID", ctypes.c_int)]
#            x = ctypes.cast( ctypes.c_void_p(pid),
#                             ctypes.POINTER(_PROCESS_INFORMATION) )
#            win32api.GenerateConsoleCtrlEvent(win32con.CTRL_C_EVENT,
#                                              x.dwProcessID)
#        else:
#            self.send_ctrl_to_process('c')
                
コード例 #18
0
ファイル: pythonshell.py プロジェクト: koll00/Gui_SM
class ExternalPythonShell(ExternalShellBase):
    """External Shell widget: execute Python script in a separate process"""
    SHELL_CLASS = ExtPythonShellWidget

    def __init__(self,
                 parent=None,
                 fname=None,
                 wdir=None,
                 interact=False,
                 debug=False,
                 path=[],
                 python_args='',
                 ipykernel=False,
                 arguments='',
                 stand_alone=None,
                 umd_enabled=True,
                 umd_namelist=[],
                 umd_verbose=True,
                 pythonstartup=None,
                 pythonexecutable=None,
                 monitor_enabled=True,
                 mpl_patch_enabled=True,
                 mpl_backend=None,
                 ets_backend='qt4',
                 qt_api=None,
                 pyqt_api=0,
                 install_qt_inputhook=True,
                 ignore_sip_setapi_errors=False,
                 merge_output_channels=False,
                 colorize_sys_stderr=False,
                 autorefresh_timeout=3000,
                 autorefresh_state=True,
                 light_background=True,
                 menu_actions=None,
                 show_buttons_inside=True,
                 show_elapsed_time=True):

        assert qt_api in (None, 'pyqt', 'pyside')

        self.namespacebrowser = None  # namespace browser widget!

        self.dialog_manager = DialogManager()

        self.stand_alone = stand_alone  # stand alone settings (None: plugin)
        self.pythonstartup = pythonstartup
        self.pythonexecutable = pythonexecutable
        self.monitor_enabled = monitor_enabled
        self.mpl_patch_enabled = mpl_patch_enabled
        self.mpl_backend = mpl_backend
        self.ets_backend = ets_backend
        self.qt_api = qt_api
        self.pyqt_api = pyqt_api
        self.install_qt_inputhook = install_qt_inputhook
        self.ignore_sip_setapi_errors = ignore_sip_setapi_errors
        self.merge_output_channels = merge_output_channels
        self.colorize_sys_stderr = colorize_sys_stderr
        self.umd_enabled = umd_enabled
        self.umd_namelist = umd_namelist
        self.umd_verbose = umd_verbose
        self.autorefresh_timeout = autorefresh_timeout
        self.autorefresh_state = autorefresh_state

        self.namespacebrowser_button = None
        self.cwd_button = None
        self.env_button = None
        self.syspath_button = None
        self.terminate_button = None

        self.notification_thread = None

        ExternalShellBase.__init__(self,
                                   parent=parent,
                                   fname=fname,
                                   wdir=wdir,
                                   history_filename='.history.py',
                                   light_background=light_background,
                                   menu_actions=menu_actions,
                                   show_buttons_inside=show_buttons_inside,
                                   show_elapsed_time=show_elapsed_time)

        if self.pythonexecutable is None:
            self.pythonexecutable = get_python_executable()

        self.python_args = None
        if python_args:
            assert isinstance(python_args, basestring)
            self.python_args = python_args

        assert isinstance(arguments, basestring)
        self.arguments = arguments

        self.connection_file = None
        self.is_ipykernel = ipykernel
        if self.is_ipykernel:
            interact = False
            # Running our custom startup script for IPython kernels:
            # (see spyderlib/widgets/externalshell/start_ipython_kernel.py)
            self.fname = get_module_source_path('SMlib.widgets.externalshell',
                                                'start_ipython_kernel.py')

        self.shell.set_externalshell(self)

        self.toggle_globals_explorer(False)
        self.interact_action.setChecked(interact)
        self.debug_action.setChecked(debug)

        self.introspection_socket = None
        self.is_interpreter = fname is None

        if self.is_interpreter:
            self.terminate_button.hide()

        # Additional python path list
        self.path = path
        self.shell.path = path

    def set_introspection_socket(self, introspection_socket):
        self.introspection_socket = introspection_socket
        if self.namespacebrowser is not None:
            settings = self.namespacebrowser.get_view_settings()
            communicate(introspection_socket,
                        'set_remote_view_settings()',
                        settings=[settings])

    def set_autorefresh_timeout(self, interval):
        if self.introspection_socket is not None:
            try:
                communicate(self.introspection_socket,
                            "set_monitor_timeout(%d)" % interval)
            except socket.error:
                pass

    def closeEvent(self, event):
        self.quit_monitor()
        ExternalShellBase.closeEvent(self, event)

    def get_toolbar_buttons(self):
        ExternalShellBase.get_toolbar_buttons(self)
        if self.namespacebrowser_button is None \
           and self.stand_alone is not None:
            self.namespacebrowser_button = create_toolbutton(
                self,
                text=_("Variables"),
                icon=get_icon('dictedit.png'),
                tip=_("Show/hide global variables explorer"),
                toggled=self.toggle_globals_explorer,
                text_beside_icon=True)
        if self.terminate_button is None:
            self.terminate_button = create_toolbutton(
                self,
                text=_("Terminate"),
                icon=get_icon('terminate.png'),
                tip=_("""Attempts to terminate the process.
The process may not exit as a result of clicking this button
(it is given the chance to prompt the user for any unsaved files, etc)."""))
        buttons = []
        if self.namespacebrowser_button is not None:
            buttons.append(self.namespacebrowser_button)
        buttons += [
            self.run_button, self.options_button, self.terminate_button,
            self.kill_button
        ]
        return buttons

    def get_options_menu(self):
        ExternalShellBase.get_options_menu(self)
        self.interact_action = create_action(self, _("Interact"))
        self.interact_action.setCheckable(True)
        self.debug_action = create_action(self, _("Debug"))
        self.debug_action.setCheckable(True)
        self.args_action = create_action(self,
                                         _("Arguments..."),
                                         triggered=self.get_arguments)
        run_settings_menu = QMenu(_("Run settings"), self)
        add_actions(
            run_settings_menu,
            (self.interact_action, self.debug_action, self.args_action))
        self.cwd_button = create_action(
            self,
            _("Working directory"),
            icon=get_std_icon('DirOpenIcon'),
            tip=_("Set current working directory"),
            triggered=self.set_current_working_directory)
        self.env_button = create_action(self,
                                        _("Environment variables"),
                                        icon=get_icon('environ.png'),
                                        triggered=self.show_env)
        self.syspath_button = create_action(self,
                                            _("Show sys.path contents"),
                                            icon=get_icon('syspath.png'),
                                            triggered=self.show_syspath)
        actions = [
            run_settings_menu, self.show_time_action, None, self.cwd_button,
            self.env_button, self.syspath_button
        ]
        if self.menu_actions is not None:
            actions += [None] + self.menu_actions
        return actions

    def is_interpreter(self):
        """Return True if shellwidget is a Python interpreter"""
        return self.is_interpreter

    def get_shell_widget(self):
        if self.stand_alone is None:
            return self.shell
        else:
            self.namespacebrowser = NamespaceBrowser(self)
            settings = self.stand_alone
            self.namespacebrowser.set_shellwidget(self)
            self.namespacebrowser.setup(**settings)
            self.connect(self.namespacebrowser, SIGNAL('collapse()'),
                         lambda: self.toggle_globals_explorer(False))
            # Shell splitter
            self.splitter = splitter = QSplitter(Qt.Vertical, self)
            self.connect(self.splitter, SIGNAL('splitterMoved(int, int)'),
                         self.splitter_moved)
            splitter.addWidget(self.shell)
            splitter.setCollapsible(0, False)
            splitter.addWidget(self.namespacebrowser)
            splitter.setStretchFactor(0, 1)
            splitter.setStretchFactor(1, 0)
            splitter.setHandleWidth(5)
            splitter.setSizes([2, 1])
            return splitter

    def get_icon(self):
        return get_icon('python.png')

    def set_buttons_runnning_state(self, state):
        ExternalShellBase.set_buttons_runnning_state(self, state)
        self.interact_action.setEnabled(not state and not self.is_interpreter)
        self.debug_action.setEnabled(not state and not self.is_interpreter)
        self.args_action.setEnabled(not state and not self.is_interpreter)
        if state:
            if self.arguments:
                argstr = _("Arguments: %s") % self.arguments
            else:
                argstr = _("No argument")
        else:
            argstr = _("Arguments...")
        self.args_action.setText(argstr)
        self.terminate_button.setVisible(not self.is_interpreter and state)
        if not state:
            self.toggle_globals_explorer(False)
        for btn in (self.cwd_button, self.env_button, self.syspath_button):
            btn.setEnabled(state and self.monitor_enabled)
        if self.namespacebrowser_button is not None:
            self.namespacebrowser_button.setEnabled(state)

    def set_namespacebrowser(self, namespacebrowser):
        """
        Set namespace browser *widget*
        Note: this method is not used in stand alone mode
        """
        self.namespacebrowser = namespacebrowser
        self.configure_namespacebrowser()

    def configure_namespacebrowser(self):
        """Connect the namespace browser to the notification thread"""
        if self.notification_thread is not None:
            self.connect(self.notification_thread,
                         SIGNAL('refresh_namespace_browser()'),
                         self.namespacebrowser.refresh_table)
            signal = self.notification_thread.sig_process_remote_view
            signal.connect(self.namespacebrowser.process_remote_view)

    def create_process(self):
        self.shell.clear()

        self.process = QProcess(self)
        if self.merge_output_channels:
            self.process.setProcessChannelMode(QProcess.MergedChannels)
        else:
            self.process.setProcessChannelMode(QProcess.SeparateChannels)
        self.connect(self.shell, SIGNAL("wait_for_ready_read()"),
                     lambda: self.process.waitForReadyRead(250))

        # Working directory
        if self.wdir is not None:
            self.process.setWorkingDirectory(self.wdir)

        #-------------------------Python specific-------------------------------
        # Python arguments
        p_args = ['-u']
        if DEBUG >= 3:
            p_args += ['-v']
        p_args += get_python_args(self.fname, self.python_args,
                                  self.interact_action.isChecked(),
                                  self.debug_action.isChecked(),
                                  self.arguments)

        env = [unicode(_path) for _path in self.process.systemEnvironment()]

        if self.pythonstartup:
            env.append('PYTHONSTARTUP=%s' % self.pythonstartup)

        # Monitor
        if self.monitor_enabled:
            env.append('SPYDER_SHELL_ID=%s' % id(self))
            env.append('SPYDER_AR_TIMEOUT=%d' % self.autorefresh_timeout)
            env.append('SPYDER_AR_STATE=%r' % self.autorefresh_state)
            from SMlib.widgets.externalshell import introspection
            introspection_server = introspection.start_introspection_server()
            introspection_server.register(self)
            notification_server = introspection.start_notification_server()
            self.notification_thread = notification_server.register(self)
            self.connect(
                self.notification_thread,
                SIGNAL('pdb(QString,int)'), lambda fname, lineno: self.emit(
                    SIGNAL('pdb(QString,int)'), fname, lineno))
            self.connect(
                self.notification_thread,
                SIGNAL('new_ipython_kernel(QString)'), lambda args: self.emit(
                    SIGNAL('create_ipython_client(QString)'), args))
            self.connect(
                self.notification_thread, SIGNAL('open_file(QString,int)'),
                lambda fname, lineno: self.emit(
                    SIGNAL('open_file(QString,int)'), fname, lineno))
            if self.namespacebrowser is not None:
                self.configure_namespacebrowser()
            env.append('SPYDER_I_PORT=%d' % introspection_server.port)
            env.append('SPYDER_N_PORT=%d' % notification_server.port)

        # External modules options
        env.append('ETS_TOOLKIT=%s' % self.ets_backend)
        env.append('MATPLOTLIB_PATCH=%r' % self.mpl_patch_enabled)
        if self.mpl_backend:
            env.append('MATPLOTLIB_BACKEND=%s' % self.mpl_backend)
        if self.qt_api:
            env.append('QT_API=%s' % self.qt_api)
        env.append('INSTALL_QT_INPUTHOOK=%s' % self.install_qt_inputhook)
        env.append('COLORIZE_SYS_STDERR=%s' % self.colorize_sys_stderr)
        #        # Socket-based alternative (see input hook in sitecustomize.py):
        #        if self.install_qt_inputhook:
        #            from PyQt4.QtNetwork import QLocalServer
        #            self.local_server = QLocalServer()
        #            self.local_server.listen(str(id(self)))
        if self.pyqt_api:
            env.append('PYQT_API=%d' % self.pyqt_api)
        env.append('IGNORE_SIP_SETAPI_ERRORS=%s' %
                   self.ignore_sip_setapi_errors)

        # User Module Deleter
        if self.is_interpreter:
            env.append('UMD_ENABLED=%r' % self.umd_enabled)
            env.append('UMD_NAMELIST=%s' % ','.join(self.umd_namelist))
            env.append('UMD_VERBOSE=%r' % self.umd_verbose)

        # IPython kernel
        env.append('IPYTHON_KERNEL=%r' % self.is_ipykernel)

        pathlist = []

        # Fix encoding with custom "sitecustomize.py"
        scpath = osp.dirname(osp.abspath(__file__))
        pathlist.append(scpath)

        # Adding Spyder path
        pathlist += self.path

        # Adding path list to PYTHONPATH environment variable
        add_pathlist_to_PYTHONPATH(env, pathlist)

        #-------------------------Python specific-------------------------------

        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.write_output)
        self.connect(self.process, SIGNAL("readyReadStandardError()"),
                     self.write_error)
        self.connect(self.process,
                     SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)

        self.connect(self, SIGNAL('finished()'), self.dialog_manager.close_all)

        self.connect(self.terminate_button, SIGNAL("clicked()"),
                     self.process.terminate)
        self.connect(self.kill_button, SIGNAL("clicked()"), self.process.kill)

        #-------------------------Python specific-------------------------------
        # Fixes for our Mac app:
        # 1. PYTHONPATH and PYTHONHOME are set while bootstrapping the app,
        #    but their values are messing sys.path for external interpreters
        #    (e.g. EPD) so we need to remove them from the environment.
        # 2. Add this file's dir to PYTHONPATH. This will make every external
        #    interpreter to use our sitecustomize script.
        # 3. Remove PYTHONOPTIMIZE from env so that we can have assert
        #    statements working with our interpreters (See Issue 1281)
        if sys.platform == 'darwin' and 'Spyder.app' in __file__:
            env.append('SPYDER_INTERPRETER=%s' % self.pythonexecutable)
            if 'Spyder.app' not in self.pythonexecutable:
                env = [p for p in env if not (p.startswith('PYTHONPATH') or \
                                              p.startswith('PYTHONHOME'))] # 1.

                env.append('PYTHONPATH=%s' % osp.dirname(__file__))  # 2.

            env = [p for p in env if not p.startswith('PYTHONOPTIMIZE')]  # 3.

        self.process.setEnvironment(env)
        self.process.start(self.pythonexecutable, p_args)
        #-------------------------Python specific-------------------------------

        running = self.process.waitForStarted(3000)
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(
                self, _("Error"),
                _("A Python or IPython Console failed to start!"))
        else:
            self.shell.setFocus()
            self.emit(SIGNAL('started()'))

        return self.process

    def finished(self, exit_code, exit_status):
        """Reimplement ExternalShellBase method"""
        ExternalShellBase.finished(self, exit_code, exit_status)
        self.introspection_socket = None

#===============================================================================
#    Input/Output
#===============================================================================

    def write_error(self):
        if os.name == 'nt':
            #---This is apparently necessary only on Windows (not sure though):
            #   emptying standard output buffer before writing error output
            self.process.setReadChannel(QProcess.StandardOutput)
            if self.process.waitForReadyRead(1):
                self.write_output()
        self.shell.write_error(self.get_stderr())
        QApplication.processEvents()

    def send_to_process(self, text):
        if not self.is_running():
            return

        if not isinstance(text, basestring):
            text = unicode(text)
        if self.install_qt_inputhook and self.introspection_socket is not None:
            communicate(self.introspection_socket,
                        "toggle_inputhook_flag(True)")
#            # Socket-based alternative (see input hook in sitecustomize.py):
#            while self.local_server.hasPendingConnections():
#                self.local_server.nextPendingConnection().write('go!')
        if text.startswith(('%', '!')):
            text = 'evalsc(r"%s")\n' % text
        if not text.endswith('\n'):
            text += '\n'
        self.process.write(locale_codec.fromUnicode(text))
        self.process.waitForBytesWritten(-1)

        # Eventually write prompt faster (when hitting Enter continuously)
        # -- necessary/working on Windows only:
        if os.name == 'nt':
            self.write_error()

    def keyboard_interrupt(self):
        if self.introspection_socket is not None:
            communicate(self.introspection_socket, "thread.interrupt_main()")

    def quit_monitor(self):
        if self.introspection_socket is not None:
            try:
                write_packet(self.introspection_socket, "thread.exit()")
            except socket.error:
                pass

#===============================================================================
#    Globals explorer
#===============================================================================

    def toggle_globals_explorer(self, state):
        if self.stand_alone is not None:
            self.splitter.setSizes([1, 1 if state else 0])
            self.namespacebrowser_button.setChecked(state)
            if state and self.namespacebrowser is not None:
                self.namespacebrowser.refresh_table()

    def splitter_moved(self, pos, index):
        self.namespacebrowser_button.setChecked(self.splitter.sizes()[1])

#===============================================================================
#    Misc.
#===============================================================================

    def set_current_working_directory(self):
        """Set current working directory"""
        cwd = self.shell.get_cwd()
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        directory = getexistingdirectory(self, _("Select directory"), cwd)
        if directory:
            self.shell.set_cwd(directory)
        self.emit(SIGNAL('redirect_stdio(bool)'), True)

    def show_env(self):
        """Show environment variables"""
        get_func = self.shell.get_env
        set_func = self.shell.set_env
        self.dialog_manager.show(RemoteEnvDialog(get_func, set_func))

    def show_syspath(self):
        """Show sys.path contents"""
        editor = DictEditor()
        editor.setup(self.shell.get_syspath(),
                     title="sys.path",
                     readonly=True,
                     width=600,
                     icon='syspath.png')
        self.dialog_manager.show(editor)
コード例 #19
0
class ExternalSystemShell(ExternalShellBase):
    """External Shell widget: execute Python script in a separate process"""
    SHELL_CLASS = TerminalWidget

    def __init__(self,
                 parent=None,
                 wdir=None,
                 path=[],
                 light_background=True,
                 menu_actions=None,
                 show_buttons_inside=True,
                 show_elapsed_time=True):
        ExternalShellBase.__init__(self,
                                   parent=parent,
                                   fname=None,
                                   wdir=wdir,
                                   history_filename='.history',
                                   light_background=light_background,
                                   menu_actions=menu_actions,
                                   show_buttons_inside=show_buttons_inside,
                                   show_elapsed_time=show_elapsed_time)

        # Additional python path list
        self.path = path

        # For compatibility with the other shells that can live in the external
        # console
        self.is_ipykernel = False
        self.connection_file = None

    def get_icon(self):
        return get_icon('cmdprompt.png')

    def create_process(self):
        self.shell.clear()

        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.MergedChannels)

        # PYTHONPATH (in case we use Python in this terminal, e.g. py2exe)
        env = [unicode(_path) for _path in self.process.systemEnvironment()]
        add_pathlist_to_PYTHONPATH(env, self.path)
        self.process.setEnvironment(env)

        # Working directory
        if self.wdir is not None:
            self.process.setWorkingDirectory(self.wdir)

        # Shell arguments
        if os.name == 'nt':
            p_args = ['/Q']
        else:
            p_args = ['-i']

        if self.arguments:
            p_args.extend(shell_split(self.arguments))

        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.write_output)
        self.connect(self.process,
                     SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)

        self.connect(self.kill_button, SIGNAL("clicked()"), self.process.kill)

        if os.name == 'nt':
            self.process.start('cmd.exe', p_args)
        else:
            # Using bash:
            self.process.start('bash', p_args)
            self.send_to_process("""PS1="\u@\h:\w> "\n""")

        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, _("Error"),
                                 _("Process failed to start"))
        else:
            self.shell.setFocus()
            self.emit(SIGNAL('started()'))

        return self.process

#===============================================================================
#    Input/Output
#===============================================================================

    def transcode(self, bytes):
        if os.name == 'nt':
            return encoding.transcode(str(bytes.data()), 'cp850')
        else:
            return ExternalShellBase.transcode(self, bytes)

    def send_to_process(self, text):
        if not isinstance(text, basestring):
            text = unicode(text)
        if text[:-1] in ["clear", "cls", "CLS"]:
            self.shell.clear()
            self.send_to_process(os.linesep)
            return
        if not text.endswith('\n'):
            text += '\n'
        if os.name == 'nt':
            self.process.write(text.encode('cp850'))
        else:
            self.process.write(locale_codec.fromUnicode(text))
        self.process.waitForBytesWritten(-1)

    def keyboard_interrupt(self):
        # This does not work on Windows:
        # (unfortunately there is no easy way to send a Ctrl+C to cmd.exe)
        self.send_ctrl_to_process('c')
コード例 #20
0
ファイル: mplayer.py プロジェクト: Ptaah/Ekd
class Mplayer(QDialog):

	REVENIR, PAS_PRECEDENT_SUIVANT, PRECEDENT_SUIVANT, CURSEUR_SUR_UNE_LIGNE,\
		CURSEUR_A_PART, PARCOURIR, PAS_PARCOURIR, LIST, RATIO = range(9)

	HAUTEUR, LARGEUR = range(2)

	def __init__(self, cheminVideo=[], taille=(250,225),
			choixWidget=(RATIO, REVENIR, PAS_PRECEDENT_SUIVANT,CURSEUR_SUR_UNE_LIGNE,PAS_PARCOURIR,LIST),
			debutFin=(0,0), cheminMPlayer=None, barreTaches=None, facteurLimitant=HAUTEUR,
			cheminParcourir=None, parent=None):

		"""widget mplayer"""
		QDialog.__init__(self, parent)

		#=== Paramètres généraux ===#
		self.setAttribute(Qt.WA_DeleteOnClose)
		self.setWindowTitle(_(u"Player vidéo"))
                #On réduit la marge pour gagner de l'espace
                self.setContentsMargins(0,0,0,0)

		self.systeme = os.name
                ### Quand EKD windows est installé, le chemin des dépendances sont ###########
                ### positionnées dans les variables d'environnement donc pas besoin de #######
                ### collecter le chemin des ces dépendances ##################################
                self.cheminMPlayer = "mplayer"

                ##############################################################################

		# liste de chemins vidéos
		if type(cheminVideo) != list :
			self.listeVideos=[cheminVideo]
		else :
			self.listeVideos = cheminVideo

		# est-ce que la vidéo est lue?
		self.estLue=False

		# est-ce que la vidéo est en pause?
		self.estEnPause=False

		self.debutFin = debutFin

		# Nom du fichier courant (le self n'est pas encore utile)
		txtParDefaut = u"Pas de fichier lu"
		if self.listeVideos.__len__()!=0:
			self.fichierCourant =  [txtParDefaut, self.listeVideos[0]]
		else: self.fichierCourant = [txtParDefaut, ""]

		# Barre des tâches de la fenêtre
		self.barreTaches = barreTaches

		# Taille de la vidéo
		self.tailleLargeur=taille[0]
		self.tailleHauteur=taille[1]

		# paramètres des boutons-icones
		iconTaille=22
		flat=1

		# Pour récupérer le temps courant depuis certains cadre
		self.temps = 0

		self.dureeTimer = 10 # temps en ms
		###############################################################################################################################

		#Pour être plus précis lors de la lecture, on prend comme unité la miliseconde. ######################
		## Il faut donc utiliser une echelle 1000 fois plus grande pour les unités du slider
		self.echelle=1000
		###############################################################################################################################

		# Permet de récupérer la durée de la vidéo depuis une instance de la classe
		# Sert dans certains cadres
		self.dureeVideo = 0

		# Chemin sur lequel peut s'ouvrir la boite de dialogue de fichier
		# associée au bouton parcourir
		self.cheminPourBoutonParcourir = cheminParcourir

		self.taille = taille

		debug("self.taille avant lecture : %s %s" % (self.taille, type(self.taille)))

		#=== Widgets ===#

		self.icone_lire=QIcon("Icones" + os.sep + "player_play.png")
		self.icone_pause=QIcon("Icones" + os.sep + "player_pause.png")
		self.icone_arret=QIcon("Icones" + os.sep + "player_stop.png")

		if Mplayer.REVENIR in choixWidget:
			self.bout_revenir = QPushButton(u"Revenir")
			self.bout_revenir.setIcon(QIcon("Icones" + os.sep + "revenir.png"))

		if Mplayer.PARCOURIR in choixWidget:
			self.bout_ouvVideo = QPushButton(u"Parcourir...")

		if Mplayer.PRECEDENT_SUIVANT in choixWidget:
			self.bout_prec = QPushButton(QIcon("Icones" + os.sep + "player_rew.png"),"")
			self.bout_prec.setIconSize(QSize(iconTaille, iconTaille))
			self.bout_prec.setFlat(flat)
			self.bout_suivant = QPushButton(QIcon("Icones" + os.sep + "player_fwd.png"),"")
			self.bout_suivant.setIconSize(QSize(iconTaille, iconTaille))
			self.bout_suivant.setFlat(flat)

		self.LISTW=False
		if Mplayer.LIST in choixWidget :
			self.LISTW = True
			self.listFichiers = QComboBox()
			self.listFichiers.hide()
			self.setListeVideo()


		self.bout_LectPause = QPushButton(self.icone_lire,"")
		self.bout_LectPause.setIconSize(QSize(iconTaille, iconTaille))
		self.bout_LectPause.setFlat(flat)

		self.bout_Arret = QPushButton(self.icone_arret,"")
		self.bout_Arret.setIconSize(QSize(iconTaille, iconTaille))
		self.bout_Arret.setFlat(flat)

		# widget qui contiendra la vidéo
		self.cibleVideo = DisplayVid(self)
		# par défaut le widget-cible est noir
		color = QColor(0, 0, 0)
		self.cibleVideo.setAutoFillBackground(True)
		self.cibleVideo.setPalette(QPalette(color))
		self.cibleVideo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
		self.cibleVideo.setFixedHeight(self.taille[1])
		self.cibleVideo.setToolTip(self.fichierCourant[0])

		#Choix de l'aspect ratio de la vidéo
                if Mplayer.RATIO in choixWidget :
                    self.conf = QGroupBox()
                    self.conf.setContentsMargins(0,0,0,0)
                    self.conf.setMinimumSize(QSize(self.tailleLargeur, 0))
                    self.conf.setObjectName("conf")
                    self.verticalLayout = QHBoxLayout(self.conf)
                    self.verticalLayout.setObjectName("verticalLayout")
                    self.choicenorm = QRadioButton(self.conf)
                    self.choicenorm.setObjectName("choicenorm")
                    self.verticalLayout.addWidget(self.choicenorm)
                    self.choicewide = QRadioButton(self.conf)
                    self.choicewide.setObjectName("choicewide")
                    self.verticalLayout.addWidget(self.choicewide)
                    self.choiceone = QRadioButton(self.conf)
                    self.choiceone.setObjectName("choiceone")
                    self.verticalLayout.addWidget(self.choiceone)
                    self.choicenorm.setText("4:3")
                    self.choicewide.setText("16:9")
                    self.choiceone.setText("w:h")
                # Checked le ratio de la vidéo
                if self.listeVideos.__len__()!=0:
                        self.changeRatio(self.listeVideos[0])
                else :
                        self.setRatio(4.0/3.0)
                        if Mplayer.RATIO in choixWidget :
                            self.choicenorm.setChecked(True)

		self.slider = QSlider(Qt.Horizontal)
		self.slider.setEnabled(True)

		self.mplayerProcess = QProcess(self)

		self.timer = QTimer(self)

		self.tempsChrono = TracerChrono()

		#=== mise-en-page/plan ===#
		mhbox = QHBoxLayout()
		vbox = QVBoxLayout()
		vbox.addWidget(self.cibleVideo)
                if Mplayer.RATIO in choixWidget :
                    vbox.addWidget(self.conf)
		hbox = QHBoxLayout()
		if Mplayer.REVENIR in choixWidget:
			hbox.addWidget(self.bout_revenir)
		if Mplayer.PARCOURIR in choixWidget:
			hbox.addWidget(self.bout_ouvVideo)
		hbox.addWidget(self.bout_LectPause)
		hbox.addWidget(self.bout_Arret)
		if Mplayer.PRECEDENT_SUIVANT in choixWidget:
			hbox.addWidget(self.bout_prec)
			hbox.addWidget(self.bout_suivant)
		hbox.addWidget(self.tempsChrono)
		if Mplayer.CURSEUR_A_PART not in choixWidget:
			hbox.addWidget(self.slider)
		vbox.addLayout(hbox)
		if Mplayer.CURSEUR_A_PART in choixWidget:
			hbox.setAlignment(Qt.AlignLeft)
			hbox = QHBoxLayout()
			hbox.addWidget(self.slider)
			vbox.addLayout(hbox)
		# Liste fichier dans combobox
		if self.LISTW :
			hbox = QHBoxLayout()
			hbox.addWidget(self.listFichiers)
			vbox.addLayout(hbox)

		mhbox.addLayout(vbox)
		self.setLayout(mhbox)

		#=== connexion des widgets à des fonctions ===#

		if Mplayer.REVENIR in choixWidget:
			self.connect(self.bout_revenir, SIGNAL('clicked()'), SLOT('close()'))
		if Mplayer.PARCOURIR in choixWidget:
			self.connect(self.bout_ouvVideo, SIGNAL('clicked()'), self.ouvrirVideo)
		if Mplayer.PRECEDENT_SUIVANT in choixWidget:
			self.connect(self.bout_prec, SIGNAL('clicked()'), self.precedent)
			self.connect(self.bout_suivant, SIGNAL('clicked()'), self.suivant)
		#Ajouté le 08/11/2009 - Liste des fichiers dans une combobox
		if self.LISTW :
			self.connect(self.listFichiers, SIGNAL('currentIndexChanged(int)'), self.changeVideo)
		self.connect(self.bout_LectPause, SIGNAL('clicked()'), self.lectPause)
		self.connect(self.bout_Arret, SIGNAL('clicked()'), self.arretMPlayer)
		self.connect(self.mplayerProcess, SIGNAL('readyReadStandardOutput()'), self.recupSortie)
		self.connect(self.mplayerProcess, SIGNAL('finished(int,QProcess::ExitStatus)'), self.finVideo)
		self.connect(self.timer, SIGNAL('timeout()'), self.sonderTempsActuel)
		self.connect(self.slider, SIGNAL('sliderMoved(int)'), self.changerTempsCurseur)
		self.connect(self.cibleVideo, SIGNAL('changeSize'), self.sizeMplayer)
                if Mplayer.RATIO in choixWidget :
                    self.connect(self.choicenorm, SIGNAL("clicked(bool)"), self.defRatio)
                    self.connect(self.choicewide, SIGNAL("clicked(bool)"), self.defRatio)
                    self.connect(self.choiceone, SIGNAL("clicked(bool)"), self.defRatio)

	def setListeVideo(self) :
		self.referenceVideo = []
		self.listFichiers.clear()
		for vid in self.listeVideos :
			self.referenceVideo.append(vid)
			self.listFichiers.addItem(os.path.basename(vid))
		if self.listeVideos.__len__() > 1 :
			self.listFichiers.show()

	def setAudio(self,au) :
		if au :
			self.cibleVideo.hide()
                        if "conf" in self.__dict__ :
			    self.conf.hide()
		else :
			self.cibleVideo.show()
                        if "conf" in self.__dict__ :
                            self.conf.show()
	def changeVideo(self, index) :
		self.arretMPlayer()
		if index >= 0 : # Condition ajoutée pour éviter une erreure de dépassement de range dans la liste.
			self.listeVideos = self.referenceVideo[index]
			self.listFichiers.setCurrentIndex(index)

	def defRatio(self, state=0) :
		if state :
			if self.choicenorm.isChecked() :
				self.setRatio(4.0/3.0)
			if self.choicewide.isChecked() :
				self.setRatio(16.0/9.0)
			if self.choiceone.isChecked() :
				try :
					dim=getVideoSize(unicode(self.listeVideos[0]))
					self.setRatio(dim[0]/dim[1])
				except :
					None
			self.defRatio()
		else :
			self.adjustSize()

	def setRatio(self,ratio) :
		self.ratio = ratio
		self.sizeMplayer()

	def changeRatio(self,video) :
		rv = getVideoRatio(video)
		if rv[0]==0.0 and type(rv[1])==float :
			rat = rv[1]
		else :
			rat = rv[0]

		if rat > 1.7 :
                        if "choicewide" in self.__dict__ :
                            self.choicewide.setChecked(True)
			self.setRatio(16.0/9.0)
		elif rat > 1.3 and rat <= 1.7 :
                        if "choicenorm" in self.__dict__ :
                            self.choicenorm.setChecked(True)
			self.setRatio(4.0/3.0)
		elif rat < 1.3 and rat != 0.0 :
                        if "choiceone" in self.__dict__ :
                            self.choiceone.setChecked(True)
			dim=getVideoSize(video)
			self.setRatio(dim[0]/dim[1])
		else :
                        if "choicenorm" in self.__dict__ :
                            self.choicenorm.setChecked(True)
			self.setRatio(4.0/3.0)

	def sizeMplayer(self) :
		self.cibleVideo.setFixedHeight(int(self.cibleVideo.width()/self.ratio))

	def ouvrirVideo(self):
		"""Ouverture de la boîte de dialogue de fichiers"""
		txt = u"Fichiers vidéo"
		if self.cheminPourBoutonParcourir:
			chemin = self.cheminPourBoutonParcourir

		else:
			try:
				chemin = EkdConfig.get('general','video_input_path').decode("UTF8")
			except:
				chemin = os.path.expanduser('~')

		liste=QFileDialog.getOpenFileNames(None, u"Ouvrir", chemin, "%s (*.avi *.mpg *.mpeg *.mjpeg *.flv *.mp4 *.ogg *.vob *.mov *.wmv *.3gp *.h264)\n*" %txt)
		if not liste: return
		self.listeVideos = liste
		self.changeRatio(unicode(self.listeVideos[0]))

		chemin = unicode(self.listeVideos[0])
		EkdConfig.set('general','video_input_path',os.path.dirname(chemin).encode("UTF8"))

	def setVideos(self, videos) :
		'''Définie proprement la liste des vidéos à jouer'''
		if type(videos) != list :
			self.listeVideos = [videos]
		else :
			self.listeVideos = videos
		if self.LISTW and videos.__len__() > 1 :
			self.setListeVideo()
		elif self.LISTW :
			self.listFichiers.hide()

	def demarrerMPlayer(self):
		"""démarrage de mplayer avec les arguments choisis"""
		if self.estLue:
			return True

		args = QStringList()	# Liste Qt qui contiendra les options de mplayer
					# Ajout d'options à liste: args << "-option"

		# mplayer fonctionnera comme un terminal dans ce script
		args << "-slave"
		# on ne veut pas avoir des commentaires sans grand intérêt
		args << "-quiet"

		# Sous linux, aucun driver n'a été nécessaire et pas de manip pour Wid :)
		if self.systeme=='posix':
			# try - except?
			# la fenêtre de mplayer restera attaché à la fenêtre
			# wid prend en valeur le nombre identifiant le widget (celui qui contiendra la vidéo)
			args << "-wid" << QString.number(self.cibleVideo.winId()) # Objet QString car args est une liste de ch de caractères
			settings = QSettings()
			videoOutput = settings.value("vo", QVariant('')).toString()
			if videoOutput:
				args << '-vo' << videoOutput

		# Sous windows
		else:
			# reinterpret_cast<qlonglong> obligatoire, winId() ne se laissant pas convertir gentiment ;)
			args << "-wid" << self.cibleVideo.winId().__hex__()
			args << "-vo" << "directx:noaccel"
			#args << "-vo" << "gl" # alternative

		# chemin de la vidéo
		args << self.listeVideos

		if PYQT_VERSION_STR >= "4.1.0":
			# mode de canal: on fusionne le canal de sortie normal (stdout) et celui des erreurs (stderr)
			self.mplayerProcess.setProcessChannelMode(QProcess.MergedChannels)
		# démarrage de mplayer (en tenant compte des arguments définis ci-dessus)
		# comme un nouveau processus
		self.mplayerProcess.start(self.cheminMPlayer, args)
		# au cas où mplayer ne démarrerait pas au bout de 3 sec (ex. problème de codec)
		if not self.mplayerProcess.waitForStarted(3000):
			QMessageBox.critical(self, u"Avertissement", u"Bogue au lancement de la vidéo avec mplayer")
			return False

		# donne le temps toutes les x secondes
		self.timer.start(self.dureeTimer)

		self.estLue = True

		return True

	def recupSortie(self):
		"""récupère les lignes d'information émises par QProcess (mplayerProcess) et en tire les conséquences"""
		while self.mplayerProcess.canReadLine(): # renvoie True si une ligne complète peut être lue à partir du système
			# stocker l'ensemble des bits d'une ligne
			tampon=QByteArray(self.mplayerProcess.readLine()) # readline: lit une ligne ascii à partir du système

			# On vérifie si on a eu des réponses
			if tampon.startsWith("Playing"):
				# On récupère les infos de base ('$ mplayer -input cmdlist' pour avoir la liste complète - file:///usr/share/doc/mplayer-doc/tech/slave.txt.gz pour plus de détails)
				self.mplayerProcess.write("get_video_resolution\n") # récupère la résolution de la vidéo
				self.mplayerProcess.write("get_time_length\n")
				# Nouveau fichier chargé -> on récupère son nom
				ind = tampon.length() - 2 # suppression du '.' à la fin
				tampon.remove(ind,ind)
				tampon.remove(0, 8) # vire Playing
				tampon.replace(QByteArray("\n"), QByteArray(""))
				tampon.replace(QByteArray("\r"), QByteArray(""))
				try:
					# Tour de passe-passe pour ne pas avoir de problème d'accents

					# Condition pour détection windows
					if os.name == 'nt':
						self.fichierCourant[1]=unicode(QString(tampon))
					# Condition pour détection Linux ou MacOSX
					elif os.name in ['posix', 'mac']:
						self.fichierCourant[1]=unicode(QString(tampon)).encode("Latin1").decode("UTF8")
				except UnicodeEncodeError, e:
					debug(e)
					self.fichierCourant[1]="?"
				self.cibleVideo.setToolTip(self.fichierCourant[1])
				if self.barreTaches is not None:
					self.barreTaches.showMessage(self.fichierCourant[1])

			# réponse à get_video_resolution : ANS_VIDEO_RESOLUTION='<width> x <height>'
			if tampon.startsWith("ANS_VIDEO_RESOLUTION"): # retourne True si l'ensemble de bits démarre avec "..."
				debug("tampon : %s" % tampon) # ex. -> ANS_VIDEO_RESOLUTION='352 x 288'
				tampon.remove(0, 21) # suppression des 21 1er caract -> '352 x 288'
				tampon.replace(QByteArray("'"), QByteArray("")) # -> 352 x 288
				tampon.replace(QByteArray(" "), QByteArray("")) # -> 352x288
				tampon.replace(QByteArray("\n"), QByteArray("")) # -> 352x288 # retour chariot unix
				tampon.replace(QByteArray("\r"), QByteArray("")) # -> 352x288 # retour chariot windows
				#print "-----tampon.indexOf('x') :", tampon.indexOf('x'), type(tampon.indexOf('x'))
				sepIndex = tampon.indexOf('x') # récupère la position de 'x' # 3 <type 'int'>
				#print "-----tampon.left(sepIndex).toInt():", tampon.left(sepIndex).toInt(), type(tampon.left(sepIndex).toInt())
				resX = tampon.left(sepIndex).toInt()[0] # -> 352 # (352, True) <type 'tuple'>
				#print "-----tampon.mid(sepIndex+1).toInt() :", tampon.mid(sepIndex+1).toInt(), type(tampon.mid(sepIndex+1).toInt())
				resY = tampon.mid(sepIndex+1).toInt()[0] # -> 288 # (288, True) <type 'tuple'>

				# on définit les nouvelles dimensions de l'image du widget-mplayer.
				# try pour éviter les bogues sur les fichiers audio (sans dimension d'image)!!!
				#try:
				if resX!=0 or resY!=0:
					debug( "ratio : %s - %s" % (self.ratio, type(self.ratio)))
				else:
					debug("fichier audio")

			# réponse à get_time_length : ANS_LENGTH=xx.yy
			elif tampon.startsWith("ANS_LENGTH"):
				debug("tampon : %s" % tampon) # -> ANS_LENGTH=279.38
				tampon.remove(0, 11) # vire ANS_LENGTH=
				tampon.replace(QByteArray("'"), QByteArray(""))
				tampon.replace(QByteArray(" "), QByteArray(""))
				tampon.replace(QByteArray("\n"), QByteArray(""))
				tampon.replace(QByteArray("\r"), QByteArray("")) # -> 279.38
				#print "-----tampon.toFloat() :", tampon.toFloat(), type(tampon.toFloat())
				tempsMax = tampon.toFloat()[0] # (279.3800048828125, True) <type 'tuple'>
				self.dureeVideo = tempsMax
				## Modifié le 28/05/2009 : On augmente la précision du slider
				#self.slider.setMaximum(tempsMax) # déf du domaine de valeur du curseur
				self.slider.setMaximum(tempsMax*self.echelle)

				# ATTENTION J'AI COMMENTE CETTE LIGNE !!!
				#self.slider.setMaximum(tempsMax)

			# réponse à get_time_pos : ANS_TIME_POSITION=xx.y
			elif tampon.startsWith("ANS_TIME_POSITION"):
				#print "tampon :",tampon # -> ANS_TIME_POSITION=1.4 (temps courant)
				tampon.remove(0, 18) # vire ANS_TIME_POSITION=
				tampon.replace(QByteArray("'"), QByteArray(""))
				tampon.replace(QByteArray(" "), QByteArray(""))
				tampon.replace(QByteArray("\n"), QByteArray(""))
				tampon.replace(QByteArray("\r"), QByteArray(""))
				#print "-----tampon.toFloat() :", tampon.toFloat(), type(tampon.toFloat())
				tempsCourant = tampon.toFloat()[0] # (1.3999999761581421, True) <type 'tuple'>
				# récupération du temps courant: utile dans certains cadres
				self.temps = tempsCourant
				# Programmer un arrêt. Utile pour les aperçus
				temps = float("%.1f" %self.temps)
				if self.debutFin!=(0,0) and self.debutFin[1]==temps:
					self.arretMPlayer()
					return
				self.slider.setValue(tempsCourant*self.echelle)
				#############################################################################
				self.changerTempsChrono(tempsCourant) # modifier le chrono du bouton
コード例 #21
0
ファイル: profilergui.py プロジェクト: sjara/spyder-profiler
class ProfilerWidget(QWidget):
    """
    Profiler widget
    """
    DATAPATH = get_conf_path('.profiler.results')
    VERSION = '0.0.1'
    
    def __init__(self, parent, max_entries=100):
        QWidget.__init__(self, parent)
        
        self.setWindowTitle("Profiler")
        
        self.output = None
        self.error_output = None
        
        self.filecombo = PythonModulesComboBox(self)
        
        self.start_button = create_toolbutton(self, icon=get_icon('run.png'),
                                    text=translate('Profiler', "Profile"),
                                    tip=translate('Profiler', "Run profiler"),
                                    triggered=self.start, text_beside_icon=True)
        self.stop_button = create_toolbutton(self,
                                    icon=get_icon('terminate.png'),
                                    text=translate('Profiler', "Stop"),
                                    tip=translate('Profiler',
                                                  "Stop current profiling"),
                                    text_beside_icon=True)
        self.connect(self.filecombo, SIGNAL('valid(bool)'),
                     self.start_button.setEnabled)
        #self.connect(self.filecombo, SIGNAL('valid(bool)'), self.show_data)
        # FIXME: The combobox emits this signal on almost any event
        #        triggering show_data() too early, too often. 

        browse_button = create_toolbutton(self, icon=get_icon('fileopen.png'),
                               tip=translate('Profiler', 'Select Python script'),
                               triggered=self.select_file)

        self.datelabel = QLabel()

        self.log_button = create_toolbutton(self, icon=get_icon('log.png'),
                                    text=translate('Profiler', "Output"),
                                    text_beside_icon=True,
                                    tip=translate('Profiler',
                                                  "Show program's output"),
                                    triggered=self.show_log)

        self.datatree = ProfilerDataTree(self)

        self.collapse_button = create_toolbutton(self, icon=get_icon('collapse.png'),
                                    triggered=lambda dD=-1:self.datatree.change_view(dD),
                                    tip='Collapse one level up')
        self.expand_button = create_toolbutton(self, icon=get_icon('expand.png'),
                                    triggered=lambda dD=1:self.datatree.change_view(dD),
                                    tip='Expand one level down')

        
        hlayout1 = QHBoxLayout()
        hlayout1.addWidget(self.filecombo)
        hlayout1.addWidget(browse_button)
        hlayout1.addWidget(self.start_button)
        hlayout1.addWidget(self.stop_button)

        hlayout2 = QHBoxLayout()
        hlayout2.addWidget(self.collapse_button)
        hlayout2.addWidget(self.expand_button)
        hlayout2.addStretch()
        hlayout2.addWidget(self.datelabel)
        hlayout2.addStretch()
        hlayout2.addWidget(self.log_button)
        
        layout = QVBoxLayout()
        layout.addLayout(hlayout1)
        layout.addLayout(hlayout2)
        layout.addWidget(self.datatree)
        self.setLayout(layout)
        
        self.process = None
        self.set_running_state(False)
        
        if not is_profiler_installed():
            for widget in (self.datatree, self.filecombo,
                           self.start_button, self.stop_button):
                widget.setDisabled(True)
            if os.name == 'nt' \
               and programs.is_module_installed("profile"):
                # The following is a comment from the pylint plugin:
                # Module is installed but script is not in PATH
                # (AFAIK, could happen only on Windows)
                text = translate('Profiler',
                     'Profiler script was not found. Please add "%s" to PATH.')
                text = unicode(text) % os.path.join(sys.prefix, "Scripts")
            else:
                text = translate('Profiler',
                    ('Please install the modules '+
                     '<b>profile</b> and <b>pstats</b>:'))
                # FIXME: need the actual website
                url = 'http://www.python.org'
                text += ' <a href=%s>%s</a>' % (url, url)
            self.datelabel.setText(text)
        else:
            pass # self.show_data()
                
    def analyze(self, filename):
        if not is_profiler_installed():
            return
        filename = unicode(filename) # filename is a QString instance
        self.kill_if_running()
        #index, _data = self.get_data(filename)
        index=None # FIXME: storing data is not implemented yet
        if index is None:
            self.filecombo.addItem(filename)
            self.filecombo.setCurrentIndex(self.filecombo.count()-1)
        else:
            self.filecombo.setCurrentIndex(self.filecombo.findText(filename))
        self.filecombo.selected()
        if self.filecombo.is_valid():
            self.start()
            
    def select_file(self):
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        filename = QFileDialog.getOpenFileName(self,
                      translate('Profiler', "Select Python script"), os.getcwdu(),
                      translate('Profiler', "Python scripts")+" (*.py ; *.pyw)")
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        if filename:
            self.analyze(filename)
        
    def show_log(self):
        if self.output:
            TextEditor(self.output, title=translate('Profiler', "Profiler output"),
                       readonly=True, size=(700, 500)).exec_()
    
    def show_errorlog(self):
        if self.error_output:
            TextEditor(self.error_output, title=translate('Profiler', "Profiler output"),
                       readonly=True, size=(700, 500)).exec_()
        
    def start(self):
        self.datelabel.setText('Profiling, please wait...')
        filename = unicode(self.filecombo.currentText())
        
        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.SeparateChannels)
        self.process.setWorkingDirectory(os.path.dirname(filename))
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.read_output)
        self.connect(self.process, SIGNAL("readyReadStandardError()"),
                     lambda: self.read_output(error=True))
        self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)
        self.connect(self.stop_button, SIGNAL("clicked()"),
                     self.process.kill)
        
        self.output = ''
        self.error_output = ''
        p_args = [os.path.basename(filename)]
        
        # FIXME: Use the system path to 'python' as opposed to hardwired
        p_args = ['-m', PROFILER_PATH, '-o', self.DATAPATH, os.path.basename(filename)]
        self.process.start('python', p_args)
        
        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, translate('Profiler', "Error"),
                                 translate('Profiler', "Process failed to start"))
    
    def set_running_state(self, state=True):
        self.start_button.setEnabled(not state)
        self.stop_button.setEnabled(state)
        
    def read_output(self, error=False):
        if error:
            self.process.setReadChannel(QProcess.StandardError)
        else:
            self.process.setReadChannel(QProcess.StandardOutput)
        bytes = QByteArray()
        while self.process.bytesAvailable():
            if error:
                bytes += self.process.readAllStandardError()
            else:
                bytes += self.process.readAllStandardOutput()
        text = unicode( QString.fromLocal8Bit(bytes.data()) )
        if error:
            self.error_output += text
        else:
            self.output += text
        
    def finished(self):
        self.set_running_state(False)
        self.show_errorlog()  # If errors occurred, show them.
        self.output = self.error_output + self.output
        # FIXME: figure out if show_data should be called here or
        #        as a signal from the combobox
        self.show_data(justanalyzed=True)
                
    def kill_if_running(self):
        if self.process is not None:
            if self.process.state() == QProcess.Running:
                self.process.kill()
                self.process.waitForFinished()
        
    def show_data(self, justanalyzed=False):
        if not justanalyzed:
            self.output = None
        self.log_button.setEnabled(self.output is not None \
                                   and len(self.output) > 0)
        self.kill_if_running()
        filename = unicode(self.filecombo.currentText())
        if not filename:
            return

        self.datatree.load_data(self.DATAPATH)
        self.datatree.show_tree()
            
        text_style = "<span style=\'color: #444444\'><b>%s </b></span>"
        date_text = text_style % time.strftime("%d %b %Y %H:%M",time.localtime())
        self.datelabel.setText(date_text)
コード例 #22
0
class serverwidget(QtGui.QFrame):
    def __init__(self, aname, apath):
        super(serverwidget, self).__init__()
        self.process = None
        self.path = apath
        self.name = aname
        self.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Sunken)
        title = QtGui.QLabel(self.name)
        startbutton = QtGui.QPushButton('START')
        killbutton = QtGui.QPushButton('TERMINATE')
        pingbutton = QtGui.QPushButton('PING')
        self.textfield = QtGui.QTextEdit()
        self.textfield.setReadOnly(True)
        startbutton.pressed.connect(self.start_server)
        killbutton.pressed.connect(self.kill_server)
        pingbutton.pressed.connect(self.ping_server)

        sublayout = QtGui.QVBoxLayout()
        sublayout.addWidget(title)
        sublayout.addWidget(startbutton)
        sublayout.addWidget(killbutton)
        sublayout.addWidget(pingbutton)
        sublayout.addWidget(self.textfield)
        self.setLayout(sublayout)

    def start_server(self):
        if self.process is None:
            self.process = QProcess()
            self.process.readyReadStandardOutput.connect(self.read_output)
            self.process.started.connect(
                lambda: self.write_message('Server started'))
            self.process.finished.connect(
                lambda: self.write_message('Server stopped'))
            self.process.setProcessChannelMode(QProcess.MergedChannels)
            self.process.setWorkingDirectory(os.path.dirname(self.path))
            self.process.start('python', [self.path])
        else:
            self.textfield.append(
                'Cannot start "{:}", as it is already running'.format(
                    self.name))

    def kill_server(self):
        if self.process is not None:
            self.process.terminate()
            self.process = None
        else:
            self.textfield.append(
                'Cannot terminate "{:}", as it is not running'.format(
                    self.name))

    def ping_server(self):
        if self.process is not None:
            state = self.process.state()
            msg = "PING: "
            if state == 0:
                msg += 'Process died'
            elif state == 1:
                msg += 'Process is starting up'
            elif state == 2:
                msg += 'Process is alive'
            self.textfield.append(msg)
            cnx = labrad.connect()
            labradserver = eval('cnx.{:}'.format(self.name))
            msg = 'PING: Labradserver is ' + labradserver.echo('alive')
            self.textfield.append(msg)
            cnx.disconnect()
        else:
            self.textfield.append('Cannot ping a server that is not started')

    def read_output(self):
        data = self.process.readAllStandardOutput()
        self.textfield.append(str(data))

    def write_message(self, message):
        self.textfield.append(message)
コード例 #23
0
ファイル: pylintgui.py プロジェクト: Brainsciences/luminoso
class PylintWidget(QWidget):
    """
    Pylint widget
    """
    DATAPATH = get_conf_path('.pylint.results')
    VERSION = '1.0.2'
    
    def __init__(self, parent, max_entries=100):
        QWidget.__init__(self, parent)
        
        self.output = None
        self.error_output = None
        
        self.max_entries = max_entries
        self.data = [self.VERSION]
        if osp.isfile(self.DATAPATH):
            try:
                data = cPickle.load(file(self.DATAPATH))
                if data[0] == self.VERSION:
                    self.data = data
            except EOFError:
                pass

        self.filecombo = PythonModulesComboBox(self)
        if self.data:
            self.remove_obsolete_items()
            self.filecombo.addItems(self.get_filenames())
        
        self.start_button = create_toolbutton(self, get_icon('run.png'),
                                    translate('Pylint', "Analyze"),
                                    tip=translate('Pylint', "Run analysis"),
                                    triggered=self.start)
        self.stop_button = create_toolbutton(self, get_icon('terminate.png'),
                                    translate('Pylint', "Stop"),
                                    tip=translate('Pylint',
                                                  "Stop current analysis"))
        self.connect(self.filecombo, SIGNAL('valid(bool)'),
                     self.start_button.setEnabled)
        self.connect(self.filecombo, SIGNAL('valid(bool)'), self.show_data)

        browse_button = create_toolbutton(self, get_icon('fileopen.png'),
                               tip=translate('Pylint', 'Select Python script'),
                               triggered=self.select_file)

        self.ratelabel = QLabel()
        self.datelabel = QLabel()
        self.log_button = create_toolbutton(self, get_icon('log.png'),
                                    translate('Pylint', "Output"),
                                    tip=translate('Pylint',
                                                  "Complete Pylint output"),
                                    triggered=self.show_log)
        self.treewidget = ResultsTree(self)
        
        hlayout1 = QHBoxLayout()
        hlayout1.addWidget(self.filecombo)
        hlayout1.addWidget(browse_button)
        hlayout1.addWidget(self.start_button)
        hlayout1.addWidget(self.stop_button)

        hlayout2 = QHBoxLayout()
        hlayout2.addWidget(self.ratelabel)
        hlayout2.addStretch()
        hlayout2.addWidget(self.datelabel)
        hlayout2.addStretch()
        hlayout2.addWidget(self.log_button)
        
        layout = QVBoxLayout()
        layout.addLayout(hlayout1)
        layout.addLayout(hlayout2)
        layout.addWidget(self.treewidget)
        self.setLayout(layout)
        
        self.process = None
        self.set_running_state(False)
        
        if not is_pylint_installed():
            for widget in (self.treewidget, self.filecombo,
                           self.start_button, self.stop_button):
                widget.setDisabled(True)
            text = translate('Pylint', 'Please install <b>pylint</b>:')
            url = 'http://www.logilab.fr'
            text += ' <a href=%s>%s</a>' % (url, url)
            self.ratelabel.setText(text)
        else:
            self.show_data()
        
    def analyze(self, filename):
        if not is_pylint_installed():
            return
        filename = unicode(filename) # filename is a QString instance
        self.kill_if_running()
        index, _data = self.get_data(filename)
        if index is None:
            self.filecombo.addItem(filename)
            self.filecombo.setCurrentIndex(self.filecombo.count()-1)
        else:
            self.filecombo.setCurrentIndex(index)
        self.filecombo.selected()
        if self.filecombo.is_valid():
            self.start()
            
    def select_file(self):
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        filename = QFileDialog.getOpenFileName(self,
                      translate('Pylint', "Select Python script"), os.getcwdu(),
                      translate('Pylint', "Python scripts")+" (*.py ; *.pyw)")
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        if filename:
            self.analyze(filename)
            
    def remove_obsolete_items(self):
        """Removing obsolete items"""
        self.data = [self.VERSION] + \
                    [(filename, data) for filename, data in self.data[1:]
                     if is_module_or_package(filename)]
        
    def get_filenames(self):
        return [filename for filename, _data in self.data[1:]]
    
    def get_data(self, filename):
        filename = osp.abspath(filename)
        for index, (fname, data) in enumerate(self.data[1:]):
            if fname == filename:
                return index, data
        else:
            return None, None
            
    def set_data(self, filename, data):
        filename = osp.abspath(filename)
        index, _data = self.get_data(filename)
        if index is not None:
            self.data.pop(index)
        self.data.append( (filename, data) )
        self.save()
        
    def set_max_entries(self, max_entries):
        self.max_entries = max_entries
        self.save()
        
    def save(self):
        while len(self.data) > self.max_entries+1:
            self.data.pop(1)
        cPickle.dump(self.data, file(self.DATAPATH, 'w'))
        
    def show_log(self):
        if self.output:
            TextEditor(self.output, title=translate('Pylint', "Pylint output"),
                       readonly=True, size=(700, 500)).exec_()
        
    def start(self):
        filename = unicode(self.filecombo.currentText())
        
        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.SeparateChannels)
        self.process.setWorkingDirectory(osp.dirname(filename))
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.read_output)
        self.connect(self.process, SIGNAL("readyReadStandardError()"),
                     lambda: self.read_output(error=True))
        self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)
        self.connect(self.stop_button, SIGNAL("clicked()"),
                     self.process.kill)
        
        self.output = ''
        self.error_output = ''
        p_args = [osp.basename(filename)]
        self.process.start(PYLINT_PATH, p_args)
        
        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, translate('Pylint', "Error"),
                                 translate('Pylint', "Process failed to start"))
    
    def set_running_state(self, state=True):
        self.start_button.setEnabled(not state)
        self.stop_button.setEnabled(state)
        
    def read_output(self, error=False):
        if error:
            self.process.setReadChannel(QProcess.StandardError)
        else:
            self.process.setReadChannel(QProcess.StandardOutput)
        bytes = QByteArray()
        while self.process.bytesAvailable():
            if error:
                bytes += self.process.readAllStandardError()
            else:
                bytes += self.process.readAllStandardOutput()
        text = unicode( QString.fromLocal8Bit(bytes.data()) )
        if error:
            self.error_output += text
        else:
            self.output += text
        
    def finished(self):
        self.set_running_state(False)
        if not self.output:
            return
        
        # Convention, Refactor, Warning, Error
        results = {'C:': [], 'R:': [], 'W:': [], 'E:': []}
        txt_module = '************* Module '
        
        module = '' # Should not be needed - just in case something goes wrong
        for line in self.output.splitlines():
            if line.startswith(txt_module):
                # New module
                module = line[len(txt_module):]
                continue
            for prefix in results:
                if line.startswith(prefix):
                    break
            else:
                continue
            i1 = line.find(':')
            if i1 == -1:
                continue
            i2 = line.find(':', i1+1)
            if i2 == -1:
                continue
            line_nb = line[i1+1:i2].strip()
            if not line_nb:
                continue
            line_nb = int(line_nb)
            message = line[i2+1:]
            item = (module, line_nb, message)
            results[line[:i1+1]].append(item)                
            
        # Rate
        rate = None
        txt_rate = 'Your code has been rated at '
        i_rate = self.output.find(txt_rate)
        if i_rate > 0:
            i_rate_end = self.output.find('/10', i_rate)
            if i_rate_end > 0:
                rate = self.output[i_rate+len(txt_rate):i_rate_end]
        
        # Previous run
        previous = ''
        if rate is not None:
            txt_prun = 'previous run: '
            i_prun = self.output.find(txt_prun, i_rate_end)
            if i_prun > 0:
                i_prun_end = self.output.find('/10', i_prun)
                previous = self.output[i_prun+len(txt_prun):i_prun_end]
            
        
        filename = unicode(self.filecombo.currentText())
        self.set_data(filename, (time.localtime(), rate, previous, results))
        self.output = self.error_output + self.output
        self.show_data(justanalyzed=True)
        
    def kill_if_running(self):
        if self.process is not None:
            if self.process.state() == QProcess.Running:
                self.process.kill()
                self.process.waitForFinished()
        
    def show_data(self, justanalyzed=False):
        if not justanalyzed:
            self.output = None
        self.log_button.setEnabled(self.output is not None \
                                   and len(self.output) > 0)
        self.kill_if_running()
        filename = unicode(self.filecombo.currentText())
        if not filename:
            return
        
        _index, data = self.get_data(filename)
        if data is None:
            text = translate('Pylint', 'Source code has not been rated yet.')
            self.treewidget.clear()
            date_text = ''
        else:
            datetime, rate, previous_rate, results = data
            if rate is None:
                text = translate('Pylint', 'Analysis did not succeed '
                                           '(see output for more details).')
                self.treewidget.clear()
                date_text = ''
            else:
                text_style = "<span style=\'color: #444444\'><b>%s </b></span>"
                rate_style = "<span style=\'color: %s\'><b>%s</b></span>"
                prevrate_style = "<span style=\'color: #666666\'>%s</span>"
                color = "#FF0000"
                if float(rate) > 5.:
                    color = "#22AA22"
                elif float(rate) > 3.:
                    color = "#EE5500"
                text = translate('Pylint', 'Global evaluation:')
                text = (text_style % text)+(rate_style % (color,
                                                          ('%s/10' % rate)))
                if previous_rate:
                    text_prun = translate('Pylint', 'previous run:')
                    text_prun = ' (%s %s/10)' % (text_prun, previous_rate)
                    text += prevrate_style % text_prun
                self.treewidget.set_results(filename, results)
                date_text = text_style % time.strftime("%d %b %Y %H:%M",
                                                       datetime)
            
        self.ratelabel.setText(text)
        self.datelabel.setText(date_text)
コード例 #24
0
class PylintWidget(QWidget):
    """
    Pylint widget
    """
    DATAPATH = get_conf_path('.pylint.results')
    VERSION = '1.0.2'

    def __init__(self, parent, max_entries=100):
        QWidget.__init__(self, parent)

        self.output = None
        self.error_output = None

        self.max_entries = max_entries
        self.data = [self.VERSION]
        if osp.isfile(self.DATAPATH):
            try:
                data = cPickle.load(file(self.DATAPATH))
                if data[0] == self.VERSION:
                    self.data = data
            except EOFError:
                pass

        self.filecombo = PythonModulesComboBox(self)
        if self.data:
            self.remove_obsolete_items()
            self.filecombo.addItems(self.get_filenames())

        self.start_button = create_toolbutton(self,
                                              get_icon('run.png'),
                                              translate('Pylint', "Analyze"),
                                              tip=translate(
                                                  'Pylint', "Run analysis"),
                                              triggered=self.start)
        self.stop_button = create_toolbutton(self,
                                             get_icon('terminate.png'),
                                             translate('Pylint', "Stop"),
                                             tip=translate(
                                                 'Pylint',
                                                 "Stop current analysis"))
        self.connect(self.filecombo, SIGNAL('valid(bool)'),
                     self.start_button.setEnabled)
        self.connect(self.filecombo, SIGNAL('valid(bool)'), self.show_data)

        browse_button = create_toolbutton(self,
                                          get_icon('fileopen.png'),
                                          tip=translate(
                                              'Pylint',
                                              'Select Python script'),
                                          triggered=self.select_file)

        self.ratelabel = QLabel()
        self.datelabel = QLabel()
        self.log_button = create_toolbutton(self,
                                            get_icon('log.png'),
                                            translate('Pylint', "Output"),
                                            tip=translate(
                                                'Pylint',
                                                "Complete Pylint output"),
                                            triggered=self.show_log)
        self.treewidget = ResultsTree(self)

        hlayout1 = QHBoxLayout()
        hlayout1.addWidget(self.filecombo)
        hlayout1.addWidget(browse_button)
        hlayout1.addWidget(self.start_button)
        hlayout1.addWidget(self.stop_button)

        hlayout2 = QHBoxLayout()
        hlayout2.addWidget(self.ratelabel)
        hlayout2.addStretch()
        hlayout2.addWidget(self.datelabel)
        hlayout2.addStretch()
        hlayout2.addWidget(self.log_button)

        layout = QVBoxLayout()
        layout.addLayout(hlayout1)
        layout.addLayout(hlayout2)
        layout.addWidget(self.treewidget)
        self.setLayout(layout)

        self.process = None
        self.set_running_state(False)

        if not is_pylint_installed():
            for widget in (self.treewidget, self.filecombo, self.start_button,
                           self.stop_button):
                widget.setDisabled(True)
            text = translate('Pylint', 'Please install <b>pylint</b>:')
            url = 'http://www.logilab.fr'
            text += ' <a href=%s>%s</a>' % (url, url)
            self.ratelabel.setText(text)
        else:
            self.show_data()

    def analyze(self, filename):
        if not is_pylint_installed():
            return
        filename = unicode(filename)  # filename is a QString instance
        self.kill_if_running()
        index, _data = self.get_data(filename)
        if index is None:
            self.filecombo.addItem(filename)
            self.filecombo.setCurrentIndex(self.filecombo.count() - 1)
        else:
            self.filecombo.setCurrentIndex(index)
        self.filecombo.selected()
        if self.filecombo.is_valid():
            self.start()

    def select_file(self):
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        filename = QFileDialog.getOpenFileName(
            self, translate('Pylint', "Select Python script"), os.getcwdu(),
            translate('Pylint', "Python scripts") + " (*.py ; *.pyw)")
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        if filename:
            self.analyze(filename)

    def remove_obsolete_items(self):
        """Removing obsolete items"""
        self.data = [self.VERSION] + \
                    [(filename, data) for filename, data in self.data[1:]
                     if is_module_or_package(filename)]

    def get_filenames(self):
        return [filename for filename, _data in self.data[1:]]

    def get_data(self, filename):
        filename = osp.abspath(filename)
        for index, (fname, data) in enumerate(self.data[1:]):
            if fname == filename:
                return index, data
        else:
            return None, None

    def set_data(self, filename, data):
        filename = osp.abspath(filename)
        index, _data = self.get_data(filename)
        if index is not None:
            self.data.pop(index)
        self.data.append((filename, data))
        self.save()

    def set_max_entries(self, max_entries):
        self.max_entries = max_entries
        self.save()

    def save(self):
        while len(self.data) > self.max_entries + 1:
            self.data.pop(1)
        cPickle.dump(self.data, file(self.DATAPATH, 'w'))

    def show_log(self):
        if self.output:
            TextEditor(self.output,
                       title=translate('Pylint', "Pylint output"),
                       readonly=True,
                       size=(700, 500)).exec_()

    def start(self):
        filename = unicode(self.filecombo.currentText())

        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.SeparateChannels)
        self.process.setWorkingDirectory(osp.dirname(filename))
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.read_output)
        self.connect(self.process, SIGNAL("readyReadStandardError()"),
                     lambda: self.read_output(error=True))
        self.connect(self.process,
                     SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)
        self.connect(self.stop_button, SIGNAL("clicked()"), self.process.kill)

        self.output = ''
        self.error_output = ''
        p_args = [osp.basename(filename)]
        self.process.start(PYLINT_PATH, p_args)

        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(
                self, translate('Pylint', "Error"),
                translate('Pylint', "Process failed to start"))

    def set_running_state(self, state=True):
        self.start_button.setEnabled(not state)
        self.stop_button.setEnabled(state)

    def read_output(self, error=False):
        if error:
            self.process.setReadChannel(QProcess.StandardError)
        else:
            self.process.setReadChannel(QProcess.StandardOutput)
        bytes = QByteArray()
        while self.process.bytesAvailable():
            if error:
                bytes += self.process.readAllStandardError()
            else:
                bytes += self.process.readAllStandardOutput()
        text = unicode(QString.fromLocal8Bit(bytes.data()))
        if error:
            self.error_output += text
        else:
            self.output += text

    def finished(self):
        self.set_running_state(False)
        if not self.output:
            return

        # Convention, Refactor, Warning, Error
        results = {'C:': [], 'R:': [], 'W:': [], 'E:': []}
        txt_module = '************* Module '

        module = ''  # Should not be needed - just in case something goes wrong
        for line in self.output.splitlines():
            if line.startswith(txt_module):
                # New module
                module = line[len(txt_module):]
                continue
            for prefix in results:
                if line.startswith(prefix):
                    break
            else:
                continue
            i1 = line.find(':')
            if i1 == -1:
                continue
            i2 = line.find(':', i1 + 1)
            if i2 == -1:
                continue
            line_nb = line[i1 + 1:i2].strip()
            if not line_nb:
                continue
            line_nb = int(line_nb)
            message = line[i2 + 1:]
            item = (module, line_nb, message)
            results[line[:i1 + 1]].append(item)

        # Rate
        rate = None
        txt_rate = 'Your code has been rated at '
        i_rate = self.output.find(txt_rate)
        if i_rate > 0:
            i_rate_end = self.output.find('/10', i_rate)
            if i_rate_end > 0:
                rate = self.output[i_rate + len(txt_rate):i_rate_end]

        # Previous run
        previous = ''
        if rate is not None:
            txt_prun = 'previous run: '
            i_prun = self.output.find(txt_prun, i_rate_end)
            if i_prun > 0:
                i_prun_end = self.output.find('/10', i_prun)
                previous = self.output[i_prun + len(txt_prun):i_prun_end]

        filename = unicode(self.filecombo.currentText())
        self.set_data(filename, (time.localtime(), rate, previous, results))
        self.output = self.error_output + self.output
        self.show_data(justanalyzed=True)

    def kill_if_running(self):
        if self.process is not None:
            if self.process.state() == QProcess.Running:
                self.process.kill()
                self.process.waitForFinished()

    def show_data(self, justanalyzed=False):
        if not justanalyzed:
            self.output = None
        self.log_button.setEnabled(self.output is not None \
                                   and len(self.output) > 0)
        self.kill_if_running()
        filename = unicode(self.filecombo.currentText())
        if not filename:
            return

        _index, data = self.get_data(filename)
        if data is None:
            text = translate('Pylint', 'Source code has not been rated yet.')
            self.treewidget.clear()
            date_text = ''
        else:
            datetime, rate, previous_rate, results = data
            if rate is None:
                text = translate(
                    'Pylint', 'Analysis did not succeed '
                    '(see output for more details).')
                self.treewidget.clear()
                date_text = ''
            else:
                text_style = "<span style=\'color: #444444\'><b>%s </b></span>"
                rate_style = "<span style=\'color: %s\'><b>%s</b></span>"
                prevrate_style = "<span style=\'color: #666666\'>%s</span>"
                color = "#FF0000"
                if float(rate) > 5.:
                    color = "#22AA22"
                elif float(rate) > 3.:
                    color = "#EE5500"
                text = translate('Pylint', 'Global evaluation:')
                text = (text_style % text) + (rate_style % (color,
                                                            ('%s/10' % rate)))
                if previous_rate:
                    text_prun = translate('Pylint', 'previous run:')
                    text_prun = ' (%s %s/10)' % (text_prun, previous_rate)
                    text += prevrate_style % text_prun
                self.treewidget.set_results(filename, results)
                date_text = text_style % time.strftime("%d %b %Y %H:%M",
                                                       datetime)

        self.ratelabel.setText(text)
        self.datelabel.setText(date_text)
コード例 #25
0
ファイル: pythonshell.py プロジェクト: koll00/Gui_SM
class ExternalPythonShell(ExternalShellBase):
    """External Shell widget: execute Python script in a separate process"""
    SHELL_CLASS = ExtPythonShellWidget
    def __init__(self, parent=None, fname=None, wdir=None,
                 interact=False, debug=False, path=[], python_args='',
                 ipykernel=False, arguments='', stand_alone=None,
                 umd_enabled=True, umd_namelist=[], umd_verbose=True,
                 pythonstartup=None, pythonexecutable=None,
                 monitor_enabled=True, mpl_patch_enabled=True,
                 mpl_backend=None, ets_backend='qt4', qt_api=None, pyqt_api=0,
                 install_qt_inputhook=True, ignore_sip_setapi_errors=False,
                 merge_output_channels=False, colorize_sys_stderr=False,
                 autorefresh_timeout=3000, autorefresh_state=True,
                 light_background=True, menu_actions=None,
                 show_buttons_inside=True, show_elapsed_time=True):

        assert qt_api in (None, 'pyqt', 'pyside')

        self.namespacebrowser = None # namespace browser widget!
        
        self.dialog_manager = DialogManager()
        
        self.stand_alone = stand_alone # stand alone settings (None: plugin)
        self.pythonstartup = pythonstartup
        self.pythonexecutable = pythonexecutable
        self.monitor_enabled = monitor_enabled
        self.mpl_patch_enabled = mpl_patch_enabled
        self.mpl_backend = mpl_backend
        self.ets_backend = ets_backend
        self.qt_api = qt_api
        self.pyqt_api = pyqt_api
        self.install_qt_inputhook = install_qt_inputhook
        self.ignore_sip_setapi_errors = ignore_sip_setapi_errors
        self.merge_output_channels = merge_output_channels
        self.colorize_sys_stderr = colorize_sys_stderr
        self.umd_enabled = umd_enabled
        self.umd_namelist = umd_namelist
        self.umd_verbose = umd_verbose
        self.autorefresh_timeout = autorefresh_timeout
        self.autorefresh_state = autorefresh_state
                
        self.namespacebrowser_button = None
        self.cwd_button = None
        self.env_button = None
        self.syspath_button = None
        self.terminate_button = None

        self.notification_thread = None
        
        ExternalShellBase.__init__(self, parent=parent, fname=fname, wdir=wdir,
                                   history_filename='.history.py',
                                   light_background=light_background,
                                   menu_actions=menu_actions,
                                   show_buttons_inside=show_buttons_inside,
                                   show_elapsed_time=show_elapsed_time)

        if self.pythonexecutable is None:
            self.pythonexecutable = get_python_executable()

        self.python_args = None
        if python_args:
            assert isinstance(python_args, basestring)
            self.python_args = python_args
        
        assert isinstance(arguments, basestring)
        self.arguments = arguments
        
        self.connection_file = None
        self.is_ipykernel = ipykernel
        if self.is_ipykernel:
            interact = False
            # Running our custom startup script for IPython kernels:
            # (see spyderlib/widgets/externalshell/start_ipython_kernel.py)
            self.fname = get_module_source_path(
                'SMlib.widgets.externalshell', 'start_ipython_kernel.py')
        
        self.shell.set_externalshell(self)

        self.toggle_globals_explorer(False)
        self.interact_action.setChecked(interact)
        self.debug_action.setChecked(debug)
        
        self.introspection_socket = None
        self.is_interpreter = fname is None
        
        if self.is_interpreter:
            self.terminate_button.hide()
        
        # Additional python path list
        self.path = path
        self.shell.path = path
        
    def set_introspection_socket(self, introspection_socket):
        self.introspection_socket = introspection_socket
        if self.namespacebrowser is not None:
            settings = self.namespacebrowser.get_view_settings()
            communicate(introspection_socket,
                        'set_remote_view_settings()', settings=[settings])
        
    def set_autorefresh_timeout(self, interval):
        if self.introspection_socket is not None:
            try:
                communicate(self.introspection_socket,
                            "set_monitor_timeout(%d)" % interval)
            except socket.error:
                pass
        
    def closeEvent(self, event):
        self.quit_monitor()
        ExternalShellBase.closeEvent(self, event)
        
    def get_toolbar_buttons(self):
        ExternalShellBase.get_toolbar_buttons(self)
        if self.namespacebrowser_button is None \
           and self.stand_alone is not None:
            self.namespacebrowser_button = create_toolbutton(self,
                  text=_("Variables"), icon=get_icon('dictedit.png'),
                  tip=_("Show/hide global variables explorer"),
                  toggled=self.toggle_globals_explorer, text_beside_icon=True)
        if self.terminate_button is None:
            self.terminate_button = create_toolbutton(self,
                  text=_("Terminate"), icon=get_icon('terminate.png'),
                  tip=_("""Attempts to terminate the process.
The process may not exit as a result of clicking this button
(it is given the chance to prompt the user for any unsaved files, etc)."""))
        buttons = []
        if self.namespacebrowser_button is not None:
            buttons.append(self.namespacebrowser_button)
        buttons += [self.run_button, self.options_button,
                    self.terminate_button, self.kill_button]
        return buttons

    def get_options_menu(self):
        ExternalShellBase.get_options_menu(self)
        self.interact_action = create_action(self, _("Interact"))
        self.interact_action.setCheckable(True)
        self.debug_action = create_action(self, _("Debug"))
        self.debug_action.setCheckable(True)
        self.args_action = create_action(self, _("Arguments..."),
                                         triggered=self.get_arguments)
        run_settings_menu = QMenu(_("Run settings"), self)
        add_actions(run_settings_menu,
                    (self.interact_action, self.debug_action, self.args_action))
        self.cwd_button = create_action(self, _("Working directory"),
                                icon=get_std_icon('DirOpenIcon'),
                                tip=_("Set current working directory"),
                                triggered=self.set_current_working_directory)
        self.env_button = create_action(self, _("Environment variables"),
                                        icon=get_icon('environ.png'),
                                        triggered=self.show_env)
        self.syspath_button = create_action(self,
                                            _("Show sys.path contents"),
                                            icon=get_icon('syspath.png'),
                                            triggered=self.show_syspath)
        actions = [run_settings_menu, self.show_time_action, None,
                   self.cwd_button, self.env_button, self.syspath_button]
        if self.menu_actions is not None:
            actions += [None]+self.menu_actions
        return actions

    def is_interpreter(self):
        """Return True if shellwidget is a Python interpreter"""
        return self.is_interpreter
        
    def get_shell_widget(self):
        if self.stand_alone is None:
            return self.shell
        else:
            self.namespacebrowser = NamespaceBrowser(self)
            settings = self.stand_alone
            self.namespacebrowser.set_shellwidget(self)
            self.namespacebrowser.setup(**settings)
            self.connect(self.namespacebrowser, SIGNAL('collapse()'),
                         lambda: self.toggle_globals_explorer(False))
            # Shell splitter
            self.splitter = splitter = QSplitter(Qt.Vertical, self)
            self.connect(self.splitter, SIGNAL('splitterMoved(int, int)'),
                         self.splitter_moved)
            splitter.addWidget(self.shell)
            splitter.setCollapsible(0, False)
            splitter.addWidget(self.namespacebrowser)
            splitter.setStretchFactor(0, 1)
            splitter.setStretchFactor(1, 0)
            splitter.setHandleWidth(5)
            splitter.setSizes([2, 1])
            return splitter
    
    def get_icon(self):
        return get_icon('python.png')

    def set_buttons_runnning_state(self, state):
        ExternalShellBase.set_buttons_runnning_state(self, state)
        self.interact_action.setEnabled(not state and not self.is_interpreter)
        self.debug_action.setEnabled(not state and not self.is_interpreter)
        self.args_action.setEnabled(not state and not self.is_interpreter)
        if state:
            if self.arguments:
                argstr = _("Arguments: %s") % self.arguments
            else:
                argstr = _("No argument")
        else:
            argstr = _("Arguments...")
        self.args_action.setText(argstr)
        self.terminate_button.setVisible(not self.is_interpreter and state)
        if not state:
            self.toggle_globals_explorer(False)
        for btn in (self.cwd_button, self.env_button, self.syspath_button):
            btn.setEnabled(state and self.monitor_enabled)
        if self.namespacebrowser_button is not None:
            self.namespacebrowser_button.setEnabled(state)
    
    def set_namespacebrowser(self, namespacebrowser):
        """
        Set namespace browser *widget*
        Note: this method is not used in stand alone mode
        """
        self.namespacebrowser = namespacebrowser
        self.configure_namespacebrowser()
        
    def configure_namespacebrowser(self):
        """Connect the namespace browser to the notification thread"""
        if self.notification_thread is not None:
            self.connect(self.notification_thread,
                         SIGNAL('refresh_namespace_browser()'),
                         self.namespacebrowser.refresh_table)
            signal = self.notification_thread.sig_process_remote_view
            signal.connect(self.namespacebrowser.process_remote_view)
    
    def create_process(self):
        self.shell.clear()
            
        self.process = QProcess(self)
        if self.merge_output_channels:
            self.process.setProcessChannelMode(QProcess.MergedChannels)
        else:
            self.process.setProcessChannelMode(QProcess.SeparateChannels)
        self.connect(self.shell, SIGNAL("wait_for_ready_read()"),
                     lambda: self.process.waitForReadyRead(250))
        
        # Working directory
        if self.wdir is not None:
            self.process.setWorkingDirectory(self.wdir)

        #-------------------------Python specific-------------------------------
        # Python arguments
        p_args = ['-u']
        if DEBUG >= 3:
            p_args += ['-v']
        p_args += get_python_args(self.fname, self.python_args,
                                  self.interact_action.isChecked(),
                                  self.debug_action.isChecked(),
                                  self.arguments)
        
        env = [unicode(_path) for _path in self.process.systemEnvironment()]

        if self.pythonstartup:
            env.append('PYTHONSTARTUP=%s' % self.pythonstartup)
        
        # Monitor
        if self.monitor_enabled:
            env.append('SPYDER_SHELL_ID=%s' % id(self))
            env.append('SPYDER_AR_TIMEOUT=%d' % self.autorefresh_timeout)
            env.append('SPYDER_AR_STATE=%r' % self.autorefresh_state)
            from SMlib.widgets.externalshell import introspection
            introspection_server = introspection.start_introspection_server()
            introspection_server.register(self)
            notification_server = introspection.start_notification_server()
            self.notification_thread = notification_server.register(self)
            self.connect(self.notification_thread, SIGNAL('pdb(QString,int)'),
                         lambda fname, lineno:
                         self.emit(SIGNAL('pdb(QString,int)'), fname, lineno))
            self.connect(self.notification_thread,
                         SIGNAL('new_ipython_kernel(QString)'),
                         lambda args:
                         self.emit(SIGNAL('create_ipython_client(QString)'),
                         args))
            self.connect(self.notification_thread,
                         SIGNAL('open_file(QString,int)'),
                         lambda fname, lineno:
                         self.emit(SIGNAL('open_file(QString,int)'),
                                   fname, lineno))
            if self.namespacebrowser is not None:
                self.configure_namespacebrowser()
            env.append('SPYDER_I_PORT=%d' % introspection_server.port)
            env.append('SPYDER_N_PORT=%d' % notification_server.port)
        
        # External modules options
        env.append('ETS_TOOLKIT=%s' % self.ets_backend)
        env.append('MATPLOTLIB_PATCH=%r' % self.mpl_patch_enabled)
        if self.mpl_backend:
            env.append('MATPLOTLIB_BACKEND=%s' % self.mpl_backend)
        if self.qt_api:
            env.append('QT_API=%s' % self.qt_api)
        env.append('INSTALL_QT_INPUTHOOK=%s' % self.install_qt_inputhook)
        env.append('COLORIZE_SYS_STDERR=%s' % self.colorize_sys_stderr)
#        # Socket-based alternative (see input hook in sitecustomize.py):
#        if self.install_qt_inputhook:
#            from PyQt4.QtNetwork import QLocalServer
#            self.local_server = QLocalServer()
#            self.local_server.listen(str(id(self)))
        if self.pyqt_api:
            env.append('PYQT_API=%d' % self.pyqt_api)
        env.append('IGNORE_SIP_SETAPI_ERRORS=%s'
                   % self.ignore_sip_setapi_errors)
        
        # User Module Deleter
        if self.is_interpreter:
            env.append('UMD_ENABLED=%r' % self.umd_enabled)
            env.append('UMD_NAMELIST=%s' % ','.join(self.umd_namelist))
            env.append('UMD_VERBOSE=%r' % self.umd_verbose)

        # IPython kernel
        env.append('IPYTHON_KERNEL=%r' % self.is_ipykernel)
            
        pathlist = []

        # Fix encoding with custom "sitecustomize.py"
        scpath = osp.dirname(osp.abspath(__file__))
        pathlist.append(scpath)
        
        # Adding Spyder path
        pathlist += self.path
        
        # Adding path list to PYTHONPATH environment variable
        add_pathlist_to_PYTHONPATH(env, pathlist)

        #-------------------------Python specific-------------------------------
                        
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.write_output)
        self.connect(self.process, SIGNAL("readyReadStandardError()"),
                     self.write_error)
        self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)
                     
        self.connect(self, SIGNAL('finished()'), self.dialog_manager.close_all)

        self.connect(self.terminate_button, SIGNAL("clicked()"),
                     self.process.terminate)
        self.connect(self.kill_button, SIGNAL("clicked()"),
                     self.process.kill)
        
        #-------------------------Python specific-------------------------------
        # Fixes for our Mac app:
        # 1. PYTHONPATH and PYTHONHOME are set while bootstrapping the app,
        #    but their values are messing sys.path for external interpreters
        #    (e.g. EPD) so we need to remove them from the environment.
        # 2. Add this file's dir to PYTHONPATH. This will make every external
        #    interpreter to use our sitecustomize script.
        # 3. Remove PYTHONOPTIMIZE from env so that we can have assert
        #    statements working with our interpreters (See Issue 1281)
        if sys.platform == 'darwin' and 'Spyder.app' in __file__:
            env.append('SPYDER_INTERPRETER=%s' % self.pythonexecutable)
            if 'Spyder.app' not in self.pythonexecutable:
                env = [p for p in env if not (p.startswith('PYTHONPATH') or \
                                              p.startswith('PYTHONHOME'))] # 1.

                env.append('PYTHONPATH=%s' % osp.dirname(__file__))        # 2.

            env = [p for p in env if not p.startswith('PYTHONOPTIMIZE')]   # 3.

        self.process.setEnvironment(env)
        self.process.start(self.pythonexecutable, p_args)
        #-------------------------Python specific-------------------------------
            
        running = self.process.waitForStarted(3000)
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, _("Error"),
                             _("A Python or IPython Console failed to start!"))
        else:
            self.shell.setFocus()
            self.emit(SIGNAL('started()'))
            
        return self.process

    def finished(self, exit_code, exit_status):
        """Reimplement ExternalShellBase method"""
        ExternalShellBase.finished(self, exit_code, exit_status)
        self.introspection_socket = None

    
#===============================================================================
#    Input/Output
#===============================================================================
    def write_error(self):
        if os.name == 'nt':
            #---This is apparently necessary only on Windows (not sure though):
            #   emptying standard output buffer before writing error output
            self.process.setReadChannel(QProcess.StandardOutput)
            if self.process.waitForReadyRead(1):
                self.write_output()
        self.shell.write_error(self.get_stderr())
        QApplication.processEvents()
        
    def send_to_process(self, text):
        if not self.is_running():
            return
            
        if not isinstance(text, basestring):
            text = unicode(text)
        if self.install_qt_inputhook and self.introspection_socket is not None:
            communicate(self.introspection_socket,
                        "toggle_inputhook_flag(True)")
#            # Socket-based alternative (see input hook in sitecustomize.py):
#            while self.local_server.hasPendingConnections():
#                self.local_server.nextPendingConnection().write('go!')
        if text.startswith(('%', '!')):
            text = 'evalsc(r"%s")\n' % text
        if not text.endswith('\n'):
            text += '\n'
        self.process.write(locale_codec.fromUnicode(text))
        self.process.waitForBytesWritten(-1)
        
        # Eventually write prompt faster (when hitting Enter continuously)
        # -- necessary/working on Windows only:
        if os.name == 'nt':
            self.write_error()
        
    def keyboard_interrupt(self):
        if self.introspection_socket is not None:
            communicate(self.introspection_socket, "thread.interrupt_main()")
        
    def quit_monitor(self):
        if self.introspection_socket is not None:
            try:
                write_packet(self.introspection_socket, "thread.exit()")
            except socket.error:
                pass
            
#===============================================================================
#    Globals explorer
#===============================================================================
    def toggle_globals_explorer(self, state):
        if self.stand_alone is not None:
            self.splitter.setSizes([1, 1 if state else 0])
            self.namespacebrowser_button.setChecked(state)
            if state and self.namespacebrowser is not None:
                self.namespacebrowser.refresh_table()
        
    def splitter_moved(self, pos, index):
        self.namespacebrowser_button.setChecked( self.splitter.sizes()[1] )

#===============================================================================
#    Misc.
#===============================================================================
    def set_current_working_directory(self):
        """Set current working directory"""
        cwd = self.shell.get_cwd()
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        directory = getexistingdirectory(self, _("Select directory"), cwd)
        if directory:
            self.shell.set_cwd(directory)
        self.emit(SIGNAL('redirect_stdio(bool)'), True)

    def show_env(self):
        """Show environment variables"""
        get_func = self.shell.get_env
        set_func = self.shell.set_env
        self.dialog_manager.show(RemoteEnvDialog(get_func, set_func))
        
    def show_syspath(self):
        """Show sys.path contents"""
        editor = DictEditor()
        editor.setup(self.shell.get_syspath(), title="sys.path", readonly=True,
                     width=600, icon='syspath.png')
        self.dialog_manager.show(editor)
コード例 #26
0
ファイル: systemshell.py プロジェクト: koll00/Gui_SM
class ExternalSystemShell(ExternalShellBase):
    """External Shell widget: execute Python script in a separate process"""
    SHELL_CLASS = TerminalWidget
    def __init__(self, parent=None, wdir=None, path=[], light_background=True,
                 menu_actions=None, show_buttons_inside=True,
                 show_elapsed_time=True):
        ExternalShellBase.__init__(self, parent=parent, fname=None, wdir=wdir,
                                   history_filename='.history',
                                   light_background=light_background,
                                   menu_actions=menu_actions,
                                   show_buttons_inside=show_buttons_inside,
                                   show_elapsed_time=show_elapsed_time)
        
        # Additional python path list
        self.path = path
        
        # For compatibility with the other shells that can live in the external
        # console
        self.is_ipykernel = False
        self.connection_file = None

    def get_icon(self):
        return get_icon('cmdprompt.png')
    
    def create_process(self):
        self.shell.clear()
            
        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.MergedChannels)
        
        # PYTHONPATH (in case we use Python in this terminal, e.g. py2exe)
        env = [unicode(_path) for _path in self.process.systemEnvironment()]
        add_pathlist_to_PYTHONPATH(env, self.path)
        self.process.setEnvironment(env)
        
        # Working directory
        if self.wdir is not None:
            self.process.setWorkingDirectory(self.wdir)
            
        # Shell arguments
        if os.name == 'nt':
            p_args = ['/Q']
        else:
            p_args = ['-i']
            
        if self.arguments:
            p_args.extend( shell_split(self.arguments) )
                        
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.write_output)
        self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)
        
        self.connect(self.kill_button, SIGNAL("clicked()"),
                     self.process.kill)
        
        if os.name == 'nt':
            self.process.start('cmd.exe', p_args)
        else:
            # Using bash:
            self.process.start('bash', p_args)
            self.send_to_process("""PS1="\u@\h:\w> "\n""")
            
        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, _("Error"),
                                 _("Process failed to start"))
        else:
            self.shell.setFocus()
            self.emit(SIGNAL('started()'))
            
        return self.process
    
#===============================================================================
#    Input/Output
#===============================================================================
    def transcode(self, bytes):
        if os.name == 'nt':
            return encoding.transcode(str(bytes.data()), 'cp850')
        else:
            return ExternalShellBase.transcode(self, bytes)
    
    def send_to_process(self, text):
        if not isinstance(text, basestring):
            text = unicode(text)
        if text[:-1] in ["clear", "cls", "CLS"]:
            self.shell.clear()
            self.send_to_process(os.linesep)
            return
        if not text.endswith('\n'):
            text += '\n'
        if os.name == 'nt':
            self.process.write(text.encode('cp850'))
        else:
            self.process.write(locale_codec.fromUnicode(text))
        self.process.waitForBytesWritten(-1)
        
    def keyboard_interrupt(self):
        # This does not work on Windows:
        # (unfortunately there is no easy way to send a Ctrl+C to cmd.exe)
        self.send_ctrl_to_process('c')

#        # The following code will soon be removed:
#        # (last attempt to send a Ctrl+C on Windows)
#        if os.name == 'nt':
#            pid = int(self.process.pid())
#            import ctypes, win32api, win32con
#            class _PROCESS_INFORMATION(ctypes.Structure):
#                _fields_ = [("hProcess", ctypes.c_int),
#                            ("hThread", ctypes.c_int),
#                            ("dwProcessID", ctypes.c_int),
#                            ("dwThreadID", ctypes.c_int)]
#            x = ctypes.cast( ctypes.c_void_p(pid),
#                             ctypes.POINTER(_PROCESS_INFORMATION) )
#            win32api.GenerateConsoleCtrlEvent(win32con.CTRL_C_EVENT,
#                                              x.dwProcessID)
#        else:
#            self.send_ctrl_to_process('c')
                
コード例 #27
0
class HostWindow(QMainWindow):
    # signals
    SIGTERM = pyqtSignal()
    SIGUSR1 = pyqtSignal()

    # --------------------------------------------------------------------------------------------------------

    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_HostWindow()
        self.ui.setupUi(self)

        # ----------------------------------------------------------------------------------------------------
        # Internal stuff

        # Current mod-ui title
        #self.fCurrentBundle = ""
        self.fCurrentTitle = ""

        # Next bundle to load (done by startup arguments)
        self.fNextBundle = ""

        # first attempt of auto-start backend doesn't show an error
        self.fFirstBackendInit = True

        # need to call session reconnect after connecting the 1st time
        self.fNeedsSessionReconnect = False

        # Qt idle timer
        self.fIdleTimerId = 0

        # Qt web frame, used for evaluating javascript
        self.fWebFrame = None

        # to be filled with key-value pairs of current settings
        self.fSavedSettings = {}

        # List of pedalboards
        self.fPedalboards = get_all_pedalboards()

        # List of current-pedalboard presets
        self.fPresetMenuList = []

        # Process that runs the backend
        self.fProccessBackend = QProcess(self)
        self.fProccessBackend.setProcessChannelMode(QProcess.MergedChannels)
        self.fProccessBackend.setReadChannel(QProcess.StandardOutput)
        self.fStoppingBackend = False

        # Thread for managing the webserver
        self.fWebServerThread = WebServerThread(self)

        # ----------------------------------------------------------------------------------------------------
        # Set up GUI

        self.ui.webview = QWebView(self.ui.swp_webview)
        self.ui.webview.setMinimumWidth(980)
        self.ui.swp_webview.layout().addWidget(self.ui.webview)

        self.ui.webpage = HostWebPage(self)
        self.ui.webpage.setViewportSize(QSize(980, 600))
        self.ui.webview.setPage(self.ui.webpage)

        self.ui.webinspector = QWebInspector(None)
        self.ui.webinspector.resize(800, 600)
        self.ui.webinspector.setPage(self.ui.webpage)
        self.ui.webinspector.setVisible(False)

        self.ui.act_file_connect.setEnabled(False)
        self.ui.act_file_connect.setVisible(False)
        self.ui.act_file_disconnect.setEnabled(False)
        self.ui.act_file_disconnect.setVisible(False)

        self.ui.label_app.setText("MOD Application v%s" % config["version"])

        # disable file menu
        self.ui.act_file_refresh.setEnabled(False)
        self.ui.act_file_inspect.setEnabled(False)

        # disable pedalboard menu
        self.ui.act_pedalboard_new.setEnabled(False)
        self.ui.act_pedalboard_open.setEnabled(False)
        self.ui.act_pedalboard_save.setEnabled(False)
        self.ui.act_pedalboard_save_as.setEnabled(False)
        self.ui.act_pedalboard_share.setEnabled(False)
        self.ui.menu_Pedalboard.setEnabled(False)

        # disable presets menu
        self.ui.act_presets_new.setEnabled(False)
        self.ui.act_presets_save.setEnabled(False)
        self.ui.act_presets_save_as.setEnabled(False)
        self.ui.menu_Presets.setEnabled(False)

        # initial stopped state
        self.slot_backendFinished(-1, -1)

        # Qt needs this so it properly creates & resizes the webview
        self.ui.stackedwidget.setCurrentIndex(1)
        self.ui.stackedwidget.setCurrentIndex(0)

        # FIXME
        #self.ui.act_backend_stop.setVisible(False)
        #self.ui.act_backend_restart.setVisible(False)

        # ----------------------------------------------------------------------------------------------------
        # Set up GUI (special stuff for Mac OS)

        if MACOS:
            self.ui.act_file_quit.setMenuRole(QAction.QuitRole)
            self.ui.act_settings_configure.setMenuRole(QAction.PreferencesRole)
            self.ui.act_help_about.setMenuRole(QAction.AboutRole)
            #self.ui.menu_Settings.setTitle("Panels")
            #self.ui.menu_Help.hide()

        # ----------------------------------------------------------------------------------------------------
        # Load Settings

        self.loadSettings(True)

        # ----------------------------------------------------------------------------------------------------
        # Connect actions to functions

        self.SIGUSR1.connect(self.slot_handleSIGUSR1)
        self.SIGTERM.connect(self.slot_handleSIGTERM)

        self.fProccessBackend.error.connect(self.slot_backendError)
        self.fProccessBackend.started.connect(self.slot_backendStarted)
        self.fProccessBackend.finished.connect(self.slot_backendFinished)
        self.fProccessBackend.readyRead.connect(self.slot_backendRead)

        self.fWebServerThread.running.connect(self.slot_webServerRunning)
        self.fWebServerThread.finished.connect(self.slot_webServerFinished)

        self.ui.act_file_refresh.triggered.connect(self.slot_fileRefresh)
        self.ui.act_file_inspect.triggered.connect(self.slot_fileInspect)

        self.ui.act_settings_configure.triggered.connect(self.slot_configure)

        self.ui.act_help_about.triggered.connect(self.slot_about)
        self.ui.act_help_project.triggered.connect(self.slot_showProject)
        self.ui.act_help_website.triggered.connect(self.slot_showWebsite)

        self.ui.b_start.clicked.connect(self.slot_backendStart)
        self.ui.b_configure.clicked.connect(self.slot_configure)
        self.ui.b_about.clicked.connect(self.slot_about)

        # force our custom refresh
        webReloadAction = self.ui.webpage.action(QWebPage.Reload)
        webReloadAction.triggered.disconnect()
        webReloadAction.triggered.connect(self.slot_fileRefresh)

        # ----------------------------------------------------------------------------------------------------
        # Final setup

        self.setProperWindowTitle()
        SESSION.setupApp(self._pedal_changed_callback)

        if not "--no-autostart" in sys.argv:
            QTimer.singleShot(0, self.slot_backendStart)

        QTimer.singleShot(1, self.fixWebViewSize)

    def __del__(self):
        self.stopAndWaitForWebServer()
        self.stopAndWaitForBackend()

    def _pedal_changed_callback(self, ok, bundlepath, title):
        #self.fCurrentBundle = bundlepath
        self.fCurrentTitle = title or ""
        #self.updatePresetsMenu()
        self.setProperWindowTitle()

    # --------------------------------------------------------------------------------------------------------
    # Files (menu actions)

    @pyqtSlot()
    def slot_fileRefresh(self):
        if self.fWebFrame is None:
            return

        self.ui.label_progress.setText(self.tr("Refreshing UI..."))
        self.ui.stackedwidget.setCurrentIndex(0)
        QTimer.singleShot(0, self.ui.webview.reload)

    @pyqtSlot()
    def slot_fileInspect(self):
        self.ui.webinspector.show()

    # --------------------------------------------------------------------------------------------------------
    # Settings (menu actions)

    @pyqtSlot()
    def slot_configure(self):
        dialog = SettingsWindow(self, True)
        if not dialog.exec_():
            return

        self.loadSettings(False)

    # --------------------------------------------------------------------------------------------------------
    # About (menu actions)

    @pyqtSlot()
    def slot_about(self):
        QMessageBox.about(
            self, self.tr("About"),
            self.tr("""
            <b>MOD Desktop Application</b><br/>
            <br/>
            A software to have the complete MOD environment running in your desktop.<br/>
            (C) 2015-2016 - The MOD Team<br/>
            <br/>
            Publications, products, content or services referenced herein or on the website are the exclusive trademarks or servicemarks of MOD.<br/>
            Other product and company names mentioned in the site may be the trademarks of their respective owners.<br/>
            <br/>
            All software is available under the <a href="https://www.gnu.org/licenses/gpl-2.0.html">GPL license</a>.<br/>
        """))

    @pyqtSlot()
    def slot_showProject(self):
        QDesktopServices.openUrl(QUrl("https://github.com/moddevices/mod-app"))

    @pyqtSlot()
    def slot_showWebsite(self):
        QDesktopServices.openUrl(QUrl("http://moddevices.com/"))

    # --------------------------------------------------------------------------------------------------------
    # Backend (menu actions)

    @pyqtSlot()
    def slot_backendInformation(self):
        table = """
        <table><tr>
        <td> MOD-UI port:     <td></td> %s </td>
        </tr></table>
        """ % (config["port"], )
        QMessageBox.information(self, self.tr("information"), table)

    @pyqtSlot()
    def slot_backendStart(self):
        if self.fProccessBackend.state() != QProcess.NotRunning:
            print("slot_backendStart ignored")
            return

        print("slot_backendStart in progress...")

        hostPath = self.fSavedSettings[MOD_KEY_HOST_PATH]
        if hostPath.endswith("ingen"):
            hostPath = MOD_DEFAULT_HOST_PATH

        hostArgs = ["-p", "5555", "-f", "5556"]
        if self.fSavedSettings[MOD_KEY_HOST_VERBOSE]:
            hostArgs.append("-v")
        else:
            hostArgs.append("-n")

        self.fProccessBackend.start(hostPath, hostArgs)

    @pyqtSlot()
    def slot_backendStop(self):
        #if self.fPluginCount > 0:
        #if not forced:
        #ask = QMessageBox.question(self, self.tr("Warning"), self.tr("There are still some plugins loaded, you need to remove them to stop the engine.\n"
        #"Do you want to do this now?"),
        #QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        #if ask != QMessageBox.Yes:
        #return

        #self.removeAllPlugins()
        #self.host.set_engine_about_to_close()
        #self.host.remove_all_plugins()

        # testing red color for server stopped
        self.ui.webview.blockSignals(True)
        self.ui.webview.setHtml("<html><body bgcolor='green'></body></html>")
        self.ui.webview.blockSignals(False)

        self.stopAndWaitForWebServer()
        self.stopAndWaitForBackend()

    @pyqtSlot()
    def slot_backendRestart(self):
        self.slot_backendStop()
        self.slot_backendStart()

    # --------------------------------------------------------------------------------------------------------

    @pyqtSlot()
    def slot_backendStarted(self):
        self.ui.act_backend_start.setEnabled(False)
        self.ui.act_backend_stop.setEnabled(True)
        self.ui.act_backend_restart.setEnabled(True)
        self.ui.w_buttons.setEnabled(False)
        self.ui.label_progress.setText(self.tr("Loading backend..."))

    @pyqtSlot(int, QProcess.ExitStatus)
    def slot_backendFinished(self, exitCode, exitStatus):
        self.fFirstBackendInit = False
        self.fStoppingBackend = False
        self.ui.act_backend_start.setEnabled(True)
        self.ui.act_backend_stop.setEnabled(False)
        self.ui.act_backend_restart.setEnabled(False)
        self.ui.w_buttons.setEnabled(True)
        self.ui.label_progress.setText("")
        self.ui.stackedwidget.setCurrentIndex(0)

        # stop webserver
        self.stopAndWaitForWebServer()

    @pyqtSlot(QProcess.ProcessError)
    def slot_backendError(self, error):
        firstBackendInit = self.fFirstBackendInit
        self.fFirstBackendInit = False

        # stop webserver
        self.stopAndWaitForWebServer()

        # crashed while stopping, ignore
        if error == QProcess.Crashed and self.fStoppingBackend:
            return

        errorStr = self.tr("Could not start host backend.\n"
                           ) + self.getProcessErrorAsString(error)
        qWarning(errorStr)

        # don't show error if this is the first time starting the host or using live-iso
        if firstBackendInit:
            return

        # show the error message
        QMessageBox.critical(self, self.tr("Error"), errorStr)

    @pyqtSlot()
    def slot_backendRead(self):
        #if self.fProccessBackend.state() != QProcess.Running:
        #return

        for line in str(
                self.fProccessBackend.readAllStandardOutput().trimmed(),
                encoding="utf-8",
                errors="ignore").strip().split("\n"):
            line = line.replace("\x1b[0m",
                                "").replace("\x1b[0;31m",
                                            "").replace("\x1b[0;33m",
                                                        "").strip()
            if not line:
                continue

            if self.fSavedSettings[MOD_KEY_HOST_VERBOSE]:
                print("BACKEND:", line)

            if line == "mod-host ready!" or line == "mod-host is running.":
                QTimer.singleShot(0, self.slot_backendStartPhase2)
            #elif "Listening on socket " in line:
            #QTimer.singleShot(1000, self.slot_ingenStarted)
            ##elif "Activated Jack client " in line:
            ##QTimer.singleShot(1000, self.fWebServerThread.start)
            #elif "Failed to create UNIX socket" in line or "Could not activate Jack client" in line:
            ## need to wait for ingen to create sockets so it can delete them on termination
            #QTimer.singleShot(1000, self.slot_ingenStartError)

    @pyqtSlot()
    def slot_backendStartPhase2(self):
        if self.fProccessBackend.state() == QProcess.NotRunning:
            return

        if not self.fNeedsSessionReconnect:
            # we'll need it for next time
            self.fNeedsSessionReconnect = True
        else:
            # we need it now
            SESSION.reconnectApp()

        self.fWebServerThread.start()

    @pyqtSlot()
    def slot_backendStartError(self):
        self.stopAndWaitForBackend()
        self.slot_backendError(-2)

    # --------------------------------------------------------------------------------------------------------
    # Web Server

    @pyqtSlot()
    def slot_webServerRunning(self):
        self.ui.webview.loadStarted.connect(self.slot_webviewLoadStarted)
        self.ui.webview.loadProgress.connect(self.slot_webviewLoadProgress)
        self.ui.webview.loadFinished.connect(self.slot_webviewLoadFinished)

        print("webserver running with URL:", config["addr"])
        self.ui.webview.load(QUrl(config["addr"]))

    @pyqtSlot()
    def slot_webServerFinished(self):
        try:
            self.ui.webview.loadStarted.disconnect(
                self.slot_webviewLoadStarted)
            self.ui.webview.loadProgress.disconnect(
                self.slot_webviewLoadProgress)
            self.ui.webview.loadFinished.disconnect(
                self.slot_webviewLoadFinished)
        except:
            pass

        print("webserver finished")
        # testing red color for server finished
        self.ui.webview.blockSignals(True)
        self.ui.webview.setHtml("<html><body bgcolor='red'></body></html>")
        self.ui.webview.blockSignals(False)

    # --------------------------------------------------------------------------------------------------------
    # Web View

    @pyqtSlot()
    def slot_webviewLoadStarted(self):
        self.ui.label_progress.setText(self.tr("Loading UI..."))
        print("load started")

    @pyqtSlot(int)
    def slot_webviewLoadProgress(self, progress):
        self.ui.label_progress.setText(self.tr("Loading UI... %i%%" %
                                               progress))

    @pyqtSlot(bool)
    def slot_webviewLoadFinished(self, ok):
        self.ui.webview.loadStarted.disconnect(self.slot_webviewLoadStarted)
        self.ui.webview.loadProgress.disconnect(self.slot_webviewLoadProgress)
        self.ui.webview.loadFinished.disconnect(self.slot_webviewLoadFinished)

        if ok:
            # message
            self.ui.label_progress.setText(self.tr("Loading UI... finished!"))

            # enable file menu
            self.ui.act_file_refresh.setEnabled(True)
            self.ui.act_file_inspect.setEnabled(True)

            # for js evaulation
            self.fWebFrame = self.ui.webpage.currentFrame()

            # postpone app stuff
            QTimer.singleShot(100, self.slot_webviewPostFinished)

        else:
            # message
            self.ui.label_progress.setText(self.tr("Loading UI... failed!"))

            # disable file menu
            self.ui.act_file_refresh.setEnabled(False)
            self.ui.act_file_inspect.setEnabled(False)

            # disable pedalboard menu
            self.ui.act_pedalboard_new.setEnabled(False)
            self.ui.act_pedalboard_open.setEnabled(False)
            self.ui.act_pedalboard_save.setEnabled(False)
            self.ui.act_pedalboard_save_as.setEnabled(False)
            self.ui.act_pedalboard_share.setEnabled(False)
            self.ui.menu_Pedalboard.setEnabled(False)

            # stop js evaulation
            self.fWebFrame = None

            # stop backend&server
            self.stopAndWaitForWebServer()
            self.stopAndWaitForBackend()

        print("load finished")

    @pyqtSlot()
    def slot_webviewPostFinished(self):
        if self.fNextBundle:
            bundle = self.fNextBundle
            self.fNextBundle = ""
            self.fWebFrame.evaluateJavaScript(
                "desktop.loadPedalboard(\"%s\")" % bundle)

        QTimer.singleShot(0, self.slot_webviewPostFinished2)

    @pyqtSlot()
    def slot_webviewPostFinished2(self):
        self.ui.stackedwidget.setCurrentIndex(1)

    # --------------------------------------------------------------------------------------------------------
    # Settings

    def saveSettings(self):
        settings = QSettings()
        settings.setValue("Geometry", self.saveGeometry())

    def loadSettings(self, firstTime):
        qsettings = QSettings()
        websettings = self.ui.webview.settings()

        self.fSavedSettings = {
            # Main
            MOD_KEY_MAIN_PROJECT_FOLDER:
            qsettings.value(MOD_KEY_MAIN_PROJECT_FOLDER,
                            MOD_DEFAULT_MAIN_PROJECT_FOLDER,
                            type=str),
            MOD_KEY_MAIN_REFRESH_INTERVAL:
            qsettings.value(MOD_KEY_MAIN_REFRESH_INTERVAL,
                            MOD_DEFAULT_MAIN_REFRESH_INTERVAL,
                            type=int),
            # Host
            MOD_KEY_HOST_VERBOSE:
            qsettings.value(MOD_KEY_HOST_VERBOSE,
                            MOD_DEFAULT_HOST_VERBOSE,
                            type=bool),
            MOD_KEY_HOST_PATH:
            qsettings.value(MOD_KEY_HOST_PATH, MOD_DEFAULT_HOST_PATH,
                            type=str),
            # WebView
            MOD_KEY_WEBVIEW_INSPECTOR:
            qsettings.value(MOD_KEY_WEBVIEW_INSPECTOR,
                            MOD_DEFAULT_WEBVIEW_INSPECTOR,
                            type=bool),
            MOD_KEY_WEBVIEW_VERBOSE:
            qsettings.value(MOD_KEY_WEBVIEW_VERBOSE,
                            MOD_DEFAULT_WEBVIEW_VERBOSE,
                            type=bool),
            MOD_KEY_WEBVIEW_SHOW_INSPECTOR:
            qsettings.value(MOD_KEY_WEBVIEW_SHOW_INSPECTOR,
                            MOD_DEFAULT_WEBVIEW_SHOW_INSPECTOR,
                            type=bool)
        }

        inspectorEnabled = self.fSavedSettings[MOD_KEY_WEBVIEW_INSPECTOR]

        websettings.setAttribute(QWebSettings.DeveloperExtrasEnabled,
                                 inspectorEnabled)

        if firstTime:
            if qsettings.contains("Geometry"):
                self.restoreGeometry(qsettings.value("Geometry", ""))
            else:
                self.setWindowState(self.windowState() | Qt.WindowMaximized)

            if inspectorEnabled and self.fSavedSettings[
                    MOD_KEY_WEBVIEW_SHOW_INSPECTOR]:
                QTimer.singleShot(1000, self.ui.webinspector.show)

        self.ui.act_file_inspect.setVisible(inspectorEnabled)

        if self.fIdleTimerId != 0:
            self.killTimer(self.fIdleTimerId)

        self.fIdleTimerId = self.startTimer(
            self.fSavedSettings[MOD_KEY_MAIN_REFRESH_INTERVAL])

    # --------------------------------------------------------------------------------------------------------
    # Misc

    @pyqtSlot()
    def slot_handleSIGUSR1(self):
        print("Got SIGUSR1 -> Saving project now")
        self.slot_pedalboardSave()

    @pyqtSlot()
    def slot_handleSIGTERM(self):
        print("Got SIGTERM -> Closing now")
        self.close()

    # --------------------------------------------------------------------------------------------------------
    # Qt events

    def closeEvent(self, event):
        if self.fIdleTimerId != 0:
            self.killTimer(self.fIdleTimerId)
            self.fIdleTimerId = 0

        self.saveSettings()
        self.slot_backendStop()

        QMainWindow.closeEvent(self, event)

        # Needed in case the web inspector is still alive
        #self.ui.webinspector.close()
        QApplication.instance().quit()

    def timerEvent(self, event):
        if event.timerId() == self.fIdleTimerId:
            pass

        QMainWindow.timerEvent(self, event)

    def resizeEvent(self, event):
        QMainWindow.resizeEvent(self, event)
        self.fixWebViewSize()

    # --------------------------------------------------------------------------------------------------------
    # Internal stuff

    def getProcessErrorAsString(self, error):
        if error == -2:
            return self.tr("Ingen failed to create UNIX socket.")
        if error == QProcess.FailedToStart:
            return self.tr("Process failed to start.")
        if error == QProcess.Crashed:
            return self.tr("Process crashed.")
        if error == QProcess.Timedout:
            return self.tr("Process timed out.")
        if error == QProcess.WriteError:
            return self.tr("Process write error.")
        return self.tr("Unkown error.")

    def fixWebViewSize(self):
        if self.ui.stackedwidget.currentIndex() == 1:
            return

        size = self.ui.swp_intro.size()
        self.ui.swp_webview.resize(size)
        self.ui.webview.resize(size)
        self.ui.webpage.setViewportSize(size)

    def stopAndWaitForBackend(self):
        SESSION.host.close_jack()

        if self.fProccessBackend.state() == QProcess.NotRunning:
            return

        self.fStoppingBackend = True
        self.fProccessBackend.terminate()
        if not self.fProccessBackend.waitForFinished(2000):
            qWarning("Backend failed top stop cleanly, forced kill")
            self.fProccessBackend.kill()

    def stopAndWaitForWebServer(self):
        if not self.fWebServerThread.isRunning():
            return

        if not self.fWebServerThread.stopWait():
            qWarning(
                "WebServer Thread failed top stop cleanly, forced terminate")
            self.fWebServerThread.terminate()

    def setProperWindowTitle(self):
        title = "MOD Application"

        if self.fCurrentTitle:
            title += " - %s" % self.fCurrentTitle

        self.setWindowTitle(title)
コード例 #28
0
ファイル: pythonshell.py プロジェクト: Brainsciences/luminoso
class ExternalPythonShell(ExternalShellBase):
    """External Shell widget: execute Python script in a separate process"""
    SHELL_CLASS = ExtPyQsciShell
    def __init__(self, parent=None, fname=None, wdir=None, commands=[],
                 interact=False, debug=False, path=[]):
        ExternalShellBase.__init__(self, parent, wdir,
                                   history_filename='.history_ec.py')
        
        self.shell.set_externalshell(self)

        self.toggle_globals_explorer(False)
        self.interact_check.setChecked(interact)
        self.debug_check.setChecked(debug)
        
        self.monitor_socket = None
        self.interpreter = fname is None
        self.fname = startup.__file__ if fname is None else fname
        
        if self.interpreter:
            self.interact_check.hide()
            self.debug_check.hide()
            self.terminate_button.hide()
        
        self.commands = ["import sys", "sys.path.insert(0, '')"] + commands
        
        # Additional python path list
        self.path = path
        
    def get_toolbar_buttons(self):
        ExternalShellBase.get_toolbar_buttons(self)
        self.globalsexplorer_button = create_toolbutton(self,
                          get_icon('dictedit.png'), self.tr("Variables"),
                          tip=self.tr("Show/hide global variables explorer"),
                          toggled=self.toggle_globals_explorer)
        self.terminate_button = create_toolbutton(self,
              get_icon('terminate.png'), self.tr("Terminate"),
              tip=self.tr("Attempts to terminate the process.\n"
                          "The process may not exit as a result of clicking "
                          "this button\n(it is given the chance to prompt "
                          "the user for any unsaved files, etc)."))        
        self.interact_check = QCheckBox(self.tr("Interact"), self)
        self.debug_check = QCheckBox(self.tr("Debug"), self)
        return [self.interact_check, self.debug_check,
                self.globalsexplorer_button, self.run_button,
                self.terminate_button, self.kill_button]
        
    def get_shell_widget(self):
        # Globals explorer
        self.globalsexplorer = GlobalsExplorer(self)
        self.connect(self.globalsexplorer, SIGNAL('collapse()'),
                     lambda: self.toggle_globals_explorer(False))
        
        # Shell splitter
        self.splitter = splitter = QSplitter(Qt.Vertical, self)
        self.connect(self.splitter, SIGNAL('splitterMoved(int, int)'),
                     self.splitter_moved)
        splitter.addWidget(self.shell)
        splitter.setCollapsible(0, False)
        splitter.addWidget(self.globalsexplorer)
        splitter.setStretchFactor(0, 2)
        splitter.setStretchFactor(1, 1)
        return splitter
    
    def get_icon(self):
        return get_icon('python.png')

    def set_buttons_runnning_state(self, state):
        ExternalShellBase.set_buttons_runnning_state(self, state)
        self.interact_check.setEnabled(not state)
        self.debug_check.setEnabled(not state)
        self.terminate_button.setEnabled(state)
        if not state:
            self.toggle_globals_explorer(False)
        self.globalsexplorer_button.setEnabled(state)
    
    def create_process(self):
        self.shell.clear()
            
        self.process = QProcess(self)
        self.process.setProcessChannelMode(QProcess.MergedChannels)
        self.connect(self.shell, SIGNAL("wait_for_ready_read()"),
                     lambda: self.process.waitForReadyRead(250))
        
        # Working directory
        if self.wdir is not None:
            self.process.setWorkingDirectory(self.wdir)

        #-------------------------Python specific-------------------------------
        # Python arguments
        p_args = ['-u']
        if self.interact_check.isChecked():
            p_args.append('-i')
        if self.debug_check.isChecked():
            p_args.extend(['-m', 'pdb'])
        p_args.append(self.fname)
        
        env = self.process.systemEnvironment()
        
        # Monitor
        env.append('SHELL_ID=%s' % id(self))
        from spyderlib.widgets.externalshell.monitor import start_server
        server, port = start_server()
        self.notification_thread = server.register(str(id(self)), self)
        self.connect(self.notification_thread, SIGNAL('refresh()'),
                     self.globalsexplorer.refresh_table)
        env.append('SPYDER_PORT=%d' % port)
        
        # Python init commands (interpreter only)
        if self.commands and self.interpreter:
            env.append('PYTHONINITCOMMANDS=%s' % ';'.join(self.commands))
            self.process.setEnvironment(env)
            
        pathlist = []

        # Fix encoding with custom "sitecustomize.py"
        scpath = osp.dirname(osp.abspath(__file__))
        pathlist.append(scpath)
        
        # Adding Spyder path
        pathlist += self.path
        
        # Adding path list to PYTHONPATH environment variable
        pypath = "PYTHONPATH"
        pathstr = os.pathsep.join(pathlist)
        if os.environ.get(pypath) is not None:
            env.replaceInStrings(pypath+'=', pypath+'='+pathstr+os.pathsep,
                                 Qt.CaseSensitive)
        else:
            env.append(pypath+'='+pathstr)
        self.process.setEnvironment(env)
        #-------------------------Python specific-------------------------------
            
        if self.arguments:
            p_args.extend( self.arguments.split(' ') )
                        
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"),
                     self.write_output)
        self.connect(self.process, SIGNAL("finished(int,QProcess::ExitStatus)"),
                     self.finished)

        self.connect(self.terminate_button, SIGNAL("clicked()"),
                     self.process.terminate)
        self.connect(self.kill_button, SIGNAL("clicked()"),
                     self.process.kill)
        
        #-------------------------Python specific-------------------------------
        self.process.start(sys.executable, p_args)
        #-------------------------Python specific-------------------------------
            
        running = self.process.waitForStarted()
        self.set_running_state(running)
        if not running:
            QMessageBox.critical(self, self.tr("Error"),
                                 self.tr("Process failed to start"))
        else:
            self.shell.setFocus()
            self.emit(SIGNAL('started()'))
            
        return self.process
    
#===============================================================================
#    Input/Output
#===============================================================================
    def _write_error(self, text, findstr):
        pos = text.find(findstr)
        if pos != -1:
            self.shell.write(text[:pos])
            if text.endswith(">>> "):
                self.shell.write_error(text[pos:-5])
                self.shell.write(text[-5:], flush=True)
            else:
                self.shell.write_error(text[pos:])
            return True
        return False
    
    def write_output(self):
        text = self.get_stdout()
        if not self._write_error(text, 'Traceback (most recent call last):') \
           and not self._write_error(text, 'File "<stdin>", line 1'):
            self.shell.write(text)
        QApplication.processEvents()
        
    def send_to_process(self, qstr):
        if not isinstance(qstr, QString):
            qstr = QString(qstr)
        if not qstr.endsWith('\n'):
            qstr.append('\n')
        self.process.write(qstr.toLocal8Bit())
        self.process.waitForBytesWritten(-1)
        
    def keyboard_interrupt(self):
        communicate(self.monitor_socket, "thread.interrupt_main()")
            
#===============================================================================
#    Globals explorer
#===============================================================================
    def toggle_globals_explorer(self, state):
        self.splitter.setSizes([1, 1 if state else 0])
        self.globalsexplorer_button.setChecked(state)
        if state:
            self.globalsexplorer.refresh_table()
        
    def splitter_moved(self, pos, index):
        self.globalsexplorer_button.setChecked( self.splitter.sizes()[1] )
コード例 #29
0
ファイル: pylint.py プロジェクト: khertan/KhtEditor
class PyLint(Plugin, QObject):
    """ PyLint Plugin """
    capabilities = ['toolbarHook']
    __version__ = '0.5'
    thread = None
    
    def do_toolbarHook(self, widget):
        """ Hook to install the pylint toolbar button"""
        widget.addAction('PyLint', self.do_pylint)
        
        
    @pyqtSlot()
    def do_pylint(self):
        """ Launch the lint process and create the result window """
        print 'do_pylint'

        self.pylint_pross = QProcess()
        self.pylint_pross.setProcessChannelMode(QProcess.MergedChannels)
        self.pylint_pross.setWorkingDirectory( \
            os.path.dirname(str(self.parent.editor.filename)))
        self.pylint_pross.setReadChannel(QProcess.StandardOutput)

        self.connect(self.pylint_pross, \
            SIGNAL('finished(int)'), \
            self.finished)
        self.connect(self.pylint_pross, \
            SIGNAL('readyReadStandardOutput()'), \
            self.handle_stdout)
        self.connect(self.pylint_pross, \
            SIGNAL('readyReadStandardError()'), \
            self.handle_stderr)
        if (self.pylint_pross.start("pylint", \
                [self.parent.editor.filename,])):
            print 'Cannot start process'

        self.win = ResultWin()
        self.win.setWindowTitle("PyLint Results :" \
            + os.path.basename(str(self.parent.editor.filename)))
        self.win.show()
        if isMAEMO:
            self.win.setAttribute(Qt.WA_Maemo5ShowProgressIndicator, True)
            
        self.win.connect(self.win.list_view, \
            SIGNAL('doubleClicked(const QModelIndex&)'), \
            self.goto_line)

        self.pylint_pross.waitForStarted()
        
    def finished(self, _):
        """ Call back called when lint end """
        if isMAEMO:
            self.win.setAttribute(Qt.WA_Maemo5ShowProgressIndicator, False)
            
    def handle_stdout(self):
        """
        Private slot to handle the readyReadStdout
        signal of the pylint process.
        """
        result_list = []
        #regex = QRegExp('(\w)\S*:\S*(\d*):.*: (.*)')
        regex = QRegExp('(\w)\s*:\s*(\d*):(.*)')
        regex_score = \
            QRegExp('.*at.(\d.\d*)/10.*')
        while self.pylint_pross and self.pylint_pross.canReadLine():
            result = unicode(self.pylint_pross.readLine())
            if result != None:
                pos = 0
                while True:
                    pos = regex.indexIn(result, pos)
                    if pos < 0:
                        if regex_score.indexIn(result, 0) >= 0:
                            self.win.setWindowTitle( \
                                "PyLint Results :" \
                                + str(regex_score.cap(1)) \
                                + ':'                                
                                + os.path.basename(str(self.parent.editor.filename)))
                        break
                    result_list.append((regex.cap(1), regex.cap(2), regex.cap(3)))
                    #print 'Append : ',(regex.cap(1), regex.cap(2), regex.cap(3))
                    pos = pos + regex.matchedLength()
                    
        if len(result_list)>0:
            self.win.append_results(result_list)
        
    def goto_line(self, index):
        """ Callback called when a lint result is double clicked """
        line = int(self.win.list_model.items[index.row()][1])
        self.parent.do_gotoLine(line)
        
    def handle_stderr(self):
        """
        Private slot to handle the readyReadStderr
        signal of the pylint process. Currently not
        managed
        """
        print 'error stderr'
コード例 #30
0
ファイル: pylint.py プロジェクト: tonal/KhtEditor
class PyLint(Plugin, QObject):
    """ PyLint Plugin """
    capabilities = ['toolbarHook']
    __version__ = '0.5'
    thread = None

    def do_toolbarHook(self, widget):
        """ Hook to install the pylint toolbar button"""
        widget.addAction('PyLint', self.do_pylint)

    @pyqtSlot()
    def do_pylint(self):
        """ Launch the lint process and create the result window """
        print 'do_pylint'

        self.pylint_pross = QProcess()
        self.pylint_pross.setProcessChannelMode(QProcess.MergedChannels)
        self.pylint_pross.setWorkingDirectory( \
            os.path.dirname(str(self.parent.editor.filename)))
        self.pylint_pross.setReadChannel(QProcess.StandardOutput)

        self.connect(self.pylint_pross, \
            SIGNAL('finished(int)'), \
            self.finished)
        self.connect(self.pylint_pross, \
            SIGNAL('readyReadStandardOutput()'), \
            self.handle_stdout)
        self.connect(self.pylint_pross, \
            SIGNAL('readyReadStandardError()'), \
            self.handle_stderr)
        if (self.pylint_pross.start("pylint", \
                [self.parent.editor.filename,])):
            print 'Cannot start process'

        self.win = ResultWin()
        self.win.setWindowTitle("PyLint Results :" \
            + os.path.basename(str(self.parent.editor.filename)))
        self.win.show()
        if isMAEMO:
            self.win.setAttribute(Qt.WA_Maemo5ShowProgressIndicator, True)

        self.win.connect(self.win.list_view, \
            SIGNAL('doubleClicked(const QModelIndex&)'), \
            self.goto_line)

        self.pylint_pross.waitForStarted()

    def finished(self, _):
        """ Call back called when lint end """
        if isMAEMO:
            self.win.setAttribute(Qt.WA_Maemo5ShowProgressIndicator, False)

    def handle_stdout(self):
        """
        Private slot to handle the readyReadStdout
        signal of the pylint process.
        """
        result_list = []
        #regex = QRegExp('(\w)\S*:\S*(\d*):.*: (.*)')
        regex = QRegExp('(\w)\s*:\s*(\d*):(.*)')
        regex_score = \
            QRegExp('.*at.(\d.\d*)/10.*')
        while self.pylint_pross and self.pylint_pross.canReadLine():
            result = unicode(self.pylint_pross.readLine())
            if result != None:
                pos = 0
                while True:
                    pos = regex.indexIn(result, pos)
                    if pos < 0:
                        if regex_score.indexIn(result, 0) >= 0:
                            self.win.setWindowTitle( \
                                "PyLint Results :" \
                                + str(regex_score.cap(1)) \
                                + ':'
                                + os.path.basename(str(self.parent.editor.filename)))
                        break
                    result_list.append(
                        (regex.cap(1), regex.cap(2), regex.cap(3)))
                    #print 'Append : ',(regex.cap(1), regex.cap(2), regex.cap(3))
                    pos = pos + regex.matchedLength()

        if len(result_list) > 0:
            self.win.append_results(result_list)

    def goto_line(self, index):
        """ Callback called when a lint result is double clicked """
        line = int(self.win.list_model.items[index.row()][1])
        self.parent.do_gotoLine(line)

    def handle_stderr(self):
        """
        Private slot to handle the readyReadStderr
        signal of the pylint process. Currently not
        managed
        """
        print 'error stderr'
コード例 #31
0
class ScriptRunner(QObject):
    def __init__(self, caller, parent=None, env=None, addEnv=None):
        QObject.__init__(self, parent)
        self._proc = None
        self._caller = caller
        self._decode = None
        if env is None:
            env = os.environ.copy()
        self._env = env
        if addEnv:
            self._env.update(addEnv)

    def stop(self, kill=False):
        if self._proc is None:
            return

        if kill:
            self._proc.kill()
        else:
            self._proc.terminate()

    def run(self, scriptFile, args=None, env=None, wd=None):
        if self._proc:
            return

        self._proc = QProcess(self)

        if wd:
            self._proc.setWorkingDirectory(wd)

        if not env is None:
            self._env.update(env)
        envList = dict2qlst(self._env)

        if args is None:
            args = []

        script = quote(scriptFile)
        if not os.path.exists(script):
            script = find_script(script)

        if not script or not os.path.exists(script):
            raise PublishException("Script '%s' cannot be found" % script)

        self._caller.handleScriptOutput("%s %s" % (scriptFile,  ' '.join(args)))

        self._proc.setEnvironment(envList)
        self._proc.setProcessChannelMode(QProcess.MergedChannels)
        QObject.connect(self._proc, QtCore.SIGNAL("readyReadStandardOutput()"),
                        self.readScriptOutput)
        QObject.connect(self._proc, QtCore.SIGNAL("finished(int, " \
                                                  "QProcess::ExitStatus)"),
                        self.scriptFinished)

        self._proc.start(script, args, QIODevice.ReadOnly)

    def scriptFinished(self, exitCode, exitStatus):
        if self._caller:
            self.readScriptOutput()
            self._caller.scriptFinished(exitCode,
                                        exitStatus == QProcess.Crashed)
        self._proc = None

    def readScriptOutput(self):
        if self._proc is None:
            return

        qba = self._proc.readAllStandardOutput()
        if self._caller and qba.length():
            if not self._decode:
                lang, deflocale = locale.getdefaultlocale()
                self._decode = codecs.getdecoder(deflocale)
            data, datalen = self._decode(qba.data())
            self._caller.handleScriptOutput(data)
コード例 #32
0
ファイル: main.py プロジェクト: federicosan/archeos-ppt-gui
# -*- coding: utf-8 -*-
import os

from PyQt4.QtGui import *
from PyQt4 import QtCore
from PyQt4.QtCore import QProcess

"""
- Processes are defined in the Global scope because I noticed

- I also use an interleave stdout and stderr (MergedChannels).
we need to do that because CMVS write some output in stderr (?).
So, a proper error handling in a separate channel is impossible.
"""
procB = QProcess()
procB.setProcessChannelMode(QProcess.MergedChannels)
procC = QProcess()
procC.setProcessChannelMode(QProcess.MergedChannels)
procP = QProcess()
procP.setProcessChannelMode(QProcess.MergedChannels)
procCam = QProcess()
procCam.setProcessChannelMode(QProcess.MergedChannels)


class PPTGUI(QWidget):
    """The main Widget.
    TODO: PEP8
    TODO: Translations
    TODO: One Console, One process
    """
コード例 #33
0
 def __createProgramEntry(self, description, exe,
                          versionCommand = "", versionStartsWith = "", 
                          versionPosition = 0, version = "",
                          versionCleanup = None, versionRe = None):
     """
     Private method to generate a program entry.
     
     @param description descriptive text (string or QString)
     @param exe name of the executable program (string)
     @param versionCommand command line switch to get the version info (string)
         if this is empty, the given version will be shown.
     @param versionStartsWith start of line identifying version info (string)
     @param versionPosition index of part containing the version info (integer)
     @keyparam version version string to show (string)
     @keyparam versionCleanup tuple of two integers giving string positions
         start and stop for the version string (tuple of integers)
     @keyparam versionRe regexp to determine the line identifying version 
         info (string). Takes precedence over versionStartsWith.
     @return version string of detected or given version (string)
     """
     itm = QTreeWidgetItem(self.programsList, QStringList(description))
     font = itm.font(0)
     font.setBold(True)
     itm.setFont(0, font)
     if not exe:
         itm.setText(1, self.trUtf8("(not configured)"))
     else:
         if os.path.isabs(exe):
             if not Utilities.isExecutable(exe):
                 exe = ""
         else:
             exe = Utilities.getExecutablePath(exe)
         if exe:
             if versionCommand and \
                (versionStartsWith != "" or \
                 (versionRe is not None and versionRe != "")) and \
                versionPosition:
                 proc = QProcess()
                 proc.setProcessChannelMode(QProcess.MergedChannels)
                 proc.start(exe, QStringList(versionCommand))
                 finished = proc.waitForFinished(10000)
                 if finished:
                     output = \
                         unicode(proc.readAllStandardOutput(), 
                                 str(Preferences.getSystem("IOEncoding")), 
                                 'replace')
                     if versionRe is None:
                         versionRe = "^%s" % re.escape(versionStartsWith)
                     versionRe = re.compile(versionRe, re.UNICODE)
                     for line in output.splitlines():
                         if versionRe.search(line):
                             try:
                                 version = line.split()[versionPosition]
                                 if versionCleanup:
                                     version = \
                                         version[versionCleanup[0]:versionCleanup[1]]
                                 break
                             except IndexError:
                                 version = self.trUtf8("(unknown)")
                 else:
                     version = self.trUtf8("(not executable)")
             itm2 = QTreeWidgetItem(itm, QStringList() << exe << version)
             itm.setExpanded(True)
         else:
             itm.setText(1, self.trUtf8("(not found)"))
     QApplication.processEvents()
     self.programsList.header().resizeSections(QHeaderView.ResizeToContents)
     self.programsList.header().setStretchLastSection(True)
     return version
コード例 #34
0
ファイル: mod_host.py プロジェクト: moddevices/mod-app
class HostWindow(QMainWindow):
    # signals
    SIGTERM = pyqtSignal()
    SIGUSR1 = pyqtSignal()

    # --------------------------------------------------------------------------------------------------------

    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = Ui_HostWindow()
        self.ui.setupUi(self)

        # ----------------------------------------------------------------------------------------------------
        # Internal stuff

        # Current mod-ui title
        #self.fCurrentBundle = ""
        self.fCurrentTitle  = ""

        # Next bundle to load (done by startup arguments)
        self.fNextBundle = ""

        # first attempt of auto-start backend doesn't show an error
        self.fFirstBackendInit = True

        # need to call session reconnect after connecting the 1st time
        self.fNeedsSessionReconnect = False

        # Qt idle timer
        self.fIdleTimerId = 0

        # Qt web frame, used for evaluating javascript
        self.fWebFrame = None

        # to be filled with key-value pairs of current settings
        self.fSavedSettings = {}

        # List of pedalboards
        self.fPedalboards = get_all_pedalboards()

        # List of current-pedalboard presets
        self.fPresetMenuList = []

        # Process that runs the backend
        self.fProccessBackend = QProcess(self)
        self.fProccessBackend.setProcessChannelMode(QProcess.MergedChannels)
        self.fProccessBackend.setReadChannel(QProcess.StandardOutput)
        self.fStoppingBackend = False

        # Thread for managing the webserver
        self.fWebServerThread = WebServerThread(self)

        # ----------------------------------------------------------------------------------------------------
        # Set up GUI

        self.ui.webview = QWebView(self.ui.swp_webview)
        self.ui.webview.setMinimumWidth(980)
        self.ui.swp_webview.layout().addWidget(self.ui.webview)

        self.ui.webpage = HostWebPage(self)
        self.ui.webpage.setViewportSize(QSize(980, 600))
        self.ui.webview.setPage(self.ui.webpage)

        self.ui.webinspector = QWebInspector(None)
        self.ui.webinspector.resize(800, 600)
        self.ui.webinspector.setPage(self.ui.webpage)
        self.ui.webinspector.setVisible(False)

        self.ui.act_file_connect.setEnabled(False)
        self.ui.act_file_connect.setVisible(False)
        self.ui.act_file_disconnect.setEnabled(False)
        self.ui.act_file_disconnect.setVisible(False)

        self.ui.label_app.setText("MOD Application v%s" % config["version"])

        # disable file menu
        self.ui.act_file_refresh.setEnabled(False)
        self.ui.act_file_inspect.setEnabled(False)

        # disable pedalboard menu
        self.ui.act_pedalboard_new.setEnabled(False)
        self.ui.act_pedalboard_open.setEnabled(False)
        self.ui.act_pedalboard_save.setEnabled(False)
        self.ui.act_pedalboard_save_as.setEnabled(False)
        self.ui.act_pedalboard_share.setEnabled(False)
        self.ui.menu_Pedalboard.setEnabled(False)

        # disable presets menu
        self.ui.act_presets_new.setEnabled(False)
        self.ui.act_presets_save.setEnabled(False)
        self.ui.act_presets_save_as.setEnabled(False)
        self.ui.menu_Presets.setEnabled(False)

        # initial stopped state
        self.slot_backendFinished(-1, -1)

        # Qt needs this so it properly creates & resizes the webview
        self.ui.stackedwidget.setCurrentIndex(1)
        self.ui.stackedwidget.setCurrentIndex(0)

        # FIXME
        #self.ui.act_backend_stop.setVisible(False)
        #self.ui.act_backend_restart.setVisible(False)

        # ----------------------------------------------------------------------------------------------------
        # Set up GUI (special stuff for Mac OS)

        if MACOS:
            self.ui.act_file_quit.setMenuRole(QAction.QuitRole)
            self.ui.act_settings_configure.setMenuRole(QAction.PreferencesRole)
            self.ui.act_help_about.setMenuRole(QAction.AboutRole)
            #self.ui.menu_Settings.setTitle("Panels")
            #self.ui.menu_Help.hide()

        # ----------------------------------------------------------------------------------------------------
        # Set up GUI (special stuff for Live-MOD ISO)

        if USING_LIVE_ISO:
            self.ui.menubar.hide()
            self.ui.b_start.hide()
            self.ui.b_configure.hide()
            self.ui.b_about.hide()

        # ----------------------------------------------------------------------------------------------------
        # Load Settings

        self.loadSettings(True)

        # ----------------------------------------------------------------------------------------------------
        # Connect actions to functions

        self.SIGUSR1.connect(self.slot_handleSIGUSR1)
        self.SIGTERM.connect(self.slot_handleSIGTERM)

        self.fProccessBackend.error.connect(self.slot_backendError)
        self.fProccessBackend.started.connect(self.slot_backendStarted)
        self.fProccessBackend.finished.connect(self.slot_backendFinished)
        self.fProccessBackend.readyRead.connect(self.slot_backendRead)

        self.fWebServerThread.running.connect(self.slot_webServerRunning)
        self.fWebServerThread.finished.connect(self.slot_webServerFinished)

        self.ui.menu_Pedalboard.aboutToShow.connect(self.slot_pedalboardCheckOnline)

        self.ui.act_file_refresh.triggered.connect(self.slot_fileRefresh)
        self.ui.act_file_inspect.triggered.connect(self.slot_fileInspect)

        self.ui.act_backend_information.triggered.connect(self.slot_backendInformation)
        self.ui.act_backend_start.triggered.connect(self.slot_backendStart)
        self.ui.act_backend_stop.triggered.connect(self.slot_backendStop)
        self.ui.act_backend_restart.triggered.connect(self.slot_backendRestart)

        self.ui.act_pedalboard_new.triggered.connect(self.slot_pedalboardNew)
        self.ui.act_pedalboard_open.triggered.connect(self.slot_pedalboardOpen)
        self.ui.act_pedalboard_save.triggered.connect(self.slot_pedalboardSave)
        self.ui.act_pedalboard_save_as.triggered.connect(self.slot_pedalboardSaveAs)
        self.ui.act_pedalboard_share.triggered.connect(self.slot_pedalboardShare)

        self.ui.act_settings_configure.triggered.connect(self.slot_configure)

        self.ui.act_help_about.triggered.connect(self.slot_about)
        self.ui.act_help_project.triggered.connect(self.slot_showProject)
        self.ui.act_help_website.triggered.connect(self.slot_showWebsite)

        self.ui.b_start.clicked.connect(self.slot_backendStart)
        self.ui.b_configure.clicked.connect(self.slot_configure)
        self.ui.b_about.clicked.connect(self.slot_about)

        # force our custom refresh
        webReloadAction = self.ui.webpage.action(QWebPage.Reload)
        webReloadAction.triggered.disconnect()
        webReloadAction.triggered.connect(self.slot_fileRefresh)

        # ----------------------------------------------------------------------------------------------------
        # Final setup

        self.setProperWindowTitle()
        SESSION.setupApp(self._pedal_changed_callback)

        if not "--no-autostart" in sys.argv:
            QTimer.singleShot(0, self.slot_backendStart)

        QTimer.singleShot(1, self.fixWebViewSize)

    def __del__(self):
        self.stopAndWaitForWebServer()
        self.stopAndWaitForBackend()

    def _pedal_changed_callback(self, ok, bundlepath, title):
        #self.fCurrentBundle = bundlepath
        self.fCurrentTitle = title or ""
        #self.updatePresetsMenu()
        self.setProperWindowTitle()

    # --------------------------------------------------------------------------------------------------------
    # Files (menu actions)

    @pyqtSlot()
    def slot_fileRefresh(self):
        if self.fWebFrame is None:
            return

        self.ui.label_progress.setText(self.tr("Refreshing UI..."))
        self.ui.stackedwidget.setCurrentIndex(0)
        QTimer.singleShot(0, self.slot_fileRefreshPost)

    @pyqtSlot()
    def slot_fileRefreshPost(self):
        self.ui.webview.loadStarted.connect(self.slot_webviewLoadStarted)
        self.ui.webview.loadProgress.connect(self.slot_webviewLoadProgress)
        self.ui.webview.loadFinished.connect(self.slot_webviewLoadFinished)
        self.ui.webview.reload()

    @pyqtSlot()
    def slot_fileInspect(self):
        self.ui.webinspector.show()

    # --------------------------------------------------------------------------------------------------------
    # Pedalboard (menu actions)

    @pyqtSlot()
    def slot_pedalboardCheckOnline(self):
        if self.fWebFrame is None:
            return
        isOnline = self.fWebFrame.evaluateJavaScript("$('#mod-cloud').hasClass('logged')")
        if isOnline is None:
            return print("isOnline is None")
        self.ui.act_pedalboard_share.setEnabled(isOnline)

    @pyqtSlot()
    def slot_pedalboardNew(self):
        if self.fWebFrame is None:
            return

        self.fWebFrame.evaluateJavaScript("desktop.reset()")

    # --------------------------------------------------------------------------------------------------------

    @pyqtSlot()
    def slot_pedalboardOpen(self):
        if len(self.fPedalboards) == 0:
            return QMessageBox.information(self, self.tr("information"), "No pedalboards found")

        dialog = OpenPedalboardWindow(self, self.fPedalboards)

        if not dialog.exec_():
            return

        pedalboard = dialog.getSelectedURI()

        if not pedalboard:
            return QMessageBox.information(self, self.tr("information"), "Invalid pedalboard selected")

        try:
            bundle = get_bundle_dirname(pedalboard)
        except:
            return

        if self.fWebFrame is None:
            return

        self.fWebFrame.evaluateJavaScript("desktop.loadPedalboard(\"%s\")" % bundle)

    def openPedalboardLater(self, filename):
        try:
            self.fNextBundle   = QFileInfo(filename).absoluteFilePath()
            self.fCurrentTitle = get_pedalboard_info(self.fNextBundle)['name']
        except:
            self.fNextBundle   = ""
            self.fCurrentTitle = ""

    # --------------------------------------------------------------------------------------------------------

    @pyqtSlot()
    def slot_pedalboardSave(self, saveAs=False):
        if self.fWebFrame is None:
            return

        self.fWebFrame.evaluateJavaScript("desktop.saveCurrentPedalboard(%s)" % ("true" if saveAs else "false"))

    @pyqtSlot()
    def slot_pedalboardSaveAs(self):
        self.slot_pedalboardSave(True)

    # --------------------------------------------------------------------------------------------------------

    @pyqtSlot()
    def slot_pedalboardShare(self):
        if self.fWebFrame is None:
            return

        self.fWebFrame.evaluateJavaScript("desktop.shareCurrentPedalboard()")

    # --------------------------------------------------------------------------------------------------------
    # Presets (menu actions)

    @pyqtSlot()
    def slot_presetClicked(self):
        print(self.sender().data())

    # --------------------------------------------------------------------------------------------------------
    # Settings (menu actions)

    @pyqtSlot()
    def slot_configure(self):
        dialog = SettingsWindow(self, True)
        if not dialog.exec_():
            return

        self.loadSettings(False)

    # --------------------------------------------------------------------------------------------------------
    # About (menu actions)

    @pyqtSlot()
    def slot_about(self):
        QMessageBox.about(self, self.tr("About"), self.tr("""
            <b>MOD Desktop Application</b><br/>
            <br/>
            A software to have the complete MOD environment running in your desktop.<br/>
            (C) 2015-2016 - The MOD Team<br/>
            <br/>
            Publications, products, content or services referenced herein or on the website are the exclusive trademarks or servicemarks of MOD.<br/>
            Other product and company names mentioned in the site may be the trademarks of their respective owners.<br/>
            <br/>
            All software is available under the <a href="https://www.gnu.org/licenses/gpl-2.0.html">GPL license</a>.<br/>
        """))

    @pyqtSlot()
    def slot_showProject(self):
        QDesktopServices.openUrl(QUrl("https://github.com/moddevices/mod-app"))

    @pyqtSlot()
    def slot_showWebsite(self):
        QDesktopServices.openUrl(QUrl("http://moddevices.com/"))

    # --------------------------------------------------------------------------------------------------------
    # Backend (menu actions)

    @pyqtSlot()
    def slot_backendInformation(self):
        table = """
        <table><tr>
        <td> MOD-UI port:     <td></td> %s </td>
        </tr><tr>
        <td> Backend address: <td></td> %s </td>
        </tr></table>
        """ % (config["port"], "unix:///tmp/mod-app-%s.sock" % config["port"])
        QMessageBox.information(self, self.tr("information"), table)

    @pyqtSlot()
    def slot_backendStart(self):
        if self.fProccessBackend.state() != QProcess.NotRunning:
            print("slot_backendStart ignored")
            return

        print("slot_backendStart in progress...")

        if USING_LIVE_ISO:
            os.system("jack_wait -w")
            os.system("jack_load mod-monitor")

            hostPath = "jack_load"
            hostArgs = ["-w", "-a", "mod-host"]

        else:
            hostPath = self.fSavedSettings[MOD_KEY_HOST_PATH]
            if hostPath.endswith("ingen"):
                hostPath = MOD_DEFAULT_HOST_PATH

            hostArgs = ["-n"]

        self.fProccessBackend.start(hostPath, hostArgs)

    @pyqtSlot()
    def slot_backendStop(self, forced = False):
        #if self.fPluginCount > 0:
            #if not forced:
                #ask = QMessageBox.question(self, self.tr("Warning"), self.tr("There are still some plugins loaded, you need to remove them to stop the engine.\n"
                                                                            #"Do you want to do this now?"),
                                                                            #QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                #if ask != QMessageBox.Yes:
                    #return

            #self.removeAllPlugins()
            #self.host.set_engine_about_to_close()
            #self.host.remove_all_plugins()

        # testing red color for server stopped
        self.ui.webview.blockSignals(True)
        self.ui.webview.setHtml("<html><body bgcolor='green'></body></html>")
        self.ui.webview.blockSignals(False)

        self.stopAndWaitForWebServer()
        self.stopAndWaitForBackend()

    @pyqtSlot()
    def slot_backendRestart(self):
        #self.ui.stackedwidget.setCurrentIndex(0)
        self.slot_backendStop()
        #QApplication.instance().processEvents()
        self.slot_backendStart()

    # --------------------------------------------------------------------------------------------------------

    @pyqtSlot()
    def slot_backendStarted(self):
        self.ui.act_backend_start.setEnabled(False)
        self.ui.act_backend_stop.setEnabled(True)
        self.ui.act_backend_restart.setEnabled(True)
        self.ui.w_buttons.setEnabled(False)
        self.ui.label_progress.setText(self.tr("Loading backend..."))

    @pyqtSlot(int, QProcess.ExitStatus)
    def slot_backendFinished(self, exitCode, exitStatus):
        self.fFirstBackendInit = False
        self.fStoppingBackend = False
        self.ui.act_backend_start.setEnabled(True)
        self.ui.act_backend_stop.setEnabled(False)
        self.ui.act_backend_restart.setEnabled(False)
        self.ui.w_buttons.setEnabled(True)
        self.ui.label_progress.setText("")
        self.ui.stackedwidget.setCurrentIndex(0)

        # stop webserver
        self.stopAndWaitForWebServer()

    @pyqtSlot(QProcess.ProcessError)
    def slot_backendError(self, error):
        firstBackendInit = self.fFirstBackendInit
        self.fFirstBackendInit = False

        # stop webserver
        self.stopAndWaitForWebServer()

        # crashed while stopping, ignore
        if error == QProcess.Crashed and self.fStoppingBackend:
            return

        errorStr = self.tr("Could not start host backend.\n") + self.getProcessErrorAsString(error)
        qWarning(errorStr)

        # don't show error if this is the first time starting the host or using live-iso
        if firstBackendInit or USING_LIVE_ISO:
            return

        # show the error message
        QMessageBox.critical(self, self.tr("Error"), errorStr)

    @pyqtSlot()
    def slot_backendRead(self):
        #if self.fProccessBackend.state() != QProcess.Running:
            #return

        for line in str(self.fProccessBackend.readAllStandardOutput().trimmed(), encoding="utf-8", errors="ignore").strip().split("\n"):
            line = line.replace("\x1b[0m","").replace("\x1b[0;31m","").replace("\x1b[0;33m","").strip()
            if not line:
                continue

            if self.fSavedSettings[MOD_KEY_HOST_VERBOSE]:
                print("BACKEND:", line)

            if line == "mod-host ready!" or line == "mod-host is running.":
                QTimer.singleShot(0, self.slot_backendStartPhase2)
            #elif "Listening on socket " in line:
                #QTimer.singleShot(1000, self.slot_ingenStarted)
            ##elif "Activated Jack client " in line:
                ##QTimer.singleShot(1000, self.fWebServerThread.start)
            #elif "Failed to create UNIX socket" in line or "Could not activate Jack client" in line:
                ## need to wait for ingen to create sockets so it can delete them on termination
                #QTimer.singleShot(1000, self.slot_ingenStartError)

    @pyqtSlot()
    def slot_backendStartPhase2(self):
        if self.fProccessBackend.state() == QProcess.NotRunning:
            return

        if not self.fNeedsSessionReconnect:
            # we'll need it for next time
            self.fNeedsSessionReconnect = True
        else:
            # we need it now
            SESSION.reconnectApp()

        self.fWebServerThread.start()

    @pyqtSlot()
    def slot_backendStartError(self):
        self.stopAndWaitForBackend()
        self.slot_backendError(-2)

    # --------------------------------------------------------------------------------------------------------
    # Web Server

    @pyqtSlot()
    def slot_webServerRunning(self):
        try:
            self.ui.webview.loadStarted.connect(self.slot_webviewLoadStarted)
            self.ui.webview.loadProgress.connect(self.slot_webviewLoadProgress)
            self.ui.webview.loadFinished.connect(self.slot_webviewLoadFinished)
        except:
            pass

        print("webserver running")
        self.ui.webview.load(QUrl(config["addr"]))

    @pyqtSlot()
    def slot_webServerFinished(self):
        try:
            self.ui.webview.loadStarted.connect(self.slot_webviewLoadStarted)
            self.ui.webview.loadProgress.connect(self.slot_webviewLoadProgress)
            self.ui.webview.loadFinished.connect(self.slot_webviewLoadFinished)
        except:
            pass

        print("webserver finished")
        # testing red color for server finished
        self.ui.webview.blockSignals(True)
        self.ui.webview.setHtml("<html><body bgcolor='red'></body></html>")
        self.ui.webview.blockSignals(False)

    # --------------------------------------------------------------------------------------------------------
    # Web View

    @pyqtSlot()
    def slot_webviewLoadStarted(self):
        self.ui.label_progress.setText(self.tr("Loading UI..."))
        print("load started")

    @pyqtSlot(int)
    def slot_webviewLoadProgress(self, progress):
        self.ui.label_progress.setText(self.tr("Loading UI... %i%%" % progress))

    @pyqtSlot(bool)
    def slot_webviewLoadFinished(self, ok):
        self.ui.webview.loadStarted.disconnect(self.slot_webviewLoadStarted)
        self.ui.webview.loadProgress.disconnect(self.slot_webviewLoadProgress)
        self.ui.webview.loadFinished.disconnect(self.slot_webviewLoadFinished)

        if ok:
            # message
            self.ui.label_progress.setText(self.tr("Loading UI... finished!"))

            # enable file menu
            self.ui.act_file_refresh.setEnabled(True)
            self.ui.act_file_inspect.setEnabled(True)

            # for js evaulation
            self.fWebFrame = self.ui.webpage.currentFrame()

            # postpone app stuff
            QTimer.singleShot(100, self.slot_webviewPostFinished)

        else:
            # message
            self.ui.label_progress.setText(self.tr("Loading UI... failed!"))

            # disable file menu
            self.ui.act_file_refresh.setEnabled(False)
            self.ui.act_file_inspect.setEnabled(False)

            # disable pedalboard menu
            self.ui.act_pedalboard_new.setEnabled(False)
            self.ui.act_pedalboard_open.setEnabled(False)
            self.ui.act_pedalboard_save.setEnabled(False)
            self.ui.act_pedalboard_save_as.setEnabled(False)
            self.ui.act_pedalboard_share.setEnabled(False)
            self.ui.menu_Pedalboard.setEnabled(False)

            # stop js evaulation
            self.fWebFrame = None

            # stop backend&server
            self.stopAndWaitForWebServer()
            self.stopAndWaitForBackend()

        print("load finished")

    @pyqtSlot()
    def slot_webviewPostFinished(self):
        if self.fNextBundle:
            bundle = self.fNextBundle
            self.fNextBundle = ""
            self.fWebFrame.evaluateJavaScript("desktop.loadPedalboard(\"%s\")" % bundle)

        QTimer.singleShot(0, self.slot_webviewPostFinished2)

    @pyqtSlot()
    def slot_webviewPostFinished2(self):
        self.ui.stackedwidget.setCurrentIndex(1)

    # --------------------------------------------------------------------------------------------------------
    # Settings

    def saveSettings(self):
        settings = QSettings()
        settings.setValue("Geometry", self.saveGeometry())

    def loadSettings(self, firstTime):
        qsettings   = QSettings()
        websettings = self.ui.webview.settings()

        self.fSavedSettings = {
            # Main
            MOD_KEY_MAIN_PROJECT_FOLDER:    qsettings.value(MOD_KEY_MAIN_PROJECT_FOLDER,    MOD_DEFAULT_MAIN_PROJECT_FOLDER,    type=str),
            MOD_KEY_MAIN_REFRESH_INTERVAL:  qsettings.value(MOD_KEY_MAIN_REFRESH_INTERVAL,  MOD_DEFAULT_MAIN_REFRESH_INTERVAL,  type=int),
            # Host
            MOD_KEY_HOST_VERBOSE:           qsettings.value(MOD_KEY_HOST_VERBOSE,           MOD_DEFAULT_HOST_VERBOSE,           type=bool),
            MOD_KEY_HOST_PATH:              qsettings.value(MOD_KEY_HOST_PATH,              MOD_DEFAULT_HOST_PATH,              type=str),
            # WebView
            MOD_KEY_WEBVIEW_INSPECTOR:      qsettings.value(MOD_KEY_WEBVIEW_INSPECTOR,      MOD_DEFAULT_WEBVIEW_INSPECTOR,      type=bool),
            MOD_KEY_WEBVIEW_VERBOSE:        qsettings.value(MOD_KEY_WEBVIEW_VERBOSE,        MOD_DEFAULT_WEBVIEW_VERBOSE,        type=bool),
            MOD_KEY_WEBVIEW_SHOW_INSPECTOR: qsettings.value(MOD_KEY_WEBVIEW_SHOW_INSPECTOR, MOD_DEFAULT_WEBVIEW_SHOW_INSPECTOR, type=bool)
        }

        inspectorEnabled = self.fSavedSettings[MOD_KEY_WEBVIEW_INSPECTOR] and not USING_LIVE_ISO

        websettings.setAttribute(QWebSettings.DeveloperExtrasEnabled, inspectorEnabled)

        if firstTime:
            if qsettings.contains("Geometry"):
                self.restoreGeometry(qsettings.value("Geometry", ""))
            else:
                self.setWindowState(self.windowState() | Qt.WindowMaximized)

            if inspectorEnabled and self.fSavedSettings[MOD_KEY_WEBVIEW_SHOW_INSPECTOR]:
                QTimer.singleShot(1000, self.ui.webinspector.show)

        self.ui.act_file_inspect.setVisible(inspectorEnabled)

        if self.fIdleTimerId != 0:
            self.killTimer(self.fIdleTimerId)

        self.fIdleTimerId = self.startTimer(self.fSavedSettings[MOD_KEY_MAIN_REFRESH_INTERVAL])

    # --------------------------------------------------------------------------------------------------------
    # Misc

    @pyqtSlot()
    def slot_handleSIGUSR1(self):
        print("Got SIGUSR1 -> Saving project now")
        self.slot_pedalboardSave()

    @pyqtSlot()
    def slot_handleSIGTERM(self):
        print("Got SIGTERM -> Closing now")
        self.close()

    # --------------------------------------------------------------------------------------------------------
    # Qt events

    def closeEvent(self, event):
        if self.fIdleTimerId != 0:
            self.killTimer(self.fIdleTimerId)
            self.fIdleTimerId = 0

        self.saveSettings()
        self.slot_backendStop(True)

        QMainWindow.closeEvent(self, event)

        # Needed in case the web inspector is still alive
        #self.ui.webinspector.close()
        QApplication.instance().quit()

    def timerEvent(self, event):
        if event.timerId() == self.fIdleTimerId:
            pass

        QMainWindow.timerEvent(self, event)

    def resizeEvent(self, event):
        QMainWindow.resizeEvent(self, event)
        self.fixWebViewSize()

    # --------------------------------------------------------------------------------------------------------
    # Internal stuff

    def getProcessErrorAsString(self, error):
        if error == -2:
            return self.tr("Ingen failed to create UNIX socket.")
        if error == QProcess.FailedToStart:
            return self.tr("Process failed to start.")
        if error == QProcess.Crashed:
            return self.tr("Process crashed.")
        if error == QProcess.Timedout:
            return self.tr("Process timed out.")
        if error == QProcess.WriteError:
            return self.tr("Process write error.")
        return self.tr("Unkown error.")

    def fixWebViewSize(self):
        if self.ui.stackedwidget.currentIndex() == 1:
            return

        size = self.ui.swp_intro.size()
        self.ui.swp_webview.resize(size)
        self.ui.webview.resize(size)
        self.ui.webpage.setViewportSize(size)

    def stopAndWaitForBackend(self):
        if self.fProccessBackend.state() == QProcess.NotRunning:
            return

        self.fStoppingBackend = True
        self.fProccessBackend.terminate()
        if not self.fProccessBackend.waitForFinished(2000):
            qWarning("Backend failed top stop cleanly, forced kill")
            self.fProccessBackend.kill()

    def stopAndWaitForWebServer(self):
        if not self.fWebServerThread.isRunning():
            return

        if not self.fWebServerThread.stopWait():
            qWarning("WebServer Thread failed top stop cleanly, forced terminate")
            self.fWebServerThread.terminate()

    def setProperWindowTitle(self):
        title = "MOD Application"

        if self.fCurrentTitle:
            title += " - %s" % self.fCurrentTitle

        self.setWindowTitle(title)
コード例 #35
0
class DialogueNew(QtGui.QDialog, FORM_CLASS):
    
    SOURCES = ["ASCII squared raster", "CSV file", "Python function"]
    METHODS = ["Multi-quadratic", "Nearest neighbour"]
    METHODS_ABRV = ["mq", "nn"]
    
    iface = None
    
    def __init__(self, parent=None):
        """Constructor."""
        super(DialogueNew, self).__init__(parent)
        # Set up the user interface from Designer.
        # After setupUI you can access any designer object by doing
        # self.<objectname>, and you can use autoconnect slots - see
        # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
        # #widgets-and-dialogs-with-auto-connect
        self.setupUi(self)
        
        self.comboBoxSource.addItems(self.SOURCES)
        self.comboBoxSource.currentIndexChanged.connect(self.sourceChanged)
        
        self.comboBoxMethod.addItems(self.METHODS)
        
        self.buttonBox.button(QDialogButtonBox.Ok).setText("Run")
        self.buttonBox.button(QDialogButtonBox.Cancel).setText("Exit")
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        
        # Activate file search buttons
        self.pushButtonSource.clicked.connect(self.selectFileSource)
        self.pushButtonOutput.clicked.connect(self.selectFileOutput)
        
        self.resize(520, 430)
        
        
    def accept(self):
        
        if(not self.checkOptions()):
            return
        
        self.resize(520, 610)
        
        if(self.comboBoxSource.currentText() == self.SOURCES[0]):
            if(self.comboBoxMethod == self.METHODS[0]):
                meth_abv = self.METHODS_ABRV[0]
            else:
                meth_abv = self.METHODS_ABRV[1]
            args = QStringList()
            args.append("-i" + self.filePathSource.text())
            args.append("-o" + self.filePathOutput.text())
            args.append("-m" + meth_abv)
            self.proc = QProcess()
            self.proc.start("asc2hasc", args)
            self.proc.setProcessChannelMode(QProcess.MergedChannels);
            QObject.connect(self.proc, SIGNAL("readyReadStandardOutput()"), self, SLOT("readStdOutput()"))
            #self.setGeometry(self._parent.x(), self._parent.y(), self.width(), 610)
            
        if(self.comboBoxSource.currentText() == self.SOURCES[1]):
            args = QStringList()
            args.append("-i" + self.filePathSource.text())
            args.append("-o" + self.filePathOutput.text())
            args.append("-s" + self.cellSide.text())
            self.proc = QProcess()
            self.proc.start("csv2hasc", args)
            self.proc.setProcessChannelMode(QProcess.MergedChannels);
            QObject.connect(self.proc, SIGNAL("readyReadStandardOutput()"), self, SLOT("readStdOutput()"))
            
        if(self.comboBoxSource.currentText() == self.SOURCES[2]):
            args = QStringList()
            args.append("-m" + self.filePathSource.text())
            args.append("-o" + self.filePathOutput.text())
            args.append("-f" + self.pythonFunction.text())
            args.append("-s" + self.cellSide.text())
            args.append("-x" + self.eastingRight.text())
            args.append("-X" + self.eastingLeft.text())
            args.append("-y" + self.northingBottom.text())
            args.append("-Y" + self.northingTop.text())
            self.proc = QProcess()
            self.proc.start("surface2hasc", args)
            self.proc.setProcessChannelMode(QProcess.MergedChannels);
            QObject.connect(self.proc, SIGNAL("readyReadStandardOutput()"), self, SLOT("readStdOutput()"))  

    @pyqtSlot()
    def readStdOutput(self):
        self.commandOutput.append(QString(self.proc.readAllStandardOutput()))        
        
        
    def reject(self):
        
        self.done(0)
        
    
    def selectFileSource(self):
        
        extension = ""
        if(self.comboBoxSource.currentText() == self.SOURCES[0]):
            extension = '*.asc'
        elif(self.comboBoxSource.currentText() == self.SOURCES[1]):
            extension = '*.csv'
        elif(self.comboBoxSource.currentText() == self.SOURCES[2]):
            extension = '*.py'
        
        self.fileNameSource = QFileDialog.getOpenFileName(self, "Select file ","", extension);
        self.filePathSource.setText(self.fileNameSource)
        
        
    def selectFileOutput(self):
                
        self.fileNameOutput = QFileDialog.getOpenFileName(self, "Select file ","", "*.hasc");
        self.filePathOutput.setText(self.fileNameOutput)
        
        
    def sourceChanged(self, i):
        
        if(self.comboBoxSource.currentText() == self.SOURCES[0]):
            self.pushButtonSource.setEnabled(True)
            self.labelExtent.setEnabled(False)
            self.labelNorthingTop.setEnabled(False)
            self.labelNorthingBottom.setEnabled(False)
            self.labelEastingRight.setEnabled(False)
            self.labelEastingLeft.setEnabled(False)
            self.northingTop.setEnabled(False)
            self.northingBottom.setEnabled(False)
            self.eastingRight.setEnabled(False)
            self.eastingLeft.setEnabled(False)
            self.labelMethod.setEnabled(True)
            self.comboBoxMethod.setEnabled(True)
            self.pythonFunction.setEnabled(False)
            self.labelPythonFunction.setEnabled(False)
            self.cellSide.setEnabled(False)
            self.labelCellSide.setEnabled(False)
            
        elif(self.comboBoxSource.currentText() == self.SOURCES[1]):
            self.pushButtonSource.setEnabled(True)
            self.labelExtent.setEnabled(False)
            self.labelNorthingTop.setEnabled(False)
            self.labelNorthingBottom.setEnabled(False)
            self.labelEastingRight.setEnabled(False)
            self.labelEastingLeft.setEnabled(False)
            self.northingTop.setEnabled(False)
            self.northingBottom.setEnabled(False)
            self.eastingRight.setEnabled(False)
            self.eastingLeft.setEnabled(False)
            self.labelMethod.setEnabled(False)
            self.comboBoxMethod.setEnabled(False)
            self.pythonFunction.setEnabled(False)
            self.labelPythonFunction.setEnabled(False)
            self.cellSide.setEnabled(True)
            self.labelCellSide.setEnabled(True)
            
        elif(self.comboBoxSource.currentText() == self.SOURCES[2]):
            self.pushButtonSource.setEnabled(True)
            self.labelExtent.setEnabled(True)
            self.labelNorthingTop.setEnabled(True)
            self.labelNorthingBottom.setEnabled(True)
            self.labelEastingRight.setEnabled(True)
            self.labelEastingLeft.setEnabled(True)
            self.northingTop.setEnabled(True)
            self.northingBottom.setEnabled(True)
            self.eastingRight.setEnabled(True)
            self.eastingLeft.setEnabled(True)
            self.labelMethod.setEnabled(False)
            self.comboBoxMethod.setEnabled(False)
            self.pythonFunction.setEnabled(True)            
            self.labelPythonFunction.setEnabled(True)
            self.cellSide.setEnabled(True)
            self.labelCellSide.setEnabled(True)
        
        else:
            return
        
        
    def checkOptions(self):
        
        if(self.comboBoxSource.currentText() == ""):
            self.showErrorMessage("Please select a source type.")
            return False
        
        if(self.filePathOutput.text() == None or self.filePathOutput.text() == ""):
            self.showErrorMessage("Please provide an output file.")
            return False
        
        if(self.filePathSource.text() == None or self.filePathSource.text() == ""):
            self.showErrorMessage("Please select a source file.")
            return False

        if(self.comboBoxSource.currentText() != self.SOURCES[0]):
            if(self.northingTop.text() == None or self.northingTop.text() == "" or 
               self.northingBottom.text() == None or self.northingBottom.text() == "" or
               self.eastingRight.text() == None or self.eastingRight.text() == "" or
               self.eastingLeft.text() == None or self.eastingLeft.text() == ""):
                self.showErrorMessage("Extent is mandatory for this source type.")
                return False     
            if(self.cellSide.text() == None or self.cellSide.text() == ""):
                self.showErrorMessage("A cell side length is required for this source type.")
                return False
        
        if(self.comboBoxSource.currentText() == self.SOURCES[2]):              
            if(self.pythonFunction.text() == None or self.pythonFunction.text() == ""):
                self.showErrorMessage("Please select a Python function in the module.")
                return False
            
        return True
     
     
    def showErrorMessage(self, mesg):
                  
        msgBox = QMessageBox()
        msgBox.setIcon(QMessageBox.Warning)
        msgBox.setText(mesg)
        msgBox.setWindowTitle("Unable to proceed")
        msgBox.exec_()

        
        
        
        
        
コード例 #36
0
ファイル: freshexample.py プロジェクト: hlamer/fresh
 def interpret(self, command):
     """Interprets command
     Returns turple (output, exitCode)
     """
     print '~~~~~~~~~ interpret'
     ec = pConsoleCommand.NotFound
     output, ec = pConsoleCommand.interpret( command)
     parts = self.parseCommands( command )
     if parts:
         cmd = parts.takeFirst()
     else:
         cmd = ''
     
     if ec != pConsoleCommand.NotFound :            # nothing to do
         pass
     elif  cmd == "ls" :
         if sys.platform.startswith('win'):
             cmd = "dir %s" % \
             " ".join(pConsoleCommand.quotedStringList(parts)).trim()
         else:
             cmd = "dir %s" % " ".join( \
                 pConsoleCommand.quotedStringList(parts)).trimmed()
         
         process = QProcess()
         process.setProcessChannelMode( QProcess.MergedChannels )
         process.start( cmd )
         process.waitForStarted()
         process.waitForFinished()
         
         output = process.readAll().trimmed()
         ec = process.exitCode()
     elif  cmd == "echo" :
         if parts:
             output = "\n".join(parts)
             ec = pConsoleCommand.Error
         else:
             output = pConsole.tr(console, "No argument given" )
             ec = pConsoleCommand.Success
     elif  cmd == "quit":
         output = pConsole.tr(console, "Quitting the application..." )
         ec = pConsoleCommand.Success
         
         QTimer.singleShot(1000, qApp.quit() )
     elif  cmd == "style" :
         if  parts.count() != 1 :
             output = pConsole.tr(console, "%s take only 1 parameter, %d given"  %
                                     (cmd, len(parts)) )
             ec = pConsoleCommand.Error
         elif  parts[-1] == "list" :
             output = pConsole.tr(console, "Available styles:\n%s" % 
                                     '\n'.join(QStyleFactory.keys()) )
             ec = pConsoleCommand.Success
         else:
             styleExists = parts[-1].lower() in \
                         [key.lower() for key in QStyleFactory.keys()]
             if styleExists:
                 output = pConsole.tr(console, "Setting style to %s..." % parts[-1])
                 self.mMainWindow.setCurrentStyle( parts[-1] )
                 ec = pConsoleCommand.Success
             else:
                 output = pConsole.tr(console, "This style does not exists" )
                 ec = pConsoleCommand.Error
     
     return (output, ec)