コード例 #1
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()
コード例 #2
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()
コード例 #3
0
class QProcessTransport(Transport):
    '''A Transport communicating with a child process.
    
    Start the process using .start().
    
    Sent data is written to the process' stdin.
    
    Data is received from the process's stdout and processed on the Qt mainloop 
    thread.
    '''
    shorthand='qprocess'
    @classmethod
    def fromstring(cls, expression):
        '''qprocess:(<commandline>)'''
        _, _, expr = expression.partition(':')
        cmdline, _, _ = paren_partition(expr)
        return cls(cmdline, sendername=expression)

    def __init__(self, cmdline, sendername='qprocess'):
        self.cmdline = cmdline
        self.sendername = sendername
        self.leftover = b''
        self.process = QProcess()
        self.process.readyRead.connect(self.on_ready_read)
        self.process.finished.connect(self.on_finished)

    def start(self):
        L().debug('starting: %r'%self.cmdline)
        self.process.start(self.cmdline)
        
    def stop(self, kill=False):
        if kill:
            self.process.kill()
        else:
            self.process.terminate()
            self.process.waitForFinished()

    def send(self, data, receivers=None):
        if receivers is not None and self.sendername not in receivers:
            return
        L().debug('message to child processs: %s'%data)
        self.process.write(data.decode('utf8'))

    def on_ready_read(self):
        data = self.process.readAllStandardOutput().data()
        errors = self.process.readAllStandardError().data().decode('utf8')
        if errors:
            L().error('Error from child process:\n%s' % errors)
        pdata = data.decode('utf8')
        if len(pdata) > 100:
            pdata = pdata[:100] + '...'
        #if pdata.startswith('{'):
        L().debug('message from child process: %s'%pdata)
        self.leftover = self.received(
            sender=self.sendername,
            data=self.leftover + data
        )

    def on_finished(self):
        L().info('Child process exited.')
コード例 #4
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()
コード例 #5
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()
コード例 #6
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()
コード例 #7
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()
コード例 #8
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()
コード例 #9
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)
コード例 #10
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()
コード例 #11
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()
コード例 #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 RdpConnection(object):

    _cfg = None
    _conn = None

    def __init__(self, cfg):
        self._cfg = cfg

    def connect(self, parent_window=None):
        if not parent_window is None:
            setattr(self._cfg, 'parent-window', parent_window)

        self._conn = QProcess()
        # print(self._cfg.as_list())
        self._conn.start('xfreerdp', self._cfg.as_list())
        self._conn.readyReadStandardOutput.connect(self._read_out)
        self._conn.readyReadStandardError.connect(self._read_err)

    def close(self):
        self._conn.close()
        self._conn.terminate()

    def connect_output(self, out_listener):
        self._out_listener = out_listener

    def _read_out(self):
        if not self._out_listener is None:
            self._out_listener(str(self._conn.readAllStandardOutput()))

    def _read_err(self):
        if not self._out_listener is None:
            self._out_listener(str(self._conn.readAllStandardError()))

    @property
    def cfg(self):
        return self._cfg
コード例 #15
0
ファイル: rdp.py プロジェクト: tiagoengel/pyrdp
class RdpConnection(object):
    
    _cfg = None
    _conn = None
    
    def __init__(self, cfg):
        self._cfg = cfg
    
    def connect(self, parent_window=None):
        if not parent_window is None:
            setattr(self._cfg, 'parent-window', parent_window)

        self._conn = QProcess()
        # print(self._cfg.as_list())
        self._conn.start('xfreerdp', self._cfg.as_list())
        self._conn.readyReadStandardOutput.connect(self._read_out)
        self._conn.readyReadStandardError.connect(self._read_err)
    
    def close(self):
        self._conn.close()
        self._conn.terminate()

    def connect_output(self, out_listener):
        self._out_listener = out_listener

    def _read_out(self):
        if not self._out_listener is None:
            self._out_listener(str(self._conn.readAllStandardOutput()))

    def _read_err(self):
        if not self._out_listener is None:
            self._out_listener(str(self._conn.readAllStandardError()))
        
    @property    
    def cfg(self):
        return self._cfg
コード例 #16
0
                firstStart = False
                print(
                    "cadence-aloop-daemon started, using %s and %i channels" %
                    ("zita-a2j/j2a" if useZita else "alsa_in/out", channels))

            run_alsa_bridge()
            doRunNow = False

        elif isKernelGood and reactivateCounter >= 0:
            if reactivateCounter == 5:
                reactivateCounter = -1
                doRunNow = True
            else:
                reactivateCounter += 1

        sleep(1)

    # Close JACK client
    jacklib.deactivate(client)
    jacklib.client_close(client)

    if os.path.exists(checkFile):
        os.remove(checkFile)

    if procIn.state() != QProcess.NotRunning:
        procIn.terminate()
        procIn.waitForFinished(1000)
    if procOut.state() != QProcess.NotRunning:
        procOut.terminate()
        procOut.waitForFinished(1000)
コード例 #17
0
class SvnChangeListsDialog(QDialog, Ui_SvnChangeListsDialog):
    """
    Class implementing a dialog to browse the change lists.
    """
    def __init__(self, vcs, parent=None):
        """
        Constructor
        
        @param vcs reference to the vcs object
        @param parent parent widget (QWidget)
        """
        QDialog.__init__(self, parent)
        self.setupUi(self)
        
        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
        
        self.process = None
        self.vcs = vcs
        
        self.rx_status = \
            QRegExp('(.{8,9})\\s+([0-9-]+)\\s+([0-9?]+)\\s+(\\S+)\\s+(.+)\\s*')
            # flags (8 or 9 anything), revision, changed rev, author, path
        self.rx_status2 = \
            QRegExp('(.{8,9})\\s+(.+)\\s*')
            # flags (8 or 9 anything), path
        self.rx_changelist = \
            QRegExp('--- \\S+ .([\\w\\s]+).:\\s+')
            # three dashes, Changelist (translated), quote,
            # changelist name, quote, :
    
    @pyqtSignature("QListWidgetItem*, QListWidgetItem*")
    def on_changeLists_currentItemChanged(self, current, previous):
        """
        Private slot to handle the selection of a new item.
        
        @param current current item (QListWidgetItem)
        @param previous previous current item (QListWidgetItem)
        """
        self.filesList.clear()
        if current is not None:
            changelist = unicode(current.text())
            if changelist in self.changeListsDict:
                self.filesList.addItems(sorted(self.changeListsDict[changelist]))
    
    def start(self, path):
        """
        Public slot to populate the data.
        
        @param path directory name to show change lists for (string)
        """
        self.changeListsDict = {}
        
        self.filesLabel.setText(self.trUtf8("Files (relative to %1):").arg(path))
        
        self.errorGroup.hide()
        self.intercept = False
        
        self.path = path
        self.currentChangelist = ""
        
        self.process = QProcess()
        self.process.finished.connect(self.__procFinished)
        self.process.readyReadStandardOutput.connect(self.__readStdout)
        self.process.readyReadStandardError.connect(self.__readStderr)
        
        args = []
        args.append('status')
        self.vcs.addArguments(args, self.vcs.options['global'])
        self.vcs.addArguments(args, self.vcs.options['status'])
        if '--verbose' not in self.vcs.options['global'] and \
           '--verbose' not in self.vcs.options['status']:
            args.append('--verbose')
        if isinstance(path, list):
            self.dname, fnames = self.vcs.splitPathList(path)
            self.vcs.addArguments(args, fnames)
        else:
            self.dname, fname = self.vcs.splitPath(path)
            args.append(fname)
        
        self.process.setWorkingDirectory(self.dname)
        
        self.process.start('svn', args)
        procStarted = self.process.waitForStarted()
        if not procStarted:
            self.inputGroup.setEnabled(False)
            self.inputGroup.hide()
            KQMessageBox.critical(self,
                self.trUtf8('Process Generation Error'),
                self.trUtf8(
                    'The process %1 could not be started. '
                    'Ensure, that it is in the search path.'
                ).arg('svn'))
        else:
            self.inputGroup.setEnabled(True)
            self.inputGroup.show()
    
    def __finish(self):
        """
        Private slot called when the process finished or the user pressed
        the button.
        """
        if self.process is not None and \
           self.process.state() != QProcess.NotRunning:
            self.process.terminate()
            QTimer.singleShot(2000, self.process.kill)
            self.process.waitForFinished(3000)
        
        self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
        self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
        self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
        
        self.inputGroup.setEnabled(False)
        self.inputGroup.hide()
        
        if len(self.changeListsDict) == 0:
            self.changeLists.addItem(self.trUtf8("No changelists found"))
            self.buttonBox.button(QDialogButtonBox.Close).setFocus(Qt.OtherFocusReason)
        else:
            self.changeLists.addItems(sorted(self.changeListsDict.keys()))
            self.changeLists.setCurrentRow(0)
            self.changeLists.setFocus(Qt.OtherFocusReason)
    
    def on_buttonBox_clicked(self, button):
        """
        Private slot called by a button of the button box clicked.
        
        @param button button that was clicked (QAbstractButton)
        """
        if button == self.buttonBox.button(QDialogButtonBox.Close):
            self.close()
        elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
            self.__finish()
        
    def __procFinished(self, exitCode, exitStatus):
        """
        Private slot connected to the finished signal.
        
        @param exitCode exit code of the process (integer)
        @param exitStatus exit status of the process (QProcess.ExitStatus)
        """
        self.__finish()
        
    def __readStdout(self):
        """
        Private slot to handle the readyReadStandardOutput signal.
        
        It reads the output of the process, formats it and inserts it into
        the contents pane.
        """
        if self.process is not None:
            self.process.setReadChannel(QProcess.StandardOutput)
            
            while self.process.canReadLine():
                s = unicode(self.process.readLine(),
                            Preferences.getSystem("IOEncoding"),
                            'replace')
                if self.currentChangelist != "" and self.rx_status.exactMatch(s):
                    file = unicode(self.rx_status.cap(5)).strip()
                    filename = file.replace(self.path + os.sep, "")
                    if filename not in self.changeListsDict[self.currentChangelist]:
                        self.changeListsDict[self.currentChangelist].append(filename)
                elif self.currentChangelist != "" and self.rx_status2.exactMatch(s):
                    file = unicode(self.rx_status2.cap(2)).strip()
                    filename = file.replace(self.path + os.sep, "")
                    if filename not in self.changeListsDict[self.currentChangelist]:
                        self.changeListsDict[self.currentChangelist].append(filename)
                elif self.rx_changelist.exactMatch(s):
                    self.currentChangelist = unicode(self.rx_changelist.cap(1))
                    if self.currentChangelist not in self.changeListsDict:
                        self.changeListsDict[self.currentChangelist] = []
        
    def __readStderr(self):
        """
        Private slot to handle the readyReadStandardError signal.
        
        It reads the error output of the process and inserts it into the
        error pane.
        """
        if self.process is not None:
            self.errorGroup.show()
            s = QString(self.process.readAllStandardError())
            self.errors.insertPlainText(s)
            self.errors.ensureCursorVisible()
        
    def on_passwordCheckBox_toggled(self, isOn):
        """
        Private slot to handle the password checkbox toggled.
        
        @param isOn flag indicating the status of the check box (boolean)
        """
        if isOn:
            self.input.setEchoMode(QLineEdit.Password)
        else:
            self.input.setEchoMode(QLineEdit.Normal)
        
    @pyqtSignature("")
    def on_sendButton_clicked(self):
        """
        Private slot to send the input to the subversion process.
        """
        input = self.input.text()
        input += os.linesep
        
        if self.passwordCheckBox.isChecked():
            self.errors.insertPlainText(os.linesep)
            self.errors.ensureCursorVisible()
        else:
            self.errors.insertPlainText(input)
            self.errors.ensureCursorVisible()
        
        self.process.write(input)
        
        self.passwordCheckBox.setChecked(False)
        self.input.clear()
        
    def on_input_returnPressed(self):
        """
        Private slot to handle the press of the return key in the input field.
        """
        self.intercept = True
        self.on_sendButton_clicked()
        
    def keyPressEvent(self, evt):
        """
        Protected slot to handle a key press event.
        
        @param evt the key press event (QKeyEvent)
        """
        if self.intercept:
            self.intercept = False
            evt.accept()
            return
        QDialog.keyPressEvent(self, evt)
コード例 #18
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)
コード例 #19
0
class RenderW(QDialog):
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.ui = ui_render.Ui_RenderW()
        self.ui.setupUi(self)

        self.fFreewheel = False
        self.fLastTime = -1
        self.fMaxTime = 180

        self.fTimer = QTimer(self)
        self.fProcess = QProcess(self)

        # -------------------------------------------------------------
        # Get JACK client and base information

        global gJackClient

        if gJackClient:
            self.fJackClient = gJackClient
        else:
            self.fJackClient = jacklib.client_open("Render-Dialog",
                                                   jacklib.JackNoStartServer,
                                                   None)

        self.fBufferSize = int(jacklib.get_buffer_size(self.fJackClient))
        self.fSampleRate = int(jacklib.get_sample_rate(self.fJackClient))

        for i in range(self.ui.cb_buffer_size.count()):
            if int(self.ui.cb_buffer_size.itemText(i)) == self.fBufferSize:
                self.ui.cb_buffer_size.setCurrentIndex(i)
                break
        else:
            self.ui.cb_buffer_size.addItem(str(self.fBufferSize))
            self.ui.cb_buffer_size.setCurrentIndex(
                self.ui.cb_buffer_size.count() - 1)

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

        # Get List of formats
        self.fProcess.start(gJackCapturePath, ["-pf"])
        self.fProcess.waitForFinished()

        formats = str(self.fProcess.readAllStandardOutput(),
                      encoding="utf-8").split(" ")
        formatsList = []

        for i in range(len(formats) - 1):
            iFormat = formats[i].strip()
            if iFormat:
                formatsList.append(iFormat)

        formatsList.sort()

        # Put all formats in combo-box, select 'wav' option
        for i in range(len(formatsList)):
            self.ui.cb_format.addItem(formatsList[i])
            if formatsList[i] == "wav":
                self.ui.cb_format.setCurrentIndex(i)

        self.ui.cb_depth.setCurrentIndex(4)  #Float
        self.ui.rb_stereo.setChecked(True)

        self.ui.te_end.setTime(QTime(0, 3, 0))
        self.ui.progressBar.setFormat("")
        self.ui.progressBar.setMinimum(0)
        self.ui.progressBar.setMaximum(1)
        self.ui.progressBar.setValue(0)

        self.ui.b_render.setIcon(getIcon("media-record"))
        self.ui.b_stop.setIcon(getIcon("media-playback-stop"))
        self.ui.b_close.setIcon(getIcon("window-close"))
        self.ui.b_open.setIcon(getIcon("document-open"))
        self.ui.b_stop.setVisible(False)
        self.ui.le_folder.setText(HOME)

        # -------------------------------------------------------------
        # Set-up connections

        self.connect(self.ui.b_render, SIGNAL("clicked()"),
                     SLOT("slot_renderStart()"))
        self.connect(self.ui.b_stop, SIGNAL("clicked()"),
                     SLOT("slot_renderStop()"))
        self.connect(self.ui.b_open, SIGNAL("clicked()"),
                     SLOT("slot_getAndSetPath()"))
        self.connect(self.ui.b_now_start, SIGNAL("clicked()"),
                     SLOT("slot_setStartNow()"))
        self.connect(self.ui.b_now_end, SIGNAL("clicked()"),
                     SLOT("slot_setEndNow()"))
        self.connect(self.ui.te_start, SIGNAL("timeChanged(const QTime)"),
                     SLOT("slot_updateStartTime(const QTime)"))
        self.connect(self.ui.te_end, SIGNAL("timeChanged(const QTime)"),
                     SLOT("slot_updateEndTime(const QTime)"))
        self.connect(self.ui.group_time, SIGNAL("clicked(bool)"),
                     SLOT("slot_transportChecked(bool)"))
        self.connect(self.fTimer, SIGNAL("timeout()"),
                     SLOT("slot_updateProgressbar()"))

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

        self.loadSettings()

    @pyqtSlot()
    def slot_renderStart(self):
        if not os.path.exists(self.ui.le_folder.text()):
            QMessageBox.warning(
                self, self.tr("Warning"),
                self.
                tr("The selected directory does not exist. Please choose a valid one."
                   ))
            return

        timeStart = self.ui.te_start.time()
        timeEnd = self.ui.te_end.time()
        minTime = (timeStart.hour() * 3600) + (timeStart.minute() *
                                               60) + (timeStart.second())
        maxTime = (timeEnd.hour() * 3600) + (timeEnd.minute() *
                                             60) + (timeEnd.second())

        newBufferSize = int(self.ui.cb_buffer_size.currentText())
        useTransport = self.ui.group_time.isChecked()

        self.fFreewheel = bool(self.ui.cb_render_mode.currentIndex() == 1)
        self.fLastTime = -1
        self.fMaxTime = maxTime

        if self.fFreewheel:
            self.fTimer.setInterval(100)
        else:
            self.fTimer.setInterval(500)

        self.ui.group_render.setEnabled(False)
        self.ui.group_time.setEnabled(False)
        self.ui.group_encoding.setEnabled(False)
        self.ui.b_render.setVisible(False)
        self.ui.b_stop.setVisible(True)
        self.ui.b_close.setEnabled(False)

        if useTransport:
            self.ui.progressBar.setFormat("%p%")
            self.ui.progressBar.setMinimum(minTime)
            self.ui.progressBar.setMaximum(maxTime)
            self.ui.progressBar.setValue(minTime)
        else:
            self.ui.progressBar.setFormat("")
            self.ui.progressBar.setMinimum(0)
            self.ui.progressBar.setMaximum(0)
            self.ui.progressBar.setValue(0)

        self.ui.progressBar.update()

        arguments = []

        # Filename prefix
        arguments.append("-fp")
        arguments.append(self.ui.le_prefix.text())

        # Format
        arguments.append("-f")
        arguments.append(self.ui.cb_format.currentText())

        # Bit depth
        arguments.append("-b")
        arguments.append(self.ui.cb_depth.currentText())

        # Channels
        arguments.append("-c")
        if self.ui.rb_mono.isChecked():
            arguments.append("1")
        elif self.ui.rb_stereo.isChecked():
            arguments.append("2")
        else:
            arguments.append(str(self.ui.sb_channels.value()))

        # Controlled only by freewheel
        if self.fFreewheel:
            arguments.append("-jf")

        # Controlled by transport
        elif useTransport:
            arguments.append("-jt")

        # Silent mode
        arguments.append("-dc")
        arguments.append("-s")

        # Change current directory
        os.chdir(self.ui.le_folder.text())

        if newBufferSize != int(jacklib.get_buffer_size(self.fJackClient)):
            print("NOTICE: buffer size changed before render")
            jacklib.set_buffer_size(self.fJackClient, newBufferSize)

        if useTransport:
            if jacklib.transport_query(
                    self.fJackClient, None
            ) > jacklib.JackTransportStopped:  # rolling or starting
                jacklib.transport_stop(self.fJackClient)

            jacklib.transport_locate(self.fJackClient,
                                     minTime * self.fSampleRate)

        self.fProcess.start(gJackCapturePath, arguments)
        self.fProcess.waitForStarted()

        if self.fFreewheel:
            print("NOTICE: rendering in freewheel mode")
            sleep(1)
            jacklib.set_freewheel(self.fJackClient, 1)

        if useTransport:
            self.fTimer.start()
            jacklib.transport_start(self.fJackClient)

    @pyqtSlot()
    def slot_renderStop(self):
        useTransport = self.ui.group_time.isChecked()

        if useTransport:
            jacklib.transport_stop(self.fJackClient)

        if self.fFreewheel:
            jacklib.set_freewheel(self.fJackClient, 0)
            sleep(1)

        self.fProcess.terminate()
        #self.fProcess.waitForFinished(5000)

        if useTransport:
            self.fTimer.stop()

        self.ui.group_render.setEnabled(True)
        self.ui.group_time.setEnabled(True)
        self.ui.group_encoding.setEnabled(True)
        self.ui.b_render.setVisible(True)
        self.ui.b_stop.setVisible(False)
        self.ui.b_close.setEnabled(True)

        self.ui.progressBar.setFormat("")
        self.ui.progressBar.setMinimum(0)
        self.ui.progressBar.setMaximum(1)
        self.ui.progressBar.setValue(0)
        self.ui.progressBar.update()

        # Restore buffer size
        newBufferSize = int(jacklib.get_buffer_size(self.fJackClient))

        if newBufferSize != self.fBufferSize:
            jacklib.set_buffer_size(self.fJackClient, newBufferSize)

    @pyqtSlot()
    def slot_getAndSetPath(self):
        getAndSetPath(self, self.ui.le_folder.text(), self.ui.le_folder)

    @pyqtSlot()
    def slot_setStartNow(self):
        time = int(
            jacklib.get_current_transport_frame(self.fJackClient) /
            self.fSampleRate)
        secs = time % 60
        mins = int(time / 60) % 60
        hrs = int(time / 3600) % 60
        self.ui.te_start.setTime(QTime(hrs, mins, secs))

    @pyqtSlot()
    def slot_setEndNow(self):
        time = int(
            jacklib.get_current_transport_frame(self.fJackClient) /
            self.fSampleRate)
        secs = time % 60
        mins = int(time / 60) % 60
        hrs = int(time / 3600) % 60
        self.ui.te_end.setTime(QTime(hrs, mins, secs))

    @pyqtSlot(QTime)
    def slot_updateStartTime(self, time):
        if time >= self.ui.te_end.time():
            self.ui.te_end.setTime(time)
            renderEnabled = False
        else:
            renderEnabled = True

        if self.ui.group_time.isChecked():
            self.ui.b_render.setEnabled(renderEnabled)

    @pyqtSlot(QTime)
    def slot_updateEndTime(self, time):
        if time <= self.ui.te_start.time():
            self.ui.te_start.setTime(time)
            renderEnabled = False
        else:
            renderEnabled = True

        if self.ui.group_time.isChecked():
            self.ui.b_render.setEnabled(renderEnabled)

    @pyqtSlot(bool)
    def slot_transportChecked(self, yesNo):
        if yesNo:
            renderEnabled = bool(
                self.ui.te_end.time() > self.ui.te_start.time())
        else:
            renderEnabled = True

        self.ui.b_render.setEnabled(renderEnabled)

    @pyqtSlot()
    def slot_updateProgressbar(self):
        time = int(jacklib.get_current_transport_frame(
            self.fJackClient)) / self.fSampleRate
        self.ui.progressBar.setValue(time)

        if time > self.fMaxTime or (self.fLastTime > time
                                    and not self.fFreewheel):
            self.slot_renderStop()

        self.fLastTime = time

    def saveSettings(self):
        settings = QSettings("Cadence", "Cadence-Render")

        if self.ui.rb_mono.isChecked():
            channels = 1
        elif self.ui.rb_stereo.isChecked():
            channels = 2
        else:
            channels = self.ui.sb_channels.value()

        settings.setValue("Geometry", self.saveGeometry())
        settings.setValue("OutputFolder", self.ui.le_folder.text())
        settings.setValue("FilenamePrefix", self.ui.le_prefix.text())
        settings.setValue("EncodingFormat", self.ui.cb_format.currentText())
        settings.setValue("EncodingDepth", self.ui.cb_depth.currentText())
        settings.setValue("EncodingChannels", channels)
        settings.setValue("UseTransport", self.ui.group_time.isChecked())
        settings.setValue("StartTime", self.ui.te_start.time())
        settings.setValue("EndTime", self.ui.te_end.time())

    def loadSettings(self):
        settings = QSettings("Cadence", "Cadence-Render")

        self.restoreGeometry(settings.value("Geometry", ""))

        outputFolder = settings.value("OutputFolder", HOME)

        if os.path.exists(outputFolder):
            self.ui.le_folder.setText(outputFolder)

        self.ui.le_prefix.setText(
            settings.value("FilenamePrefix", "jack_capture_"))

        encFormat = settings.value("EncodingFormat", "Wav", type=str)

        for i in range(self.ui.cb_format.count()):
            if self.ui.cb_format.itemText(i) == encFormat:
                self.ui.cb_format.setCurrentIndex(i)
                break

        encDepth = settings.value("EncodingDepth", "Float", type=str)

        for i in range(self.ui.cb_depth.count()):
            if self.ui.cb_depth.itemText(i) == encDepth:
                self.ui.cb_depth.setCurrentIndex(i)
                break

        encChannels = settings.value("EncodingChannels", 2, type=int)

        if encChannels == 1:
            self.ui.rb_mono.setChecked(True)
        elif encChannels == 2:
            self.ui.rb_stereo.setChecked(True)
        else:
            self.ui.rb_outro.setChecked(True)
            self.ui.sb_channels.setValue(encChannels)

        self.ui.group_time.setChecked(
            settings.value("UseTransport", False, type=bool))
        self.ui.te_start.setTime(
            settings.value("StartTime", self.ui.te_start.time(), type=QTime))
        self.ui.te_end.setTime(
            settings.value("EndTime", self.ui.te_end.time(), type=QTime))

    def closeEvent(self, event):
        self.saveSettings()

        if self.fJackClient:
            jacklib.client_close(self.fJackClient)

        QDialog.closeEvent(self, event)

    def done(self, r):
        QDialog.done(self, r)
        self.close()
コード例 #20
0
class Window(QWidget):
 
    def __init__(self):

        QWidget.__init__(self)
        self.rawstr = r"""(?:^.*Track .*?\d*\D*)(\d{1,})(?:\D*of.*?)(\d{1,})(?:.*?MB written.*$)"""
        self.compile_obj = re.compile(self.rawstr, re.MULTILINE)
        
        self.textBrowser = QTextBrowser(self)
        self.lineEdit = QLineEdit(self)
        self.startButton = QPushButton(self.tr("Start"), self)
        self.stopButton = QPushButton(self.tr("Stop"), self)
        self.stopButton.setEnabled(False)
        
        self.list1 = QStringList()
        self.connect(self.lineEdit, SIGNAL("returnPressed()"), self.startCommand)
        self.connect(self.startButton, SIGNAL("clicked()"), self.startCommand)
        self.connect(self.stopButton, SIGNAL("clicked()"), self.stopCommand)

        layout = QGridLayout(self)
        layout.setSpacing(8)
        layout.addWidget(self.textBrowser, 0, 0)
        layout.addWidget(self.lineEdit, 1, 0)
        layout.addWidget(self.startButton, 1, 1)
        layout.addWidget(self.stopButton, 1, 2)

 
        self.process = QProcess()
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.readOutput)
        self.connect(self.process, SIGNAL("readyReadStandardError()"), self.readErrors)
        self.connect(self.process, SIGNAL("finished(int)"), self.resetButtons)

    def startCommand(self):
        a=self.lineEdit.text().split(" ")
        self.process.start(a.first(), a.mid(1))

        self.startButton.setEnabled(False)
        self.stopButton.setEnabled(True)
        self.textBrowser.clear()

         
        if  self.process.exitCode():
            self.textBrowser.setText(
                QString("*** Failed to run %1 ***").arg(self.lineEdit.text())
                )
            self.resetButtons()
            return

    def stopCommand(self):
        self.resetButtons()
        self.process.terminate()
        QTimer.singleShot(5000, self.process, SLOT("kill()"))


    def readOutput(self):
        a= self.process.readAllStandardOutput().data()
        match_obj = self.compile_obj.search(a)
        
        if match_obj:
            all_groups = match_obj.groups()
            group_1 = float(match_obj.group(1))
            group_2 = float(match_obj.group(2))
            g=int(group_1*100.0/group_2)
            if group_1:
                self.textBrowser.append(QString(str(g)))

    def readErrors(self):
        a= self.process.readAllStandardError().data()
        self.textBrowser.append("error: " + QString(a))
        
    def resetButtons(self,  i):
        self.startButton.setEnabled(True)
        self.stopButton.setEnabled(False)
コード例 #21
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)
コード例 #22
0
ファイル: render.py プロジェクト: nick87720z/Cadence
class RenderW(QDialog):
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.ui = ui_render.Ui_RenderW()
        self.ui.setupUi(self)

        self.fFreewheel = False
        self.fLastTime  = -1
        self.fMaxTime   = 180

        self.fTimer   = QTimer(self)
        self.fProcess = QProcess(self)

        # -------------------------------------------------------------
        # Get JACK client and base information

        global gJackClient

        if gJackClient:
            self.fJackClient = gJackClient
        else:
            self.fJackClient = jacklib.client_open("Render-Dialog", jacklib.JackNoStartServer, None)

        self.fBufferSize = int(jacklib.get_buffer_size(self.fJackClient))
        self.fSampleRate = int(jacklib.get_sample_rate(self.fJackClient))

        for i in range(self.ui.cb_buffer_size.count()):
            if int(self.ui.cb_buffer_size.itemText(i)) == self.fBufferSize:
                self.ui.cb_buffer_size.setCurrentIndex(i)
                break
        else:
            self.ui.cb_buffer_size.addItem(str(self.fBufferSize))
            self.ui.cb_buffer_size.setCurrentIndex(self.ui.cb_buffer_size.count() - 1)

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

        # Get List of formats
        self.fProcess.start(gJackCapturePath, ["-pf"])
        self.fProcess.waitForFinished()

        formats     = str(self.fProcess.readAllStandardOutput(), encoding="utf-8").split(" ")
        formatsList = []

        for i in range(len(formats) - 1):
            iFormat = formats[i].strip()
            if iFormat:
                formatsList.append(iFormat)

        formatsList.sort()

        # Put all formats in combo-box, select 'wav' option
        for i in range(len(formatsList)):
            self.ui.cb_format.addItem(formatsList[i])
            if formatsList[i] == "wav":
                self.ui.cb_format.setCurrentIndex(i)

        self.ui.cb_depth.setCurrentIndex(4) #Float
        self.ui.rb_stereo.setChecked(True)

        self.ui.te_end.setTime(QTime(0, 3, 0))
        self.ui.progressBar.setFormat("")
        self.ui.progressBar.setMinimum(0)
        self.ui.progressBar.setMaximum(1)
        self.ui.progressBar.setValue(0)

        self.ui.b_render.setIcon(getIcon("media-record"))
        self.ui.b_stop.setIcon(getIcon("media-playback-stop"))
        self.ui.b_close.setIcon(getIcon("window-close"))
        self.ui.b_open.setIcon(getIcon("document-open"))
        self.ui.b_stop.setVisible(False)
        self.ui.le_folder.setText(HOME)

        # -------------------------------------------------------------
        # Set-up connections

        self.connect(self.ui.b_render, SIGNAL("clicked()"), SLOT("slot_renderStart()"))
        self.connect(self.ui.b_stop, SIGNAL("clicked()"), SLOT("slot_renderStop()"))
        self.connect(self.ui.b_open, SIGNAL("clicked()"), SLOT("slot_getAndSetPath()"))
        self.connect(self.ui.b_now_start, SIGNAL("clicked()"), SLOT("slot_setStartNow()"))
        self.connect(self.ui.b_now_end, SIGNAL("clicked()"), SLOT("slot_setEndNow()"))
        self.connect(self.ui.te_start, SIGNAL("timeChanged(const QTime)"), SLOT("slot_updateStartTime(const QTime)"))
        self.connect(self.ui.te_end, SIGNAL("timeChanged(const QTime)"), SLOT("slot_updateEndTime(const QTime)"))
        self.connect(self.ui.group_time, SIGNAL("clicked(bool)"), SLOT("slot_transportChecked(bool)"))
        self.connect(self.fTimer, SIGNAL("timeout()"), SLOT("slot_updateProgressbar()"))

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

        self.loadSettings()

    @pyqtSlot()
    def slot_renderStart(self):
        if not os.path.exists(self.ui.le_folder.text()):
            QMessageBox.warning(self, self.tr("Warning"), self.tr("The selected directory does not exist. Please choose a valid one."))
            return

        timeStart = self.ui.te_start.time()
        timeEnd   = self.ui.te_end.time()
        minTime   = (timeStart.hour() * 3600) + (timeStart.minute() * 60) + (timeStart.second())
        maxTime   = (timeEnd.hour() * 3600) + (timeEnd.minute() * 60) + (timeEnd.second())

        newBufferSize = int(self.ui.cb_buffer_size.currentText())
        useTransport  = self.ui.group_time.isChecked()

        self.fFreewheel = bool(self.ui.cb_render_mode.currentIndex() == 1)
        self.fLastTime  = -1
        self.fMaxTime   = maxTime

        if self.fFreewheel:
            self.fTimer.setInterval(100)
        else:
            self.fTimer.setInterval(500)

        self.ui.group_render.setEnabled(False)
        self.ui.group_time.setEnabled(False)
        self.ui.group_encoding.setEnabled(False)
        self.ui.b_render.setVisible(False)
        self.ui.b_stop.setVisible(True)
        self.ui.b_close.setEnabled(False)

        if useTransport:
            self.ui.progressBar.setFormat("%p%")
            self.ui.progressBar.setMinimum(minTime)
            self.ui.progressBar.setMaximum(maxTime)
            self.ui.progressBar.setValue(minTime)
        else:
            self.ui.progressBar.setFormat("")
            self.ui.progressBar.setMinimum(0)
            self.ui.progressBar.setMaximum(0)
            self.ui.progressBar.setValue(0)

        self.ui.progressBar.update()

        arguments = []

        # Filename prefix
        arguments.append("-fp")
        arguments.append(self.ui.le_prefix.text())

        # Format
        arguments.append("-f")
        arguments.append(self.ui.cb_format.currentText())

        # Bit depth
        arguments.append("-b")
        arguments.append(self.ui.cb_depth.currentText())

        # Channels
        arguments.append("-c")
        if self.ui.rb_mono.isChecked():
            arguments.append("1")
        elif self.ui.rb_stereo.isChecked():
            arguments.append("2")
        else:
            arguments.append(str(self.ui.sb_channels.value()))

        # Controlled only by freewheel
        if self.fFreewheel:
            arguments.append("-jf")

        # Controlled by transport
        elif useTransport:
            arguments.append("-jt")

        # Silent mode
        arguments.append("-dc")
        arguments.append("-s")

        # Change current directory
        os.chdir(self.ui.le_folder.text())

        if newBufferSize != int(jacklib.get_buffer_size(self.fJackClient)):
            print("NOTICE: buffer size changed before render")
            jacklib.set_buffer_size(self.fJackClient, newBufferSize)

        if useTransport:
            if jacklib.transport_query(self.fJackClient, None) > jacklib.JackTransportStopped: # rolling or starting
                jacklib.transport_stop(self.fJackClient)

            jacklib.transport_locate(self.fJackClient, minTime * self.fSampleRate)

        self.fProcess.start(gJackCapturePath, arguments)
        self.fProcess.waitForStarted()

        if self.fFreewheel:
            print("NOTICE: rendering in freewheel mode")
            sleep(1)
            jacklib.set_freewheel(self.fJackClient, 1)

        if useTransport:
            self.fTimer.start()
            jacklib.transport_start(self.fJackClient)

    @pyqtSlot()
    def slot_renderStop(self):
        useTransport = self.ui.group_time.isChecked()

        if useTransport:
            jacklib.transport_stop(self.fJackClient)

        if self.fFreewheel:
            jacklib.set_freewheel(self.fJackClient, 0)
            sleep(1)

        self.fProcess.terminate()
        #self.fProcess.waitForFinished(5000)

        if useTransport:
            self.fTimer.stop()

        self.ui.group_render.setEnabled(True)
        self.ui.group_time.setEnabled(True)
        self.ui.group_encoding.setEnabled(True)
        self.ui.b_render.setVisible(True)
        self.ui.b_stop.setVisible(False)
        self.ui.b_close.setEnabled(True)

        self.ui.progressBar.setFormat("")
        self.ui.progressBar.setMinimum(0)
        self.ui.progressBar.setMaximum(1)
        self.ui.progressBar.setValue(0)
        self.ui.progressBar.update()

        # Restore buffer size
        newBufferSize = int(jacklib.get_buffer_size(self.fJackClient))

        if newBufferSize != self.fBufferSize:
            jacklib.set_buffer_size(self.fJackClient, newBufferSize)

    @pyqtSlot()
    def slot_getAndSetPath(self):
        getAndSetPath(self, self.ui.le_folder.text(), self.ui.le_folder)

    @pyqtSlot()
    def slot_setStartNow(self):
        time = int(jacklib.get_current_transport_frame(self.fJackClient) / self.fSampleRate)
        secs = time % 60
        mins = int(time / 60) % 60
        hrs  = int(time / 3600) % 60
        self.ui.te_start.setTime(QTime(hrs, mins, secs))

    @pyqtSlot()
    def slot_setEndNow(self):
        time = int(jacklib.get_current_transport_frame(self.fJackClient) / self.fSampleRate)
        secs = time % 60
        mins = int(time / 60) % 60
        hrs  = int(time / 3600) % 60
        self.ui.te_end.setTime(QTime(hrs, mins, secs))

    @pyqtSlot(QTime)
    def slot_updateStartTime(self, time):
        if time >= self.ui.te_end.time():
            self.ui.te_end.setTime(time)
            renderEnabled = False
        else:
            renderEnabled = True

        if self.ui.group_time.isChecked():
            self.ui.b_render.setEnabled(renderEnabled)

    @pyqtSlot(QTime)
    def slot_updateEndTime(self, time):
        if time <= self.ui.te_start.time():
            self.ui.te_start.setTime(time)
            renderEnabled = False
        else:
            renderEnabled = True

        if self.ui.group_time.isChecked():
            self.ui.b_render.setEnabled(renderEnabled)

    @pyqtSlot(bool)
    def slot_transportChecked(self, yesNo):
        if yesNo:
            renderEnabled = bool(self.ui.te_end.time() > self.ui.te_start.time())
        else:
            renderEnabled = True

        self.ui.b_render.setEnabled(renderEnabled)

    @pyqtSlot()
    def slot_updateProgressbar(self):
        time = int(jacklib.get_current_transport_frame(self.fJackClient)) / self.fSampleRate
        self.ui.progressBar.setValue(time)

        if time > self.fMaxTime or (self.fLastTime > time and not self.fFreewheel):
            self.slot_renderStop()

        self.fLastTime = time

    def saveSettings(self):
        settings = QSettings("Cadence", "Cadence-Render")

        if self.ui.rb_mono.isChecked():
            channels = 1
        elif self.ui.rb_stereo.isChecked():
            channels = 2
        else:
            channels = self.ui.sb_channels.value()

        settings.setValue("Geometry", self.saveGeometry())
        settings.setValue("OutputFolder", self.ui.le_folder.text())
        settings.setValue("FilenamePrefix", self.ui.le_prefix.text())
        settings.setValue("EncodingFormat", self.ui.cb_format.currentText())
        settings.setValue("EncodingDepth", self.ui.cb_depth.currentText())
        settings.setValue("EncodingChannels", channels)
        settings.setValue("UseTransport", self.ui.group_time.isChecked())
        settings.setValue("StartTime", self.ui.te_start.time())
        settings.setValue("EndTime", self.ui.te_end.time())

    def loadSettings(self):
        settings = QSettings("Cadence", "Cadence-Render")

        self.restoreGeometry(settings.value("Geometry", ""))

        outputFolder = settings.value("OutputFolder", HOME)

        if os.path.exists(outputFolder):
            self.ui.le_folder.setText(outputFolder)

        self.ui.le_prefix.setText(settings.value("FilenamePrefix", "jack_capture_"))

        encFormat = settings.value("EncodingFormat", "Wav", type=str)

        for i in range(self.ui.cb_format.count()):
            if self.ui.cb_format.itemText(i) == encFormat:
                self.ui.cb_format.setCurrentIndex(i)
                break

        encDepth = settings.value("EncodingDepth", "Float", type=str)

        for i in range(self.ui.cb_depth.count()):
            if self.ui.cb_depth.itemText(i) == encDepth:
                self.ui.cb_depth.setCurrentIndex(i)
                break

        encChannels = settings.value("EncodingChannels", 2, type=int)

        if encChannels == 1:
            self.ui.rb_mono.setChecked(True)
        elif encChannels == 2:
            self.ui.rb_stereo.setChecked(True)
        else:
            self.ui.rb_outro.setChecked(True)
            self.ui.sb_channels.setValue(encChannels)

        self.ui.group_time.setChecked(settings.value("UseTransport", False, type=bool))
        self.ui.te_start.setTime(settings.value("StartTime", self.ui.te_start.time(), type=QTime))
        self.ui.te_end.setTime(settings.value("EndTime", self.ui.te_end.time(), type=QTime))

    def closeEvent(self, event):
        self.saveSettings()

        if self.fJackClient:
            jacklib.client_close(self.fJackClient)

        QDialog.closeEvent(self, event)

    def done(self, r):
        QDialog.done(self, r)
        self.close()
コード例 #23
0
ファイル: burning.py プロジェクト: homoludens/Freedom-Toaster
class Window(QWidget):
    __pyqtSignals__ = ("burningProgress(int)")
    __pyqtSignals__ = ("burningFinished()")
    __pyqtSignals__ = ("burningStartingIn(int)")
    __pyqtSignals__ = ("burningError(int)")
    
    def __init__(self):
        QWidget.__init__(self)
        self.rawstr3 = r"""(?:^Current:\s)(.*)"""
        self.rawstr2 = r"""(?:^.*?)(\d)(?:\sseconds\.$)"""
        self.rawstr = r"""(?:^.*Track .*?\d*\D*)(\d{1,})(?:\D*of.*?)(\d{1,})(?:.*?MB written.*$)"""
        self.compile_obj = re.compile(self.rawstr, re.MULTILINE)
        self.compile_obj_2 = re.compile(self.rawstr2, re.MULTILINE)
        self.compile_obj_3 = re.compile(self.rawstr3, re.MULTILINE)
        self.process = QProcess()
        self.connect(self.process, SIGNAL("readyReadStandardOutput()"), self.readOutput)
        self.connect(self.process, SIGNAL("readyReadStandardError()"), self.readErrors)
        self.connect(self.process, SIGNAL("finished(int)"), self.resetButtons)
        self.connect(self, SIGNAL("burningProgress(int)"), self.readProgress)
        
        self.noError=True
    
    def blankCommand(self):
        print "blankCDRW"
        b=QString("cdrecord -v dev=1000,0,0 --blank=fast") 
        a=b.split(" ")
        self.process.start(a.first(), a.mid(1))

         
        if  self.process.exitCode():
            print "exitCode"
            self.resetButtons()
            return
    
    
    
    def startCommand(self, isofile):
        print "startCommand"
        b=QString("cdrecord -v -pad speed=8 dev=/dev/cdrom "+isofile) 
        a=b.split(" ")
        self.process.start(a.first(), a.mid(1))

         
        if  self.process.exitCode():
            print "exitCode"
            self.resetButtons()
            return

    def stopCommand(self, i):
        self.resetButtons(i)
        self.process.terminate()
        QTimer.singleShot(5000, self.process, SLOT("kill()"))


    def readOutput(self):
        a= self.process.readAllStandardOutput().data()
        match_obj = self.compile_obj.search(a)
        match_obj_2 = self.compile_obj_2.search(a)
        match_obj_3 = self.compile_obj_3.search(a)
        print a
        if match_obj:
            all_groups = match_obj.groups()
            group_1 = float(match_obj.group(1))
            group_2 = float(match_obj.group(2))
            g=int(group_1*100.0/group_2)
            if group_1:
                self.emit(SIGNAL("burningProgress(int)"), g)
        
        if match_obj_2:
            group_1 = int(match_obj_2.group(1))
            print "group_1: "+str(group_1)
            if group_1: 
                self.emit(SIGNAL("burningStartingIn(int)"), group_1)
                
        if match_obj_3:
            group_1 = match_obj_3.group(1)
            if group_1 == "none":
                print "NO MEDIA"
                self.stopCommand(334)
            
        if a=="Re-load disk and hit \<CR\>":
            print "Non writable disc"
            self.stopCommand()

    def readProgress(self, g):
        print g


    def readErrors(self):
        a= self.process.readAllStandardError().data()
        print "ERORR: "+a
        if a.startswith("cdrecord: Try to load media by hand"):
            print "ERROR: Non writable disc"
            self.stopCommand(333)
        
    def resetButtons(self,  i):
        print "resetButtons"
        print i
        if i==0:
            if self.noError:
                self.emit(SIGNAL("burningFinished()"))
        if i==333:
            self.noError=False
            self.emit(SIGNAL("burningError(int)"), i)
        if i==334:
            self.noError=False
            self.emit(SIGNAL("burningError(int)"), i)
        if i==335:
            self.noError=False
            self.emit(SIGNAL("burningCanceled(int)"), i)
コード例 #24
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)
コード例 #25
0
        if doRunNow:
            if firstStart:
                firstStart = False
                print("cadence-aloop-daemon started, using %s and %i channels" % ("zita-a2j/j2a" if useZita else "alsa_in/out", channels))

            run_alsa_bridge()
            doRunNow = False

        elif isKernelGood and reactivateCounter >= 0:
            if reactivateCounter == 5:
                reactivateCounter = -1
                doRunNow = True
            else:
                reactivateCounter += 1

        sleep(1)

    # Close JACK client
    jacklib.deactivate(client)
    jacklib.client_close(client)

    if os.path.exists(checkFile):
        os.remove(checkFile)

    if procIn.state() != QProcess.NotRunning:
        procIn.terminate()
        procIn.waitForFinished(1000)
    if procOut.state() != QProcess.NotRunning:
        procOut.terminate()
        procOut.waitForFinished(1000)
コード例 #26
0
class ExternalProcessWidget(QDockWidget):

    def __init__(self, command, working_dir=None, parent=None, keep_open=False):
        QDockWidget.__init__(self, parent=parent)
        # setup user interface
        ui_file = os.path.join(rp.get_path('roslab_ide'), 'resource', 'widgets', 'ExternalProcessWidget.ui')
        self.ui = loadUi(ui_file, self)
        # set command as window title
        self.setWindowTitle(command)
        # set working dir
        if not working_dir:
            working_dir = os.curdir

        # vars
        self._command = command
        self._process_finished = False

        if keep_open:
            args = [
                '-hold',
                '-into', str(self.ui.placeholderWidget.winId()),
                '-e', command
            ]
        else:
            args = [
                '-into', str(self.ui.placeholderWidget.winId()),
                '-e', command
            ]

        # print info
        print('starting "{}" in external terminal...'.format(self._command))
        if keep_open:
            print('(terminal will stay open after process has finished. you must close it yourself!)')
        else:
            print('(terminal will close after process has finished.)')

        self.process = QProcess()
        self.process.setWorkingDirectory(working_dir)
        self.process.start('xterm', args)

        # signals
        self.process.finished.connect(self.finished_process)

    def __del__(self):
        self.terminate_process()

    def save_settings(self):
        pass

    def load_settings(self):
        pass

    def terminate_process(self):
        print('terminating "{}" in external terminal...'.format(self._command))
        self.process.terminate()
        self.process.waitForFinished()
        del self.process
        self._process_finished = True
        self.process = None
        # print info
        print('...done!')

    def process_has_finished(self):
        return self._process_finished

    @pyqtSlot()
    def finished_process(self):
        print('...finished "{}" in external terminal.'.format(self._command))
        self._process_finished = True
        del self.process
        self.process = None
        self.close()

    def closeEvent(self, event):
        if not self._process_finished:
            self.terminate_process()
        event.accept()