def animationLabel(self, index, animationFile):
     """
     Public slot to set an animated icon.
     
     @param index tab index (integer)
     @param animationFile name of the file containing the animation (string)
     @return reference to the created label (QLabel)
     """
     if index == -1:
         return None
     
     if hasattr(self.__tabBar, 'setTabButton'):
         side = self.__freeSide()
         animation = QLabel(self)
         if animationFile and not animation.movie():
             movie = QMovie(animationFile, QByteArray(), animation)
             movie.setSpeed(50)
             animation.setMovie(movie)
             movie.start()
         self.__tabBar.setTabButton(index, side, None)
         self.__tabBar.setTabButton(index, side, animation)
         return animation
     else:
         return None
Exemplo n.º 2
0
class XLoaderWidget(QWidget):
    """ """
    Mode    = enum('Spinner', 'Progress')
    MOVIE   = None
    
    def __init__( self, parent = None, style='gray' ):
        super(XLoaderWidget, self).__init__( parent )
        
        # define properties
        self._currentMode       = None
        self._showSubProgress   = False
        
        self.setAttribute(Qt.WA_DeleteOnClose)
        
        # udpate the palette
        palette = self.palette()
        
        if style == 'white':
            palette.setColor( palette.Window, QColor(255, 255, 255, 180) )
        else:
            palette.setColor( palette.Window, QColor( 80, 80, 80, 180 ) )
        
        palette.setColor( palette.Base, Qt.gray )
        palette.setColor( palette.AlternateBase, Qt.lightGray )
        palette.setColor( palette.WindowText, Qt.gray )
        self.setPalette(palette)
        
        # create the movie label
        self._movieLabel = QLabel(self)
        self._movieLabel.setAlignment(Qt.AlignCenter)
        self._movieLabel.setMovie(XLoaderWidget.getMovie())
        self._movieLabel.setPalette(palette)
        
        self._smallMovieLabel = QLabel(self)
        self._smallMovieLabel.setAlignment(Qt.AlignCenter)
        self._smallMovieLabel.setMovie(XLoaderWidget.getMovie())
        self._smallMovieLabel.setPalette(palette)
        self._smallMovieLabel.hide()
        
        # create text label
        self._messageLabel = QLabel(self)
        self._messageLabel.setAlignment(Qt.AlignCenter)
        self._messageLabel.setText('Loading...')
        self._messageLabel.setPalette(palette)
        
        # create primary progress bar
        self._primaryProgressBar    = XLoaderProgressBar(self)
        self._subProgressBar        = XLoaderProgressBar(self)
        
        self._primaryProgressBar.setPalette(palette)
        self._subProgressBar.setPalette(palette)
        
        # create the loader widget
        self._loaderFrame = QFrame(self)
        self._loaderFrame.setFrameShape(QFrame.Box)
        self._loaderFrame.setAutoFillBackground(True)
        self._loaderFrame.setFixedWidth(160)
        self._loaderFrame.setFixedHeight(60)
        
        if style == 'white':
            palette.setColor(palette.Window, QColor('white'))
        else:
            palette.setColor(palette.Window, QColor(85, 85, 85))
        self._loaderFrame.setPalette(palette)
        
        layout = QVBoxLayout()
        layout.addWidget(self._movieLabel)
        layout.addWidget(self._primaryProgressBar)
        layout.addWidget(self._subProgressBar)
        layout.addStretch()
        layout.addWidget(self._messageLabel)
        self._loaderFrame.setLayout(layout)
        
        # set default properties
        self.setAutoFillBackground(True)
        
        # layout the controls
        layout = QVBoxLayout()
        layout.addStretch(1)
        layout.addWidget(self._loaderFrame)
        layout.addWidget(self._smallMovieLabel)
        layout.addStretch(1)
        
        hlayout = QHBoxLayout()
        hlayout.addStretch(1)
        hlayout.addLayout(layout)
        hlayout.addStretch(1)
        
        self.setLayout(hlayout)
        self.setCurrentMode(XLoaderWidget.Mode.Spinner)
        
        # create connections
    
    def currentMode( self ):
        """
        Returns the current mode that this loader's in.
        
        :return     <XLoaderWidget.Mode>
        """
        return self._currentMode
    
    def eventFilter( self, object, event ):
        """
        Resizes this widget with the parent when its resize event is triggered.
        
        :param      object | <QObject>
                    event  | <QEvent>
        
        :return     <bool> | consumed
        """
        if event.type() == event.Resize:
            self.resize(event.size())
            
        elif event.type() == event.Move:
            self.move(event.pos())
        
        elif event.type() == event.Close:
            self.setParent(None)
            self.deleteLater()
        
        return False
    
    def increment( self, amount=1):
        """
        Increments the main progress bar by amount.
        """
        self._primaryProgressBar.setValue(self.value() + amount)
    
    def incrementSub( self, amount=1):
        """
        Increments the sub-progress bar by amount.
        """
        self._subProgressBar.setValue(self.subValue() + amount)
    
    def message( self ):
        """
        Returns the current message being displayed in the loader.
        
        :return     <str>
        """
        return self._messageLabel.text()
    
    def movie(self):
        """
        Returns the movie linked with this loader.
        
        :return     <QMovie>
        """
        return self._movieLabel.movie()
    
    def resize(self, size):
        """
        Handles when the loader is too small for an area.
        
        :param      event | <QResizeEvent>
        """
        super(XLoaderWidget, self).resize(size)
        
        # show small loader
        if size.width() < self._loaderFrame.width() or \
           size.height() < self._loaderFrame.height():
            self._loaderFrame.hide()
            self._smallMovieLabel.show()
        
        # show regular loader
        else:
            self._loaderFrame.show()
            self._smallMovieLabel.hide()
    
    def subValue( self ):
        """
        Returns the value of the sub progress bar.
        
        :return     <int>
        """
        return self._subProgressBar.value()
    
    def setCurrentMode( self, mode ):
        """
        Sets what mode this loader will be in.
        
        :param      mode | <XLoaderWidget.Mode>
        """
        if ( mode == self._currentMode ):
            return
            
        self._currentMode = mode
        
        ajax = mode == XLoaderWidget.Mode.Spinner
        self._movieLabel.setVisible(ajax)
        self._primaryProgressBar.setVisible(not ajax)
        self._subProgressBar.setVisible(not ajax and self._showSubProgress)
    
    def setMessage( self, message ):
        """
        Sets the loading message to display.
        
        :param      message | <str>
        """
        self._messageLabel.setText(message)
    
    def setMovie( self, movie ):
        """
        Sets the movie for this loader to the inputed movie.
        
        :param      movie | <QMovie>
        """
        self._movieLabel.setMovie(movie)
        self._smallMovieLabel.setMovie(movie)
    
    def setTotal( self, amount ):
        """
        Sets the total amount for the main progress bar.
        
        :param      amount | <int>
        """
        self._primaryProgressBar.setValue(0)
        self._primaryProgressBar.setMaximum(amount)
        
        if amount:
            self.setCurrentMode(XLoaderWidget.Mode.Progress)
    
    def setSubTotal( self, amount ):
        """
        Sets the total value for the sub progress bar.
        
        :param      amount | <int>
        """
        self._subProgressBar.setValue(0)
        self._subProgressBar.setMaximum(amount)
        if amount:
            self.setShowSubProgress(True)
    
    def setSubValue( self, value ):
        """
        Sets the current value for the sub progress bar.
        
        :param      value | <int>
        """
        self._subProgressBar.setValue(value)
        
    def setShowSubProgress( self, state ):
        """
        Toggles whether or not the sub progress bar should be visible.
        
        :param      state | <bool>
        """
        ajax = self.currentMode() == XLoaderWidget.Mode.Spinner
        self._showSubProgress = state
        self._subProgressBar.setVisible(not ajax and state)
    
    def setValue(self, value):
        """
        Sets the current value for the primary progress bar.
        
        :param      value | <int>
        """
        self._primaryProgressBar.setValue(value)
    
    def showSubProgress( self ):
        """
        Returns whether or not the sub progress bar is visible when not in
        ajax mode.
        
        :return     <bool>
        """
        return self._showSubProgress
    
    def subValue( self ):
        """
        Returns the sub value for this loader.
        
        :return     <int>
        """
        return self._subProgressBar.value()
    
    def value( self ):
        """
        Returns the value for the primary progress bar.
        
        :return     <int>
        """
        return self._primaryProgressBar.value()
    
    @staticmethod
    def getMovie():
        """
        Returns the movie instance for the loader widget.
        
        :return     <QMovie>
        """
        if not XLoaderWidget.MOVIE:
            filename = projexui.resources.find('img/ajax_loader.gif')
            XLoaderWidget.MOVIE = QMovie()
            XLoaderWidget.MOVIE.setFileName(filename)
            XLoaderWidget.MOVIE.start()
        
        return XLoaderWidget.MOVIE
    
    @staticmethod
    def start(widget, processEvents=True, style=None, movie=None):
        """
        Starts a loader widget on the inputed widget.
        
        :param      widget          | <QWidget>
        
        :return     <XLoaderWidget>
        """
        if style is None:
            style = os.environ.get('PROJEXUI_LOADER_STYLE', 'gray')
        
        # there is a bug with the way the loader is handled in a splitter,
        # so bypass it
        parent = widget.parent()
        while isinstance(parent, QSplitter):
            parent = parent.parent()
        
        # retrieve the loader widget
        loader = getattr(widget, '_private_xloader_widget', None)
        if not loader:
            loader = XLoaderWidget(parent, style)
            
            # make sure that if the widget is destroyed, the loader closes
            widget.destroyed.connect(loader.deleteLater)
            
            setattr(widget, '_private_xloader_widget', loader)
            setattr(widget, '_private_xloader_count', 0)
            
            loader.move(widget.pos())
            if widget.isVisible():
                loader.show()
            
            if movie:
                loader.setMovie(movie)
            
            widget.installEventFilter(loader)
        else:
            count = getattr(widget, '_private_xloader_count', 0)
            setattr(widget, '_private_xloader_count', count + 1)
        
        loader.resize(widget.size())
        return loader
    
    @staticmethod
    def stop(widget, force=False):
        """
        Stops a loader widget on the inputed widget.
        
        :param      widget | <QWidget>
        """
        # make sure we have a widget to stop
        loader = getattr(widget, '_private_xloader_widget', None)
        if not loader:
            return
        
        # decrement the number of times this loader was created for the widget
        # to allow for stacked closure
        count = getattr(widget, '_private_xloader_count', 0)
        if force or count <= 1:
            # close out the loader widget
            setattr(widget, '_private_xloader_count', 0)
            setattr(widget, '_private_xloader_widget', None)
            
            loader.close()
            loader.setParent(None)
            loader.deleteLater()
        else:
            setattr(widget, '_private_xloader_count', count - 1)
    
    @staticmethod
    def stopAll(widget):
        """
        Stops all loader widgets from this parent down, cleaning out the \
        memory for them.
        
        :param      widget  | <QWidget>
        """
        for loader in widget.findChildren(XLoaderWidget):
            loader.setParent(None)
            loader.deleteLater()