Exemplo n.º 1
0
class _QueuedMessageWidget(QWidget):
    
    cleared = pyqtSignal()
    finished = pyqtSignal()
    shown = pyqtSignal()
    closed = pyqtSignal()
    linkActivated = pyqtSignal(unicode)
    linkHovered= pyqtSignal(unicode)
    buttonClicked = pyqtSignal(QAbstractButton)
    
    def __init__(self, *args):
        QWidget.__init__(self, *args)
        self._messages = []
        self._defaultTimeout = 0
        self._defaultPixmap = QPixmap(":/enkiicons/infos.png" )
        self._defaultBackground = QBrush( QColor( 250, 230, 147 ) )
        self._defaultForeground = QBrush( QColor( 0, 0, 0 ) )
        
        # pixmap
        self.lPixmap = QLabel( self )
        self.lPixmap.setAlignment( Qt.AlignCenter )
        self.lPixmap.setSizePolicy( QSizePolicy( QSizePolicy.Maximum, QSizePolicy.Preferred ) )
        
        # message
        self.lMessage = QLabel( self )
        self.lMessage.setAlignment( Qt.AlignVCenter | Qt.AlignLeft )
        self.lMessage.setSizePolicy( QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred ) )
        self.lMessage.setWordWrap( True )
        self.lMessage.setOpenExternalLinks( True )
        self.lMessage.setTextInteractionFlags( Qt.TextBrowserInteraction )
        
        # button
        self.dbbButtons = QDialogButtonBox( self )
        
        # if false - buttons don't have neither text nor icons
        self.dbbButtons.setStyleSheet("dialogbuttonbox-buttons-have-icons: true;")

        self.dbbButtons.setSizePolicy( QSizePolicy( QSizePolicy.Maximum, QSizePolicy.Preferred ) )
        
        self.setSizePolicy( QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Maximum ) )
        
        # layout
        self.hbl = QHBoxLayout( self )
        self.hbl.setMargin( 0 )
        self.hbl.addWidget( self.lPixmap, 0, Qt.AlignCenter )
        self.hbl.addWidget( self.lMessage )
        self.hbl.addWidget( self.dbbButtons, 0, Qt.AlignCenter )
        
        # connections
        self.lMessage.linkActivated.connect(self.linkActivated)
        self.lMessage.linkHovered.connect(self.linkHovered)
        self.dbbButtons.clicked.connect(self.buttonClicked)

    def sizeHint(self):
        return QWidget.minimumSizeHint(self)

    def openExternalLinks(self):
        return self.lMessage.openExternalLinks()

    def defaultTimeout(self):
        return self._defaultTimeout

    def defaultPixmap(self):
        return self._defaultPixmap

    def defaultBackground(self):
        return self._defaultBackground

    def defaultForeground(self):
        return self._defaultForeground

    def currentMessageInformations(self):
        return self.currentMessagePixmap(), self.currentMessageBackground(), self.currentMessageForeground()

    def pendingMessageCount(self):
        return len(self._messages)

    def currentMessage(self):
        return self._messages[0]

    def append(self, message, milliSeconds ):
        msg = _QueuedMessage()
        msg.message = message
        if milliSeconds == -1:
            msg.milliSeconds = self._defaultTimeout
        else:
           msg.milliSeconds = milliSeconds
        msg.pixmap = self._defaultPixmap
        msg.background = self._defaultBackground
        msg.foreground = self._defaultForeground
        
        self._messages.append(msg)
            
        if  len(self._messages) == 1 :
            QTimer.singleShot( 0, self.showMessage)

    def setOpenExternalLinks(self, open ):
        self.lMessage.setOpenExternalLinks( open )

    def setDefaultTimeout(self, timeout ):
        self._defaultTimeout = timeout

    def setDefaultPixmap(self, pixmap ):
        self._defaultPixmap = pixmap

    def setDefaultBackground(self, brush ):
        self._defaultBackground = brush

    def setDefaultForeground(self, brush ):
        self._defaultForeground = brush

    def remove(self, message ):
        raise NotImplemented()  # incorrect port from cpp fresh
        if not self._messages or self._messages.first() == message:
            return

        self._messages.removeOne( message )

    def clear(self):
        self._messages.clear()
        self.lPixmap.clear()
        self.lMessage.clear()
        self.dbbButtons.clear()
        self.cleared.emit()

    def currentMessagePixmap(self):
        msg = self.currentMessage()
        if msg.pixmap.isNull():
            return self._defaultPixmap
        else:
            return msg.pixmap

    def currentMessageBackground(self):
        msg = self.currentMessage()
        if msg.background == QBrush( Qt.NoBrush ):
            return self._defaultBackground
        else:
            return msg.background

    def currentMessageForeground(self):
        msg = self.currentMessage()
        if msg.foreground == QBrush( Qt.NoBrush ):
            return self._defaultForeground
        else:
            return msg.foreground

    def paintEvent(self, event ):
        if  self.pendingMessageCount() == 0 :
            QWidget.paintEvent(self, event )
            return
        
        painter = QPainter( self )
        painter.setPen( Qt.NoPen )
        painter.setBrush( self.currentMessageBackground() )
        painter.drawRect( self.contentsRect() )

    def buttonClicked(self, button ):
        msg = self.currentMessage()
        standardButton = self.dbbButtons.standardButton( button )
        
        if msg.slot is not None:
            msg.slot(standardButton, msg)
        
        self.closeMessage()

    def showMessage(self):
        # get message
        msg = self.currentMessage()
        
        # update palette
        pal = self.lMessage.palette()
        pal.setBrush( self.lMessage.foregroundRole(), self.currentMessageForeground() )
        self.lMessage.setPalette( pal )
        
        # format widget
        self.lPixmap.setPixmap( self.currentMessagePixmap() )
        self.lMessage.setText( msg.message )
        self.lMessage.setToolTip( msg.message )
        self.lMessage.setWhatsThis( msg.message )
        
        # set buttons
        if not msg.buttons:
            msg.buttons[ QDialogButtonBox.Close ] = None

        self.dbbButtons.clear()
        
        for button in msg.buttons.keys():
            pb = self.dbbButtons.addButton( button )
            
            if button in msg.buttons:
                pb.setText( msg.buttons[ button ] )
        
        # auto close if needed
        if msg.milliSeconds == -1:
            timeout = self._defaultTimeout
        else:
            timeout =  msg.milliSeconds
        
        if  timeout > 0:
            QTimer.singleShot( timeout, self.closeMessage )
        
        # signal.emit
        self.shown.emit()

    def closeMessage(self):
        # message.emit
        self.closed.emit()
        
        # remove remove current message from hash
        self._messages = self._messages[1:]
        
        # process next if possible, clear gui
        if self._messages:
            QTimer.singleShot( 0, self.showMessage)
        else:
            QTimer.singleShot( 0, self.clearMessage)
        
        # finished.emit message if needed
        if not self._messages:
            self.finished.emit()

    def clearMessage(self):
        self.lPixmap.clear()
        self.lMessage.clear()
        self.dbbButtons.clear()