Exemple #1
0
class ThreadManagerDialog(QDialog):
    def __init__( self, iface, title="Worker Thread"):
        QDialog.__init__( self, iface)#.mainWindow() )
        self.iface = iface
        self.setWindowTitle(title)
        self.setLayout(QVBoxLayout())
        self.primaryLabel = QLabel(self)
        self.layout().addWidget(self.primaryLabel)
        self.primaryBar = QProgressBar(self)
        self.layout().addWidget(self.primaryBar)
        self.secondaryLabel = QLabel(self)
        self.layout().addWidget(self.secondaryLabel)
        self.secondaryBar = QProgressBar(self)
        self.layout().addWidget(self.secondaryBar)
        self.closeButton = QPushButton("Close")
        self.closeButton.setEnabled(False)
        self.layout().addWidget(self.closeButton)
        self.closeButton.clicked.connect(self.reject)
    def run(self):
        self.runThread()
        self.exec_()
    def runThread( self):
        QObject.connect( self.workerThread, SIGNAL( "jobFinished( PyQt_PyObject )" ), self.jobFinishedFromThread )
        QObject.connect( self.workerThread, SIGNAL( "primaryValue( PyQt_PyObject )" ), self.primaryValueFromThread )
        QObject.connect( self.workerThread, SIGNAL( "primaryRange( PyQt_PyObject )" ), self.primaryRangeFromThread )
        QObject.connect( self.workerThread, SIGNAL( "primaryText( PyQt_PyObject )" ), self.primaryTextFromThread )
        QObject.connect( self.workerThread, SIGNAL( "secondaryValue( PyQt_PyObject )" ), self.secondaryValueFromThread )
        QObject.connect( self.workerThread, SIGNAL( "secondaryRange( PyQt_PyObject )" ), self.secondaryRangeFromThread )
        QObject.connect( self.workerThread, SIGNAL( "secondaryText( PyQt_PyObject )" ), self.secondaryTextFromThread )
        self.workerThread.start()
    def cancelThread( self ):
        self.workerThread.stop()
    def jobFinishedFromThread( self, success ):
        self.workerThread.stop()
        self.primaryBar.setValue(self.primaryBar.maximum())
        self.secondaryBar.setValue(self.secondaryBar.maximum())
        self.emit( SIGNAL( "jobFinished( PyQt_PyObject )" ), success )
        self.closeButton.setEnabled( True )
    def primaryValueFromThread( self, value ):
        self.primaryBar.setValue(value)
    def primaryRangeFromThread( self, range_vals ):
        self.primaryBar.setRange( range_vals[ 0 ], range_vals[ 1 ] )
    def primaryTextFromThread( self, value ):
        self.primaryLabel.setText(value)
    def secondaryValueFromThread( self, value ):
        self.secondaryBar.setValue(value)
    def secondaryRangeFromThread( self, range_vals ):
        self.secondaryBar.setRange( range_vals[ 0 ], range_vals[ 1 ] )
    def secondaryTextFromThread( self, value ):
        self.secondaryLabel.setText(value)
class _TransferWidget(QFrame):
    cancel = pyqtSignal()
    cancelBeforeTransfer = pyqtSignal(int) # transfer ID
    retry = pyqtSignal(object, object, int) # filesOrData, peerID, transfer ID
    
    def __init__(self, parent, logger, filesOrData, name, targetDir, numFiles, totalSize, peerID, transferID, down):
        super(_TransferWidget, self).__init__(parent)
        
        self.logger = logger
        self._filesOrData = filesOrData
        self._targetDir = targetDir
        self._numFiles = numFiles
        self._totalSize = totalSize
        self._targetFile = None
        self._peerID = peerID
        self._transferID = transferID
        self._transferring = True
        self._down = down
        self._success = False
        self._connectedToThread = False
        self._currentFile = None
        
        self._initLayout()
        
        if type(filesOrData) is list and len(filesOrData) is 1:
            self._setCurrentFile(filesOrData[0])
        elif name:
            f = NamedTemporaryFile(suffix=name, delete=True)
            f.flush()
            self._setCurrentFile(f.name, name)
            f.close()
        else:
            self._setCurrentFile(None)
        self.reset()
        
    def _initLayout(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(5, 5, 5, 5)
        layout.setSpacing(0)
        
        nameLayout = QHBoxLayout()
        nameLayout.setContentsMargins(0, 0, 0, 0)
        
        self._fileIconLabel = QLabel(self)
        nameLayout.addWidget(self._fileIconLabel, 0, Qt.AlignLeft)
        
        self._nameLabel = QLabel(self)
        nameLayout.addSpacing(5)
        nameLayout.addWidget(self._nameLabel, 1, Qt.AlignLeft)
        
        layout.addLayout(nameLayout)
        
        progressWidget = QWidget(self)
        progressLayout = QHBoxLayout(progressWidget)
        progressLayout.setSpacing(5)
        progressLayout.setContentsMargins(0, 0, 0, 0)
        
        iconLabel = QLabel(progressWidget)
        if self._down:
            picFile = get_settings().get_resource("images", "down.png")
        else:
            picFile = get_settings().get_resource("images", "up.png")
        iconLabel.setPixmap(QPixmap(picFile))
        iconLabel.setFixedSize(15,15)
        progressLayout.addWidget(iconLabel, 0, Qt.AlignBottom)
        
        self._progress = QProgressBar(progressWidget)
        self._progress.setMinimum(0)
        self._progress.setMaximum(100)
        if getPlatform() == PLATFORM_MAC:
            self._progress.setAttribute(Qt.WA_MacMiniSize)
            self._progress.setMaximumHeight(16)
        progressLayout.addWidget(self._progress, 1)
        
        self._button = QPushButton(progressWidget)
        self._button.clicked.connect(self._buttonClicked)
        progressLayout.addSpacing(5)
        progressLayout.addWidget(self._button, 0, Qt.AlignCenter)
        
        layout.addWidget(progressWidget, 0, Qt.AlignBottom)
        
        self._statusLabel = QLabel(self)
        if getPlatform() == PLATFORM_MAC:
            self._statusLabel.setAttribute(Qt.WA_MacSmallSize)
        layout.addWidget(self._statusLabel)
        
        self.setObjectName(u"__transfer_widget")
        self.setFrameShape(QFrame.StyledPanel)
        self.setStyleSheet("QFrame#__transfer_widget{border-width: 1px; border-top-style: none; border-right-style: none; border-bottom-style: solid; border-left-style: none; border-color:palette(mid)}");
            
        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
        
    def reset(self):
        self._transferring = True
        self._statusLabel.setText(u"Waiting for data..." if self._down else u"Waiting for peer...")
        self._checkButtonFunction()
        self._progress.setMaximum(0)
        
    def isFinished(self):
        return not self._transferring
    
    def isSuccessful(self):
        return self._success
    
    def getFilePath(self):
        if self._numFiles is 1:
            return self._currentFile
        
    def _setFileIcon(self, curPath):
        if os.path.exists(curPath):
            fileInfo = QFileInfo(curPath)
            iconProvider = QFileIconProvider()
            icon = iconProvider.icon(fileInfo)
            self._fileIconLabel.setPixmap(icon.pixmap(16,16))
        
    def _setCurrentFile(self, path, dispName=None):
        if get_peers() is not None:
            peerName = get_peers().getDisplayedPeerName(self._peerID)
        else:
            peerName = u"<unknown peer>"
            
        if not path:
            if self._down:
                text = u"%d %s (total %s) \u2190 %s"
            else:
                text = u"%d %s (total %s) \u2192 %s"
            text = text % (self._numFiles, u"file" if self._numFiles is 1 else "files", formatSize(self._totalSize), peerName)
        else:
            if self._down:
                text = u"%s (%stotal %s) \u2190 %s"
            else:
                text = u"%s (%stotal %s) \u2192 %s"
            if dispName is None:
                dispName = os.path.basename(path)
            
            numFilesS = u"" if self._numFiles is 1 else u"%d files, " % self._numFiles
            text = text % (dispName, numFilesS, formatSize(self._totalSize), peerName)
            self._setFileIcon(path)
            
        self._currentFile = path
        self._nameLabel.setText(text)
        
    def _setIcon(self, baseName):
        if baseName is None:
            self._button.setStyleSheet("""
                QPushButton {min-width: 15px;
                             max-width: 15px;
                             min-height: 15px;
                             max-height: 15px;
                             margin: 0px;
                             padding: 0px;
                             border:none;
                }
            """)
        else:
            defPath = get_settings().get_resource("images", "%s32.png" % baseName)
            pressPath = get_settings().get_resource("images", "%s32p.png" % baseName)
            self._button.setStyleSheet("""
                QPushButton {min-width: 15px;
                             max-width: 15px;
                             min-height: 15px;
                             max-height: 15px;
                             margin: 0px;
                             padding: 0px;
                             border:none;
                             border-image: url(%s);
                }
                QPushButton:pressed {
                             border-image: url(%s);
                }
            """ % (defPath, pressPath)
            )
        
    def _checkButtonFunction(self):
        if self._transferring:
            self._setIcon("cancel")
        elif self._down:
            if self._success:
                self._setIcon("reveal")
            else:
                self._setIcon(None)
        else:
            if self._success:
                self._setIcon("reveal")
            else:
                self._setIcon("retry")
    
    def _reveal(self):
        filePath = self.getFilePath()
        if filePath:
            revealFile(filePath, self.logger)
        elif self._down:
            openFile(self._targetDir, self.logger)
        elif self._currentFile and os.path.exists(self._currentFile):
            revealFile(self._currentFile, self.logger)
    
    def _buttonClicked(self):
        if self._transferring:
            if self._connectedToThread:
                self.cancel.emit()
            else:
                self.cancelBeforeTransfer.emit(self._transferID)
        elif self._down:
            if self._success:
                self._reveal()
        else:
            if self._success:
                self._reveal()
            else:
                self.retry.emit(self._filesOrData, self._peerID, self._transferID)
                
    @loggingSlot(object, int)
    def nextFile(self, nameOrPath, _size):
        self._setCurrentFile(nameOrPath)
        
    def connectDataThread(self, dataThread):
        if not dataThread.isRunning():
            self.transferError(dataThread, u"Transfer didn't start.")
            return
        self._connectedToThread = True
        dataThread.progressChanged.connect(self.progressChanged)
        dataThread.errorOnTransfer.connect(self.transferError)
        dataThread.successfullyTransferred.connect(self.successfullyTransferred)
        dataThread.transferCanceled.connect(self.transferCanceled)
        dataThread.nextFile.connect(self.nextFile)
        self.cancel.connect(dataThread.cancelTransfer)

    def disconnectDataThread(self, dataThread):
        if self._connectedToThread:
            self._connectedToThread = False   
            dataThread.progressChanged.disconnect(self.progressChanged)
            dataThread.errorOnTransfer.disconnect(self.transferError)
            dataThread.successfullyTransferred.disconnect(self.successfullyTransferred)
            dataThread.transferCanceled.disconnect(self.transferCanceled)
            dataThread.nextFile.disconnect(self.nextFile)
            self.cancel.disconnect(dataThread.cancelTransfer)
    
    @loggingSlot(int, int)
    def progressChanged(self, newVal, maxVal):
        if newVal is 0:
            self._transferring = True
            self._progress.setMaximum(maxVal)
            self._statusLabel.setText(u"Receiving data" if self._down else u"Sending data")
        self._progress.setValue(newVal)
    
    @pyqtSlot(QThread)
    @loggingSlot(QThread, object)
    def successfullyTransferred(self, thread, _path=None):
        self._transferring = False
        self._success = True
        self._statusLabel.setText(u"Transfer finished successfully")
        self.disconnectDataThread(thread)
        self._checkButtonFunction()
    
    @loggingSlot(QThread, object)
    def transferError(self, thread, message=None):
        if not self._transferring:
            return
        self._transferring = False
        self._statusLabel.setText(u"Error transferring file (%s)" % message)
        self.disconnectDataThread(thread)
        self._checkButtonFunction()
        if self._progress.maximum() == 0:
            self._progress.setMaximum(100)
    
    @loggingSlot(QThread)
    def transferCanceled(self, thread):
        self._transferring = False
        self._statusLabel.setText(u"Transfer canceled")
        self.disconnectDataThread(thread)
        self._checkButtonFunction()
        
    def canceledBeforeTransfer(self, isTimeout):
        self._progress.setMaximum(100)
        self._transferring = False
        if isTimeout:
            self._statusLabel.setText(u"Transfer timed out")
        else:
            self._statusLabel.setText(u"Transfer canceled")
        self._checkButtonFunction()
class dialog_auto_prog(QDialog):

    #-----------------------------------------------------------------------
    # DEFINE THE INITIALIZATION FUNCTION.
    #-----------------------------------------------------------------------

    def __init__(self, time_strt, time_stop):

        # Inherit all attributes of an instance of "QDialog".

        super(dialog_auto_prog, self).__init__()

        # Make this a non-modal dialog (i.e., allow the user to still
        # interact with the main application window).

        self.setModal(False)

        # Set the title of this dialog window.

        self.setWindowTitle('Progress')

        # Give this widget a grid layout, "self.grd".

        self.grd = QGridLayout()

        self.grd.setContentsMargins(6, 6, 6, 6)

        self.setLayout(self.grd)

        # Initialize the progress bar and set its minimum, maximum, and
        # initial values.

        self.bar = QProgressBar()

        self.bar.setMinimum(calc_time_val(time_strt))
        self.bar.setMaximum(calc_time_val(time_stop))

        self.bar.setValue(self.bar.minimum())

        # Initialize the event button.

        self.btn_exit = event_PushButton(self, 'exit', 'Close')

        # Initialize the label.

        self.lab = QLabel('Note: closing this window will *NOT* ' +
                          'interrupt the automated analysis.')

        self.lab.setWordWrap(True)

        # Row by row, add the bar and buttons to the grid layout.

        self.grd.addWidget(self.bar, 0, 0, 1, 1)
        self.grd.addWidget(self.btn_exit, 0, 1, 1, 1)

        self.grd.addWidget(self.lab, 1, 0, 1, 2)

        # Display this dialog.

        self.show()

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR UPDATING THE PROGRESS BAR.
    #-----------------------------------------------------------------------

    def updt_bar(self, time):

        # Convert this functions argument (i.e., the timestamp of the
        # current spectrum) to Unix time.

        time_curr = calc_time_val(time)

        # If necessary, adjust the minimum or maximum of the progress
        # bar based on the new timestamp.

        if (time_curr < self.bar.minimum()):
            self.bar.setMinimum(time_curr)

        if (time_curr > self.bar.maximum()):
            self.bar.setMaximum(time_curr)

        # Update the value of the progress bar.

        self.bar.setValue(time_curr)

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESPONDING TO A USER-INITIATED EVENT.
    #-----------------------------------------------------------------------

    def user_event(self, event, fnc):

        # If the close button was pressed, close this dialog.

        if (fnc == 'exit'):

            self.close()

            return