Example #1
0
 def __init__(self, parent=None):
     QtGui.QItemDelegate.__init__(self, parent)
     self.rowAnimator = RowAnimator(parent.packageList.reset)
     icon_path = KIconLoader().iconPath(DEFAULT_ICON, KIconLoader.Panel)
     self.defaultIcon = QtGui.QIcon(
         QtGui.QPixmap(icon_path).scaled(QSize(32, 32), Qt.KeepAspectRatio))
     self.animatable = True
Example #2
0
    def __init__(self,
                 parent=None,
                 mainWindow=None,
                 showDetailsButton=True,
                 animatable=True):
        super(PackageDelegate, self).__init__(parent)
        self.webDialog = WebDialog(mainWindow)
        self.show_details_button = showDetailsButton

        self.rowAnimator = RowAnimator(parent.packageList)
        self.defaultIcon = QIcon(
            QPixmap('/usr/share/package-manager/data/tray-zero.svg').scaled(
                32, 32))
        #self.defaultIcon = KIcon(('package-x-generic', 'package_applications'), 32)
        self.defaultInstalledIcon = QIcon(
            QPixmap('/usr/share/package-manager/data/installed.svg').scaled(
                32, 32))
        #self.defaultInstalledIcon = KIcon(KIconLoader.loadOverlayed(('package-x-generic', 'package_applications'), CHECK_ICON, 32))
        self.animatable = animatable
        self._max_height = ROW_HEIGHT

        self._rt_0 = QIcon(":/data/star_0.svg")
        self._rt_1 = QIcon(":/data/star_1.svg")

        self.types = {
            'critical': (RED, _translate("Packaga Manager", 'critical')),
            'security': (DARKRED, _translate("Packaga Manager", 'security'))
        }

        self.font = Pds.settings('font', 'Sans,10').split(',')[0]

        self.normalFont = QFont(self.font, 10, QFont.Normal)
        self.boldFont = QFont(self.font, 11, QFont.Bold)
        self.normalDetailFont = QFont(self.font, 9, QFont.Normal)
        self.boldDetailFont = QFont(self.font, 9, QFont.Bold)
        self.tagFont = QFont(self.font, 7, QFont.Normal)

        self.tagFontFM = QFontMetrics(self.tagFont)
        self.boldFontFM = QFontMetrics(self.boldFont)
        self.boldDetailFontFM = QFontMetrics(self.boldDetailFont)
        self.normalFontFM = QFontMetrics(self.normalFont)
        self.normalDetailFontFM = QFontMetrics(self.normalDetailFont)

        self._titles = {
            'description': _translate("Packaga Manager", "Description:"),
            'website': _translate("Packaga Manager", "Website:"),
            'release': _translate("Packaga Manager", "Release:"),
            'repository': _translate("Packaga Manager", "Repository:"),
            'size': _translate("Packaga Manager", "Package Size:"),
            'installVers': _translate("Packaga Manager", "Installed Version:")
        }

        self._titleFM = {}
        for key, value in self._titles.items():
            self._titleFM[key] = self.boldDetailFontFM.width(
                value) + ICON_SIZE + 3

        self.baseWidth = self.boldFontFM.width(
            max(self._titles.values(), key=len)) + ICON_SIZE
        self.parent = parent.packageList
Example #3
0
    def __init__(self, parent=None, mainWindow=None, showDetailsButton=True, animatable=True):
        super(PackageDelegate, self).__init__(parent)
        self.webDialog = WebDialog(mainWindow)
        self.show_details_button = showDetailsButton

        self.rowAnimator = RowAnimator(parent.packageList)
        KIconLoader().addExtraDesktopThemes()
        self.defaultIcon = QtGui.QIcon(KIconLoader().loadIcon('applications-other', \
                                                               KIconLoader.Desktop, 32))
        self.defaultInstalledIcon = QtGui.QIcon(KIconLoader().loadIcon('applications-other', KIconLoader.Desktop, 32, KIconLoader.DefaultState, [CHECK_ICON]))
        self.animatable = animatable
        self._max_height = ROW_HEIGHT

        self._rt_0 = QtGui.QIcon(":/data/star_0.png")
        self._rt_1 = QtGui.QIcon(":/data/star_1.png")

        self.types = {'critical':(RED,     i18n('critical')),
                      'security':(DARKRED, i18n('security'))}

        self.font = QtGui.qApp.font().toString().split(',')[0]

        self.normalFont = QtGui.QFont(self.font, 10, QtGui.QFont.Normal)
        self.boldFont = QtGui.QFont(self.font, 11, QtGui.QFont.Bold)
        self.normalDetailFont = QtGui.QFont(self.font, 9, QtGui.QFont.Normal)
        self.boldDetailFont = QtGui.QFont(self.font, 9, QtGui.QFont.Bold)
        self.tagFont = QtGui.QFont(self.font, 7, QtGui.QFont.Normal)

        self.tagFontFM = QtGui.QFontMetrics(self.tagFont)
        self.boldFontFM = QtGui.QFontMetrics(self.boldFont)
        self.boldDetailFontFM = QtGui.QFontMetrics(self.boldDetailFont)
        self.normalFontFM = QtGui.QFontMetrics(self.normalFont)
        self.normalDetailFontFM = QtGui.QFontMetrics(self.normalDetailFont)

        self._titles = {'description': i18n("Description:"),
                        'website'    : i18n("Website:"),
                        'release'    : i18n("Release:"),
                        'repository' : i18n("Repository:"),
                        'size'       : i18n("Package Size:"),
                        'installVers': i18n("Installed Version:")}

        self._titleFM = {}
        for key, value in self._titles.items():
            self._titleFM[key] = self.boldDetailFontFM.width(value) + ICON_SIZE + 3

        self.baseWidth = self.boldFontFM.width(max(self._titles.values(), key=len)) + ICON_SIZE
        self.parent = parent.packageList

        # Base style for some of important features
        self.oxygen = QtGui.QStyleFactory.create('oxygen')
Example #4
0
    def __init__(self, parent=None, mainWindow=None, showDetailsButton=True, animatable=True):
        super(PackageDelegate, self).__init__(parent)
        self.state = StateManager(self)
        self.webDialog = WebDialog(self.state, mainWindow)
        self.show_details_button = showDetailsButton

        self.rowAnimator = RowAnimator(parent.packageList)
        KIconLoader().addExtraDesktopThemes()
        self.defaultIcon = QtGui.QIcon(KIconLoader().loadIcon('applications-other', \
                                                               KIconLoader.Desktop, 32))
        self.defaultInstalledIcon = QtGui.QIcon(KIconLoader().loadIcon('applications-other', KIconLoader.Desktop, 32, KIconLoader.DefaultState, [CHECK_ICON]))
        self.animatable = animatable
        self._max_height = ROW_HEIGHT

        self._rt_0 = QtGui.QIcon(":/data/star_0.png")
        self._rt_1 = QtGui.QIcon(":/data/star_1.png")

        self.types = {'critical':(RED,     i18n('critical')),
                      'security':(DARKRED, i18n('security'))}

        self.font = QtGui.qApp.font().toString().split(',')[0]

        self.normalFont = QtGui.QFont(self.font, 10, QtGui.QFont.Normal)
        self.boldFont = QtGui.QFont(self.font, 11, QtGui.QFont.Bold)
        self.normalDetailFont = QtGui.QFont(self.font, 9, QtGui.QFont.Normal)
        self.boldDetailFont = QtGui.QFont(self.font, 9, QtGui.QFont.Bold)
        self.tagFont = QtGui.QFont(self.font, 7, QtGui.QFont.Normal)

        self.tagFontFM = QtGui.QFontMetrics(self.tagFont)
        self.boldFontFM = QtGui.QFontMetrics(self.boldFont)
        self.boldDetailFontFM = QtGui.QFontMetrics(self.boldDetailFont)
        self.normalFontFM = QtGui.QFontMetrics(self.normalFont)
        self.normalDetailFontFM = QtGui.QFontMetrics(self.normalDetailFont)

        self._titles = {'description': i18n("Description:"),
                        'website'    : i18n("Website:"),
                        'release'    : i18n("Release:"),
                        'repository' : i18n("Repository:"),
                        'size'       : i18n("Package Size:"),
                        'installVers': i18n("Installed Version:")}

        self._titleFM = {}
        for key, value in self._titles.items():
            self._titleFM[key] = self.boldDetailFontFM.width(value) + ICON_SIZE + 3

        self.baseWidth = self.boldFontFM.width(max(self._titles.values(), key=len)) + ICON_SIZE
        self.parent = parent.packageList

        # Base style for some of important features
        self.oxygen = QtGui.QStyleFactory.create('oxygen')
    def __init__(self, parent=None, mainWindow=None, showDetailsButton=True, animatable=True):
        super(PackageDelegate, self).__init__(parent)
        self.webDialog = WebDialog(mainWindow)
        self.show_details_button = showDetailsButton

        self.rowAnimator = RowAnimator(parent.packageList)
        self.defaultIcon = QIcon(QPixmap('/usr/share/package-manager/data/tray-zero.svg').scaled(32, 32))
        #self.defaultIcon = KIcon(('package-x-generic', 'package_applications'), 32)
        self.defaultInstalledIcon = QIcon(QPixmap('/usr/share/package-manager/data/installed.svg').scaled(32, 32))
        #self.defaultInstalledIcon = KIcon(KIconLoader.loadOverlayed(('package-x-generic', 'package_applications'), CHECK_ICON, 32))
        self.animatable = animatable
        self._max_height = ROW_HEIGHT

        self._rt_0 = QIcon(":/data/star_0.svg")
        self._rt_1 = QIcon(":/data/star_1.svg")

        self.types = {'critical':(RED,     _translate("Packaga Manager",'critical')),
                      'security':(DARKRED, _translate("Packaga Manager",'security'))}

        self.font = Pds.settings('font','Sans,10').split(',')[0]

        self.normalFont = QFont(self.font, 10, QFont.Normal)
        self.boldFont = QFont(self.font, 11, QFont.Bold)
        self.normalDetailFont = QFont(self.font, 9, QFont.Normal)
        self.boldDetailFont = QFont(self.font, 9, QFont.Bold)
        self.tagFont = QFont(self.font, 7, QFont.Normal)

        self.tagFontFM = QFontMetrics(self.tagFont)
        self.boldFontFM = QFontMetrics(self.boldFont)
        self.boldDetailFontFM = QFontMetrics(self.boldDetailFont)
        self.normalFontFM = QFontMetrics(self.normalFont)
        self.normalDetailFontFM = QFontMetrics(self.normalDetailFont)

        self._titles = {'description': _translate("Packaga Manager","Description:"),
                        'website'    : _translate("Packaga Manager","Website:"),
                        'release'    : _translate("Packaga Manager","Release:"),
                        'repository' : _translate("Packaga Manager","Repository:"),
                        'size'       : _translate("Packaga Manager","Package Size:"),
                        'installVers': _translate("Packaga Manager","Installed Version:")}

        self._titleFM = {}
        for key, value in self._titles.items():
            self._titleFM[key] = self.boldDetailFontFM.width(value) + ICON_SIZE + 3

        self.baseWidth = self.boldFontFM.width(max(self._titles.values(), key=len)) + ICON_SIZE
        self.parent = parent.packageList
Example #6
0
    def __init__(self, parent=None):
        QtGui.QItemDelegate.__init__(self, parent)
        self.rowAnimator = RowAnimator(parent.packageList)
        self.defaultIcon = KIcon(DEFAULT_ICON, 32)
        self.animatable = True
        self._max_height = ROW_HEIGHT

        self.types = {"critical": (RED, i18n("critical")), "security": (DARKRED, i18n("security"))}

        self.font = Pds.settings("font", "Sans").split(",")[0]

        self.normalFont = QtGui.QFont(self.font, 10, QtGui.QFont.Normal)
        self.boldFont = QtGui.QFont(self.font, 11, QtGui.QFont.Bold)
        self.normalDetailFont = QtGui.QFont(self.font, 9, QtGui.QFont.Normal)
        self.boldDetailFont = QtGui.QFont(self.font, 9, QtGui.QFont.Bold)
        self.tagFont = QtGui.QFont(self.font, 7, QtGui.QFont.Normal)

        self.tagFontFM = QtGui.QFontMetrics(self.tagFont)
        self.boldFontFM = QtGui.QFontMetrics(self.boldFont)
        self.boldDetailFontFM = QtGui.QFontMetrics(self.boldDetailFont)
        self.normalFontFM = QtGui.QFontMetrics(self.normalFont)
        self.normalDetailFontFM = QtGui.QFontMetrics(self.normalDetailFont)

        self._titles = {
            "description": i18n("Description:"),
            "website": i18n("Website:"),
            "release": i18n("Release:"),
            "repository": i18n("Repository:"),
            "size": i18n("Package Size:"),
            "installVers": i18n("Installed Version:"),
        }

        self._titleFM = {}
        for key, value in self._titles.items():
            self._titleFM[key] = self.boldDetailFontFM.width(value) + ICON_SIZE + 3

        self.baseWidth = self.boldFontFM.width(max(self._titles.values(), key=len)) + ICON_SIZE
        self.parent = parent.packageList
class PackageDelegate(QStyledItemDelegate):
    packageSelected=pyqtSignal([bool])

    AppStyle = qApp.style

    def __init__(self, parent=None, mainWindow=None, showDetailsButton=True, animatable=True):
        super(PackageDelegate, self).__init__(parent)
        self.webDialog = WebDialog(mainWindow)
        self.show_details_button = showDetailsButton

        self.rowAnimator = RowAnimator(parent.packageList)
        self.defaultIcon = KIcon(('package-x-generic', 'package_applications'), 32)
        self.defaultInstalledIcon = QIcon(KIconLoader.loadOverlayed(('package-x-generic', 'package_applications'), CHECK_ICON, 32))
        self.animatable = animatable
        self._max_height = ROW_HEIGHT

        self._rt_0 = QIcon(":/data/star_0.svg")
        self._rt_1 = QIcon(":/data/star_1.svg")

        self.types = {'critical':(RED,     _translate("Packaga Manager",'critical')),
                      'security':(DARKRED, _translate("Packaga Manager",'security'))}

        self.font = Pds.settings('font','Sans,10').split(',')[0]

        self.normalFont = QFont(self.font, 10, QFont.Normal)
        self.boldFont = QFont(self.font, 11, QFont.Bold)
        self.normalDetailFont = QFont(self.font, 9, QFont.Normal)
        self.boldDetailFont = QFont(self.font, 9, QFont.Bold)
        self.tagFont = QFont(self.font, 7, QFont.Normal)

        self.tagFontFM = QFontMetrics(self.tagFont)
        self.boldFontFM = QFontMetrics(self.boldFont)
        self.boldDetailFontFM = QFontMetrics(self.boldDetailFont)
        self.normalFontFM = QFontMetrics(self.normalFont)
        self.normalDetailFontFM = QFontMetrics(self.normalDetailFont)

        self._titles = {'description': _translate("Packaga Manager","Description:"),
                        'website'    : _translate("Packaga Manager","Website:"),
                        'release'    : _translate("Packaga Manager","Release:"),
                        'repository' : _translate("Packaga Manager","Repository:"),
                        'size'       : _translate("Packaga Manager","Package Size:"),
                        'installVers': _translate("Packaga Manager","Installed Version:")}

        self._titleFM = {}
        for key, value in self._titles.items():
            self._titleFM[key] = self.boldDetailFontFM.width(value) + ICON_SIZE + 3

        self.baseWidth = self.boldFontFM.width(max(self._titles.values(), key=len)) + ICON_SIZE
        self.parent = parent.packageList

        # Base style for some of important features
        # self.plastik = QStyleFactory.create('plastique')

    def paint(self, painter, option, index):
        if not index.isValid():
            return super(PackageDelegate, self).paint(painter, option, index)
        
        if index.flags() & Qt.ItemIsUserCheckable:
            if index.column() == 0:
                self.paintCheckBoxColumn(painter, option, index)
            else:
                self.paintInfoColumn(painter, option, index)
        else:
            self.paintInfoColumn(painter, option, index, width_limit = 10)

    def paintCheckBoxColumn(self, painter, option, index):
        opt = QStyleOptionViewItem(option)
        
        buttonStyle = QStyleOptionButton()
        buttonStyle.state = QStyle.State_On if index.model().data(index, Qt.CheckStateRole) == QVariant(Qt.Checked) else QStyle.State_Off
        buttonStyle.state |= QStyle.State_Enabled
        
        if option.state & QStyle.State_MouseOver or option.state & QStyle.State_HasFocus:
            buttonStyle.state |= QStyle.State_HasFocus | QStyle.State_MouseOver
        

        buttonStyle.rect = opt.rect.adjusted(4, -opt.rect.height() + ROW_HEIGHT, 0, 0)
        PackageDelegate.AppStyle().drawControl(QStyle.CE_CheckBox, buttonStyle, painter, None)

    def paintInfoColumn(self, painter, option, index, width_limit = 0):
        left = option.rect.left() + 3
        top = option.rect.top()
        width = option.rect.width() - width_limit

        pixmap = QPixmap(option.rect.size())
        pixmap.fill(Qt.transparent)

        p = QPainter(pixmap)
        p.setRenderHint(QPainter.Antialiasing, True)
        p.translate(-option.rect.topLeft())

        textInner = 2 * ICON_PADDING + ROW_HEIGHT - 10
        itemHeight = ROW_HEIGHT + 2 * ICON_PADDING

        margin = left + ICON_PADDING - 10

        title = QVariant.value(index.model().data(index, NameRole))
        summary = QVariant.value(index.model().data(index, SummaryRole))
        ptype = QVariant.value(index.model().data(index, TypeRole))
        
        rate = int(QVariant.value(index.model().data(index, RateRole))) if QVariant.value(index.model().data(index, RateRole))!= None  else 0
        
        installed = True if QVariant.value(index.model().data(index, InstalledRole))=="True" else False
        
        # We need to request update if its not possible to get meta data about the package
        try:
            # Get Package Icon if exists
            _icon = QVariant.value(index.model().data(index, Qt.DecorationRole))
        except:
            p.end()
            painter.drawPixmap(option.rect.topLeft(), pixmap)
            self.parent.requestUpdate()
            return

        icon = None

        if _icon:
            overlay = [CHECK_ICON] if installed else []
            KIconLoader._forceCache = True
            pix = KIconLoader.loadOverlayed(_icon, overlay, 32)
            if not pix.isNull():
                icon = QIcon(pix.scaled(QSize(32, 32), Qt.KeepAspectRatio, Qt.SmoothTransformation))
            KIconLoader._forceCache = False
               

        if not icon:
            icon = self.defaultIcon if not installed else self.defaultInstalledIcon

        # Paint the Icon
        icon.paint(p, margin, top + ICON_PADDING, ROW_HEIGHT, ROW_HEIGHT, Qt.AlignCenter)

        fix_pos = 0
        if index.model().columnCount() <= 1:
            fix_pos = 22

        if config.USE_APPINFO:
            # Rating Stars
            for _rt_i in range(5):
                self._rt_0.paint(p, width + 10 * _rt_i - 30 - fix_pos, top + ROW_HEIGHT / 4, 10, 10, Qt.AlignCenter)
            for _rt_i in range(rate):
                self._rt_1.paint(p, width + 10 * _rt_i - 30 - fix_pos, top + ROW_HEIGHT / 4, 10, 10, Qt.AlignCenter)
        
        foregroundColor = option.palette.color(QPalette.Text)
        p.setPen(foregroundColor)

        # Package Name
        p.setFont(self.boldFont)
        p.drawText(left + textInner, top, width - textInner, itemHeight / 2,Qt.AlignBottom | Qt.AlignLeft, title) # 
                
        tagWidth = 0

        _component_width = 0
        if self.parent.showComponents:
            component = str(QVariant.value(index.model().data(index, ComponentRole)))
            widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner

            p.setFont(self.tagFont)
            rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, component)
            p.setPen(LIGHTGREEN)
            p.setBrush(LIGHTGREEN)
            p.drawRoundedRect(widthOfTitle , top + 12, rect.width() + 4, rect.height(), 10, 10)
            p.setPen(DARKGREEN)
            p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(), Qt.AlignCenter, component)
            p.setPen(foregroundColor)
            _component_width = rect.width() + 8

        if self.parent.showIsA:
            isa = str(QVariant.value(index.model().data(index, IsaRole)))
            if not isa == '':
                widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner + _component_width

                p.setFont(self.tagFont)
                rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, isa)
                p.setPen(LIGHTBLUE)
                p.setBrush(LIGHTBLUE)
                p.drawRoundedRect(widthOfTitle , top + 12, rect.width() + 4, rect.height(), 10, 10)
                p.setPen(DARKVIOLET)
                p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(), Qt.AlignCenter, isa)
                p.setPen(foregroundColor)
                _component_width += rect.width() + 8

        if ptype not in ('None', 'normal'):
            widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner + _component_width
            p.setFont(self.tagFont)
            rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, self.types[ptype][1])
            p.setPen(self.types[ptype][0])
            p.setBrush(self.types[ptype][0])
            p.drawRoundedRect(widthOfTitle, top + 12, rect.width() + 4, rect.height(), 10, 10)
            p.setPen(WHITE)
            p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(), Qt.AlignCenter, self.types[ptype][1])
            p.setPen(foregroundColor)
            tagWidth = rect.width()

        # Package Summary
        p.setFont(self.normalFont)
        foregroundColor.setAlpha(160)
        p.setPen(foregroundColor)
        elided_summary = self.normalFontFM.elidedText(summary, Qt.ElideRight, width - textInner - tagWidth - 22)
        p.drawText(left + textInner, top + itemHeight / 2, width - textInner, itemHeight / 2, Qt.TextDontClip, elided_summary)
        foregroundColor.setAlpha(255)
        p.setPen(foregroundColor)

        buttonStyle = None
        if self.rowAnimator.currentRow() == index.row():
            description = str(QVariant.value(index.model().data(index, DescriptionRole)))
            size = str(QVariant.value(index.model().data(index, SizeRole)))
            homepage = str(QVariant.value(index.model().data(index, HomepageRole)))
            installedVersion = str(QVariant.value(index.model().data(index, InstalledVersionRole)))
            version = str(QVariant.value(index.model().data(index, VersionRole)))

            # Package Detail Label
            position = top + ROW_HEIGHT

            p.setFont(self.normalDetailFont)
            baseRect = QRect(left, position, width - 8, option.rect.height())
            rect = self.normalDetailFontFM.boundingRect(baseRect, Qt.TextWordWrap | Qt.TextDontClip, description)
            p.drawText(left + 2, position, width - 8, rect.height(), Qt.TextWordWrap | Qt.TextDontClip, description)

            # Package Detail Homepage
            position += rect.height() + 4

            p.setFont(self.boldDetailFont)
            p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['website'])

            p.setFont(self.normalDetailFont)
            homepage = self.normalDetailFontFM.elidedText(homepage, Qt.ElideRight, width - self._titleFM['website'])
            rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextSingleLine, homepage)
            self.rowAnimator.hoverLinkFilter.link_rect = QRect(left + self._titleFM['website'] + 2, position + 2 + 32, rect.width(), rect.height())

            p.setPen(option.palette.color(QPalette.Link))
            p.drawText(left + self._titleFM['website'], position, width, rect.height(), Qt.TextSingleLine, homepage)
            p.setPen(foregroundColor)

            # Package Detail Version
            position += rect.height()

            p.setFont(self.boldDetailFont)
            p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['release'])

            p.setFont(self.normalDetailFont)
            rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextWordWrap, version)
            p.drawText(left + self._titleFM['release'], position, width, rect.height(), Qt.TextWordWrap, version)

            if not installedVersion == '' or not installedVersion == None:
                position += rect.height()

                p.setFont(self.boldDetailFont)
                p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['installVers'])

                p.setFont(self.normalDetailFont)
                rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextWordWrap, installedVersion)
                p.drawText(left + self._titleFM['installVers'], position, width, rect.height(), Qt.TextWordWrap, installedVersion)

            # Package Detail Repository
            repository = QVariant.value(index.model().data(index, RepositoryRole))
            if not repository == '':
                repository = _translate("Packaga Manager",'Unknown')  if repository == 'N/A' else repository
                position += rect.height()

                p.setFont(self.boldDetailFont)
                p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['repository'])

                p.setFont(self.normalDetailFont)
                p.drawText(left + self._titleFM['repository'], position, width, itemHeight / 2, Qt.TextWordWrap, repository)

            # Package Detail Size
            position += rect.height()

            p.setFont(self.boldDetailFont)
            p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles['size'])

            p.setFont(self.normalDetailFont)
            p.drawText(left + self._titleFM['size'], position, width, itemHeight / 2, Qt.TextWordWrap, size)
            position += rect.height()
            self.rowAnimator.max_height = position - top + 8

            # Package More info button
            opt = QStyleOptionViewItem(option)

            buttonStyle = QStyleOptionButton()
            if option.state & QStyle.State_MouseOver or option.state & QStyle.State_HasFocus:
                buttonStyle.state |= QStyle.State_HasFocus
            
            buttonStyle.state |= QStyle.State_Enabled
            buttonStyle.text = _translate("Packaga Manager","Details")

            buttonStyle.rect = QRect(width - 100, position - 22, 100, 22)

        p.end()

        # FIXME
        # if option.state & QStyle.State_HasFocus and self.animatable:
        #     option.state |= QStyle.State_MouseOver
            # Use Plastique style to draw focus rect like MouseOver effect of Oxygen.
            # self.plastik.drawPrimitive(QStyle.PE_FrameLineEdit, option, painter, None)

        if not self.rowAnimator.running() and buttonStyle:
            if self.show_details_button and (installed or config.USE_APPINFO):
                PackageDelegate.AppStyle().drawControl(QStyle.CE_PushButton, buttonStyle, painter, None)
                self.rowAnimator.hoverLinkFilter.button_rect = QRect(buttonStyle.rect)

        painter.drawPixmap(option.rect.topLeft(), pixmap)
        del pixmap

    def editorEvent(self, event, model, option, index):
        #paket seçim olayında hata var seçim olayı gerçekleşiyor ama packageList sonraki seçimde görüyor
        #geçici çözümle giderildi tamamen çözülmeli
        if event.type() == QEvent.MouseButtonRelease and index.column() == 0 and index.flags() & Qt.ItemIsUserCheckable:
            toggled = Qt.Checked if model.data(index, Qt.CheckStateRole) == QVariant(Qt.Unchecked) else Qt.Unchecked
            self.packageSelected.emit(bool(toggled))
            return model.setData(index, toggled, Qt.CheckStateRole)
        
        __event = QItemDelegate(self).editorEvent(event, model, option, index)
        
        animate_requested = False
        if event.type() == QEvent.MouseButtonRelease and self.animatable:
            if self.rowAnimator.row == index.row():
                epos = event.pos()
                if self.rowAnimator.hoverLinkFilter.link_rect.contains(QPoint(epos.x(), epos.y() + 32)):
                    url = QUrl(QVariant.value(model.data(index, HomepageRole)))
                    QDesktopServices.openUrl(url)
                    return __event
                elif self.rowAnimator.hoverLinkFilter.button_rect.contains(epos, True):
                    self.showPackageDetails(model, index)
                    return __event
            animate_requested = True
        elif event.type() == QEvent.KeyPress and self.animatable:
            # KeyCode 32 : Space key
            if event.key() == 32 and index.column() == index.model().columnCount() - 1:
                animate_requested = True
        if not QVariant.value(model.data(index, DescriptionRole)) == '' and animate_requested:
            self.rowAnimator.animate(index.row())
        return __event

    def showPackageDetails(self, model, index):

        def _getter(role):
            return model.data(index, role)

        name = _getter(NameRole)
        summary = _getter(SummaryRole)
        description = _getter(DescriptionRole)
        installed = True if str(QVariant.value(model.data(index, InstalledRole)))=="True" else False
        
        self.webDialog.showPackageDetails(name, installed, summary, description)

    def sizeHint(self, option, index):
        if self.rowAnimator.currentRow() == index.row() and not index.row() == 0:
            return self.rowAnimator.size()
        else:
            width = ICON_SIZE if index.column() == 0 else 0
            return QSize(width, ROW_HEIGHT)

    def setAnimatable(self, animatable):
        self.animatable = animatable

    def reset(self):
        self.rowAnimator.reset()
class PackageDelegate(QStyledItemDelegate):

    AppStyle = QApplication.style

    def __init__(self,
                 parent=None,
                 mainWindow=None,
                 showDetailsButton=True,
                 animatable=True):
        super(PackageDelegate, self).__init__(parent)
        self.webDialog = WebDialog(mainWindow)
        self.show_details_button = showDetailsButton

        self.rowAnimator = RowAnimator(parent.packageList)
        self.defaultIcon = KIcon(('package-x-generic', 'package_applications'),
                                 32)
        self.defaultInstalledIcon = QIcon(
            KIconLoader.loadOverlayed(
                ('package-x-generic', 'package_applications'), CHECK_ICON, 32))
        self.animatable = animatable
        self._max_height = ROW_HEIGHT

        self._rt_0 = QIcon(":/data/star_0.png")
        self._rt_1 = QIcon(":/data/star_1.png")

        self.types = {
            'critical': (RED, self.tr('critical')),
            'security': (DARKRED, self.tr('security'))
        }

        self.font = Pds.settings('font', 'Sans,10').split(',')[0]

        self.normalFont = QFont(self.font, 10, QFont.Normal)
        self.boldFont = QFont(self.font, 11, QFont.Bold)
        self.normalDetailFont = QFont(self.font, 9, QFont.Normal)
        self.boldDetailFont = QFont(self.font, 9, QFont.Bold)
        self.tagFont = QFont(self.font, 7, QFont.Normal)

        self.tagFontFM = QFontMetrics(self.tagFont)
        self.boldFontFM = QFontMetrics(self.boldFont)
        self.boldDetailFontFM = QFontMetrics(self.boldDetailFont)
        self.normalFontFM = QFontMetrics(self.normalFont)
        self.normalDetailFontFM = QFontMetrics(self.normalDetailFont)

        self._titles = {
            'description': self.tr("Description:"),
            'website': self.tr("Website:"),
            'release': self.tr("Release:"),
            'repository': self.tr("Repository:"),
            'size': self.tr("Package Size:"),
            'installVers': self.tr("Installed Version:")
        }

        self._titleFM = {}
        for key, value in self._titles.items():
            self._titleFM[key] = self.boldDetailFontFM.width(
                value) + ICON_SIZE + 3

        self.baseWidth = self.boldFontFM.width(
            max(self._titles.values(), key=len)) + ICON_SIZE
        self.parent = parent.packageList

        # Base style for some of important features
        # self.plastik = QStyleFactory.create('plastique')

    def paint(self, painter, option, index):
        if not index.isValid():
            return super(PackageDelegate, self).paint(painter, option, index)

        if index.flags() & Qt.ItemIsUserCheckable:
            if index.column() == 0:
                self.paintCheckBoxColumn(painter, option, index)
            else:
                self.paintInfoColumn(painter, option, index)
        else:
            self.paintInfoColumn(painter, option, index, width_limit=10)

    def paintCheckBoxColumn(self, painter, option, index):
        opt = QStyleOptionViewItem(option)

        buttonStyle = QStyleOptionButton()
        buttonStyle.state = QStyle.State_On if index.model().data(
            index, Qt.CheckStateRole) == QVariant(
                Qt.Checked) else QStyle.State_Off

        if option.state & QStyle.State_MouseOver or option.state & QStyle.State_HasFocus:
            buttonStyle.state |= QStyle.State_HasFocus

        buttonStyle.rect = opt.rect.adjusted(4,
                                             -opt.rect.height() + ROW_HEIGHT,
                                             0, 0)
        PackageDelegate.AppStyle().drawControl(QStyle.CE_CheckBox, buttonStyle,
                                               painter, None)

    def paintInfoColumn(self, painter, option, index, width_limit=0):
        left = option.rect.left() + 3
        top = option.rect.top()
        width = option.rect.width() - width_limit

        pixmap = QPixmap(option.rect.size())
        pixmap.fill(Qt.transparent)

        p = QPainter(pixmap)
        p.setRenderHint(QPainter.Antialiasing, True)
        p.translate(-option.rect.topLeft())

        textInner = 2 * ICON_PADDING + ROW_HEIGHT - 10
        itemHeight = ROW_HEIGHT + 2 * ICON_PADDING

        margin = left + ICON_PADDING - 10

        title = index.model().data(index, NameRole).toString()
        summary = index.model().data(index, SummaryRole).toString()
        ptype = str(index.model().data(index, TypeRole).toString())
        rate = int(index.model().data(index, RateRole).toInt()[0])
        installed = index.model().data(index, InstalledRole).toBool()

        # We need to request update if its not possible to get meta data about the package
        try:
            # Get Package Icon if exists
            _icon = index.model().data(index, Qt.DecorationRole).toString()
        except:
            p.end()
            painter.drawPixmap(option.rect.topLeft(), pixmap)
            self.parent.requestUpdate()
            return

        icon = None

        if _icon:
            overlay = [CHECK_ICON] if installed else []
            KIconLoader._forceCache = True
            pix = KIconLoader.loadOverlayed(_icon, overlay, 32)
            if not pix.isNull():
                icon = QIcon(
                    pix.scaled(QSize(32, 32), Qt.KeepAspectRatio,
                               Qt.SmoothTransformation))
            KIconLoader._forceCache = False

        if not icon:
            icon = self.defaultIcon if not installed else self.defaultInstalledIcon

        # Paint the Icon
        icon.paint(p, margin, top + ICON_PADDING, ROW_HEIGHT, ROW_HEIGHT,
                   Qt.AlignCenter)

        fix_pos = 0
        if index.model().columnCount() <= 1:
            fix_pos = 22

        if config.USE_APPINFO:
            # Rating Stars
            for _rt_i in range(5):
                self._rt_0.paint(p, width + 10 * _rt_i - 30 - fix_pos,
                                 top + ROW_HEIGHT / 4, 10, 10, Qt.AlignCenter)
            for _rt_i in range(rate):
                self._rt_1.paint(p, width + 10 * _rt_i - 30 - fix_pos,
                                 top + ROW_HEIGHT / 4, 10, 10, Qt.AlignCenter)

        foregroundColor = option.palette.color(QPalette.Text)
        p.setPen(foregroundColor)

        # Package Name
        p.setFont(self.boldFont)
        p.drawText(left + textInner, top, width - textInner, itemHeight / 2,
                   Qt.AlignBottom | Qt.AlignLeft, title)

        tagWidth = 0

        _component_width = 0
        if self.parent.showComponents:
            component = str(index.model().data(index,
                                               ComponentRole).toString())
            widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner

            p.setFont(self.tagFont)
            rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap,
                                               component)
            p.setPen(LIGHTGREEN)
            p.setBrush(LIGHTGREEN)
            p.drawRoundRect(widthOfTitle, top + 12,
                            rect.width() + 4, rect.height(), 10, 10)
            p.setPen(DARKGREEN)
            p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(),
                       Qt.AlignCenter, component)
            p.setPen(foregroundColor)
            _component_width = rect.width() + 8

        if self.parent.showIsA:
            isa = str(index.model().data(index, IsaRole).toString())
            if not isa == '':
                widthOfTitle = self.boldFontFM.width(
                    title) + 6 + left + textInner + _component_width

                p.setFont(self.tagFont)
                rect = self.tagFontFM.boundingRect(option.rect,
                                                   Qt.TextWordWrap, isa)
                p.setPen(LIGHTBLUE)
                p.setBrush(LIGHTBLUE)
                p.drawRoundRect(widthOfTitle, top + 12,
                                rect.width() + 4, rect.height(), 10, 10)
                p.setPen(DARKVIOLET)
                p.drawText(widthOfTitle + 2, top + 12, rect.width(),
                           rect.height(), Qt.AlignCenter, isa)
                p.setPen(foregroundColor)
                _component_width += rect.width() + 8

        if ptype not in ('None', 'normal'):
            widthOfTitle = self.boldFontFM.width(
                title) + 6 + left + textInner + _component_width
            p.setFont(self.tagFont)
            rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap,
                                               self.types[ptype][1])
            p.setPen(self.types[ptype][0])
            p.setBrush(self.types[ptype][0])
            p.drawRoundRect(widthOfTitle, top + 12,
                            rect.width() + 4, rect.height(), 10, 10)
            p.setPen(WHITE)
            p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(),
                       Qt.AlignCenter, self.types[ptype][1])
            p.setPen(foregroundColor)
            tagWidth = rect.width()

        # Package Summary
        p.setFont(self.normalFont)
        foregroundColor.setAlpha(160)
        p.setPen(foregroundColor)
        elided_summary = self.normalFontFM.elidedText(
            summary, Qt.ElideRight, width - textInner - tagWidth - 22)
        p.drawText(left + textInner, top + itemHeight / 2, width - textInner,
                   itemHeight / 2, Qt.TextDontClip, elided_summary)
        foregroundColor.setAlpha(255)
        p.setPen(foregroundColor)

        buttonStyle = None
        if self.rowAnimator.currentRow() == index.row():
            description = index.model().data(index, DescriptionRole).toString()
            size = index.model().data(index, SizeRole).toString()
            homepage = index.model().data(index, HomepageRole).toString()
            installedVersion = str(index.model().data(
                index, InstalledVersionRole).toString())
            version = index.model().data(index, VersionRole)

            # Package Detail Label
            position = top + ROW_HEIGHT

            p.setFont(self.normalDetailFont)
            baseRect = QRect(left, position, width - 8, option.rect.height())
            rect = self.normalDetailFontFM.boundingRect(
                baseRect, Qt.TextWordWrap | Qt.TextDontClip, description)
            p.drawText(left + 2, position, width - 8, rect.height(),
                       Qt.TextWordWrap | Qt.TextDontClip, description)

            # Package Detail Homepage
            position += rect.height() + 4

            p.setFont(self.boldDetailFont)
            p.drawText(left + ICON_SIZE, position, width - textInner,
                       itemHeight / 2, Qt.AlignLeft, self._titles['website'])

            p.setFont(self.normalDetailFont)
            homepage = self.normalDetailFontFM.elidedText(
                homepage, Qt.ElideRight, width - self._titleFM['website'])
            rect = self.normalDetailFontFM.boundingRect(
                option.rect, Qt.TextSingleLine, homepage)
            self.rowAnimator.hoverLinkFilter.link_rect = QRect(
                left + self._titleFM['website'] + 2, position + 2 + 32,
                rect.width(), rect.height())

            p.setPen(option.palette.color(QPalette.Link))
            p.drawText(left + self._titleFM['website'], position, width,
                       rect.height(), Qt.TextSingleLine, homepage)
            p.setPen(foregroundColor)

            # Package Detail Version
            position += rect.height()

            p.setFont(self.boldDetailFont)
            p.drawText(left + ICON_SIZE, position, width - textInner,
                       itemHeight / 2, Qt.AlignLeft, self._titles['release'])

            p.setFont(self.normalDetailFont)
            rect = self.normalDetailFontFM.boundingRect(
                option.rect, Qt.TextWordWrap, version.toString())
            p.drawText(left + self._titleFM['release'], position, width,
                       rect.height(), Qt.TextWordWrap, version.toString())

            if not installedVersion == '':
                position += rect.height()

                p.setFont(self.boldDetailFont)
                p.drawText(left + ICON_SIZE, position, width - textInner,
                           itemHeight / 2, Qt.AlignLeft,
                           self._titles['installVers'])

                p.setFont(self.normalDetailFont)
                rect = self.normalDetailFontFM.boundingRect(
                    option.rect, Qt.TextWordWrap, installedVersion)
                p.drawText(left + self._titleFM['installVers'], position,
                           width, rect.height(), Qt.TextWordWrap,
                           installedVersion)

            # Package Detail Repository
            repository = index.model().data(index, RepositoryRole).toString()
            if not repository == '':
                repository = self.tr(
                    'Unknown') if repository == 'N/A' else repository
                position += rect.height()

                p.setFont(self.boldDetailFont)
                p.drawText(left + ICON_SIZE, position, width - textInner,
                           itemHeight / 2, Qt.AlignLeft,
                           self._titles['repository'])

                p.setFont(self.normalDetailFont)
                p.drawText(left + self._titleFM['repository'], position, width,
                           itemHeight / 2, Qt.TextWordWrap, repository)

            # Package Detail Size
            position += rect.height()

            p.setFont(self.boldDetailFont)
            p.drawText(left + ICON_SIZE, position, width - textInner,
                       itemHeight / 2, Qt.AlignLeft, self._titles['size'])

            p.setFont(self.normalDetailFont)
            p.drawText(left + self._titleFM['size'], position, width,
                       itemHeight / 2, Qt.TextWordWrap, size)
            position += rect.height()
            self.rowAnimator.max_height = position - top + 8

            # Package More info button
            opt = QStyleOptionViewItem(option)

            buttonStyle = QStyleOptionButton()
            if option.state & QStyle.State_MouseOver or option.state & QStyle.State_HasFocus:
                buttonStyle.state |= QStyle.State_HasFocus
            buttonStyle.state |= QStyle.State_Enabled
            buttonStyle.text = self.tr("Details")

            buttonStyle.rect = QRect(width - 100, position - 22, 100, 22)

        p.end()

        # FIXME
        # if option.state & QStyle.State_HasFocus and self.animatable:
        #     option.state |= QStyle.State_MouseOver
        # Use Plastique style to draw focus rect like MouseOver effect of Oxygen.
        # self.plastik.drawPrimitive(QStyle.PE_FrameLineEdit, option, painter, None)

        if not self.rowAnimator.running() and buttonStyle:
            if self.show_details_button and (installed or config.USE_APPINFO):
                PackageDelegate.AppStyle().drawControl(QStyle.CE_PushButton,
                                                       buttonStyle, painter,
                                                       None)
                self.rowAnimator.hoverLinkFilter.button_rect = QRect(
                    buttonStyle.rect)

        painter.drawPixmap(option.rect.topLeft(), pixmap)
        del pixmap

    def editorEvent(self, event, model, option, index):
        if event.type() == QEvent.MouseButtonRelease and index.column(
        ) == 0 and index.flags() & Qt.ItemIsUserCheckable:
            toggled = Qt.Checked if model.data(
                index, Qt.CheckStateRole) == QVariant(
                    Qt.Unchecked) else Qt.Unchecked
            return model.setData(index, toggled, Qt.CheckStateRole)
        __event = QItemDelegate(self).editorEvent(event, model, option, index)
        animate_requested = False
        if event.type() == QEvent.MouseButtonRelease and self.animatable:
            if self.rowAnimator.row == index.row():
                epos = event.pos()
                if self.rowAnimator.hoverLinkFilter.link_rect.contains(
                        QPoint(epos.x(),
                               epos.y() + 32)):
                    url = QUrl(model.data(index, HomepageRole).toString())
                    QDesktopServices.openUrl(url)
                    return __event
                elif self.rowAnimator.hoverLinkFilter.button_rect.contains(
                        epos, True):
                    self.showPackageDetails(model, index)
                    return __event
            animate_requested = True
        elif event.type() == QEvent.KeyPress and self.animatable:
            # KeyCode 32 : Space key
            if event.key() == 32 and index.column(
            ) == index.model().columnCount() - 1:
                animate_requested = True
        if not unicode(model.data(
                index,
                DescriptionRole).toString()) == '' and animate_requested:
            self.rowAnimator.animate(index.row())
        return __event

    def showPackageDetails(self, model, index):
        def _getter(role):
            return model.data(index, role).toString()

        name = _getter(NameRole)
        summary = _getter(SummaryRole)
        description = _getter(DescriptionRole)
        installed = model.data(index, InstalledRole).toBool()
        self.webDialog.showPackageDetails(name, installed, summary,
                                          description)

    def sizeHint(self, option, index):
        if self.rowAnimator.currentRow() == index.row(
        ) and not index.row() == 0:
            return self.rowAnimator.size()
        else:
            width = ICON_SIZE if index.column() == 0 else 0
            return QSize(width, ROW_HEIGHT)

    def setAnimatable(self, animatable):
        self.animatable = animatable

    def reset(self):
        self.rowAnimator.reset()
Example #9
0
class PackageDelegate(QtGui.QItemDelegate):
    def __init__(self, parent=None):
        QtGui.QItemDelegate.__init__(self, parent)
        self.rowAnimator = RowAnimator(parent.packageList.reset)
        icon_path = KIconLoader().iconPath(DEFAULT_ICON, KIconLoader.Panel)
        self.defaultIcon = QtGui.QIcon(
            QtGui.QPixmap(icon_path).scaled(QSize(32, 32), Qt.KeepAspectRatio))
        self.animatable = True

    def paint(self, painter, option, index):
        if not index.isValid():
            return

        opt = QtGui.QStyleOptionViewItemV4(option)
        opt.state &= ~QtGui.QStyle.State_Selected
        opt.widget.style().drawPrimitive(QtGui.QStyle.PE_PanelItemViewItem,
                                         opt, painter, None)

        if index.flags() & Qt.ItemIsUserCheckable and index.column() == 0:
            self.paintCheckBoxColumn(painter, option, index)
        else:
            self.paintInfoColumn(painter, option, index)

    def paintCheckBoxColumn(self, painter, option, index):
        opt = QtGui.QStyleOptionViewItemV4(option)

        buttonStyle = QtGui.QStyleOptionButton()
        buttonStyle.state = QtGui.QStyle.State_On if index.model().data(
            index, Qt.CheckStateRole) == QVariant(
                Qt.Checked) else QtGui.QStyle.State_Off

        if option.state & QtGui.QStyle.State_MouseOver:
            buttonStyle.state |= QtGui.QStyle.State_HasFocus

        buttonStyle.rect = opt.rect.adjusted(4, -opt.rect.height() + 64, 0, -2)
        opt.widget.style().drawControl(QtGui.QStyle.CE_CheckBox, buttonStyle,
                                       painter, None)

    def paintInfoColumn(self, painter, option, index):
        left = option.rect.left()
        top = option.rect.top()
        width = option.rect.width()

        pixmap = QtGui.QPixmap(option.rect.size())
        pixmap.fill(Qt.transparent)

        p = QtGui.QPainter(pixmap)
        p.translate(-option.rect.topLeft())

        textInner = 2 * ICON_PADDING + ROW_HEIGHT
        itemHeight = ROW_HEIGHT + 2 * ICON_PADDING

        margin = left + ICON_PADDING

        icon_path = index.model().data(index, Qt.DecorationRole).toString()
        if icon_path:
            icon = QtGui.QIcon(
                QtGui.QPixmap(icon_path).scaled(QSize(32, 32),
                                                Qt.KeepAspectRatio))
        else:
            icon = self.defaultIcon
        icon.paint(p, margin, top + ICON_PADDING, ROW_HEIGHT, ROW_HEIGHT,
                   Qt.AlignCenter)

        title = index.model().data(index, Qt.DisplayRole)
        summary = index.model().data(index, SummaryRole)
        description = index.model().data(index, DescriptionRole)
        size = index.model().data(index, SizeRole)

        foregroundColor = option.palette.color(QtGui.QPalette.Text)
        normalFont = QtGui.QFont(KGlobalSettings.generalFont().family(), 10,
                                 QtGui.QFont.Normal)
        boldFont = QtGui.QFont(KGlobalSettings.generalFont().family(), 10,
                               QtGui.QFont.Bold)
        normalDetailFont = QtGui.QFont(KGlobalSettings.generalFont().family(),
                                       9, QtGui.QFont.Normal)
        boldDetailFont = QtGui.QFont(KGlobalSettings.generalFont().family(), 9,
                                     QtGui.QFont.Bold)

        p.setPen(foregroundColor)

        # Package Name
        p.setFont(boldFont)
        p.drawText(left + textInner, top, width - textInner, itemHeight / 2,
                   Qt.AlignBottom | Qt.AlignLeft, title.toString())

        # Package Summary
        p.setFont(normalFont)
        p.drawText(left + textInner, top + itemHeight / 2, width - textInner,
                   itemHeight / 2, Qt.TextWordWrap, summary.toString())

        if self.rowAnimator.currentRow() == index.row():

            repository = index.model().data(index, RepositoryRole)
            version = index.model().data(index, VersionRole)

            # Package Detail Label
            position = top + ROW_HEIGHT

            p.setFont(boldDetailFont)
            p.drawText(left + ICON_SIZE, position, width - textInner,
                       itemHeight / 2, Qt.AlignLeft, i18n("Description:"))

            p.setFont(normalDetailFont)

            fontMetrics = QtGui.QFontMetrics(normalDetailFont)
            rect = fontMetrics.boundingRect(option.rect, Qt.TextWordWrap,
                                            description.toString())
            p.drawText(left + 2 * ROW_HEIGHT, position,
                       width - textInner - ROW_HEIGHT, rect.height(),
                       Qt.TextWordWrap, description.toString())

            # Package Detail Version
            position += rect.height()

            p.setFont(boldDetailFont)
            p.drawText(left + ICON_SIZE, position, width - textInner,
                       itemHeight / 2, Qt.AlignLeft, i18n("Release:"))

            p.setFont(normalDetailFont)
            rect = fontMetrics.boundingRect(option.rect, Qt.TextWordWrap,
                                            version.toString())
            p.drawText(left + 2 * ROW_HEIGHT, position,
                       width - textInner - ROW_HEIGHT, rect.height(),
                       Qt.TextWordWrap, version.toString())

            # Package Detail Repository
            position += rect.height()

            p.setFont(boldDetailFont)
            p.drawText(left + ICON_SIZE, position, width - textInner,
                       itemHeight / 2, Qt.AlignLeft, i18n("Repository:"))

            p.setFont(normalDetailFont)
            p.drawText(left + 2 * ROW_HEIGHT, position,
                       width - textInner - ROW_HEIGHT, itemHeight / 2,
                       Qt.TextWordWrap, repository.toString())

            # Package Detail Size
            position += rect.height()

            p.setFont(boldDetailFont)
            p.drawText(left + ICON_SIZE, position, width - textInner,
                       itemHeight / 2, Qt.AlignLeft, i18n("Package Size:"))

            p.setFont(normalDetailFont)
            p.drawText(left + 2 * ROW_HEIGHT, position,
                       width - textInner - ROW_HEIGHT, itemHeight / 2,
                       Qt.TextWordWrap, size.toString())

        p.end()
        painter.drawPixmap(option.rect.topLeft(), pixmap)

    def editorEvent(self, event, model, option, index):
        if event.type() == QEvent.MouseButtonRelease and index.column() == 0:
            toggled = Qt.Checked if model.data(
                index, Qt.CheckStateRole) == QVariant(
                    Qt.Unchecked) else Qt.Unchecked
            return model.setData(index, toggled, Qt.CheckStateRole)
        if event.type() == QEvent.MouseButtonRelease and index.column(
        ) == 1 and self.animatable:
            self.rowAnimator.animate(index.row())
        return QtGui.QItemDelegate(self).editorEvent(event, model, option,
                                                     index)

    def sizeHint(self, option, index):
        if self.rowAnimator.currentRow() == index.row():
            return self.rowAnimator.size()
        else:
            width = ICON_SIZE if index.column() == 0 else 0
            return QSize(width, ROW_HEIGHT)

    def setAnimatable(self, animatable):
        self.animatable = animatable

    def reset(self):
        self.rowAnimator.reset()
 def __init__(self, parent=None):
     QtGui.QItemDelegate.__init__(self, parent)
     self.rowAnimator = RowAnimator(parent.packageList.reset)
     icon_path = KIconLoader().iconPath(DEFAULT_ICON, KIconLoader.Panel)
     self.defaultIcon = QtGui.QIcon(QtGui.QPixmap(icon_path).scaled(QSize(32, 32), Qt.KeepAspectRatio))
     self.animatable = True
class PackageDelegate(QtGui.QItemDelegate):
    def __init__(self, parent=None):
        QtGui.QItemDelegate.__init__(self, parent)
        self.rowAnimator = RowAnimator(parent.packageList.reset)
        icon_path = KIconLoader().iconPath(DEFAULT_ICON, KIconLoader.Panel)
        self.defaultIcon = QtGui.QIcon(QtGui.QPixmap(icon_path).scaled(QSize(32, 32), Qt.KeepAspectRatio))
        self.animatable = True

    def paint(self, painter, option, index):
        if not index.isValid():
            return

        opt = QtGui.QStyleOptionViewItemV4(option)
        opt.state &= ~QtGui.QStyle.State_Selected
        opt.widget.style().drawPrimitive(QtGui.QStyle.PE_PanelItemViewItem, opt, painter, None)

        if index.flags() & Qt.ItemIsUserCheckable and index.column() == 0:
            self.paintCheckBoxColumn(painter, option, index)
        else:
            self.paintInfoColumn(painter, option, index)

    def paintCheckBoxColumn(self, painter, option, index):
        opt = QtGui.QStyleOptionViewItemV4(option)

        buttonStyle = QtGui.QStyleOptionButton()
        buttonStyle.state = QtGui.QStyle.State_On if index.model().data(index, Qt.CheckStateRole) == QVariant(Qt.Checked) else QtGui.QStyle.State_Off

        if option.state & QtGui.QStyle.State_MouseOver:
            buttonStyle.state |= QtGui.QStyle.State_HasFocus

        buttonStyle.rect = opt.rect.adjusted(4, -opt.rect.height() + 64, 0, -2)
        opt.widget.style().drawControl(QtGui.QStyle.CE_CheckBox, buttonStyle, painter, None)

    def paintInfoColumn(self, painter, option, index):
        left = option.rect.left()
        top = option.rect.top()
        width = option.rect.width()

        pixmap = QtGui.QPixmap(option.rect.size())
        pixmap.fill(Qt.transparent)

        p = QtGui.QPainter(pixmap)
        p.translate(-option.rect.topLeft())

        textInner = 2 * ICON_PADDING + ROW_HEIGHT
        itemHeight = ROW_HEIGHT + 2 * ICON_PADDING

        margin = left + ICON_PADDING

        icon_path = index.model().data(index, Qt.DecorationRole).toString()
        if icon_path:
            icon = QtGui.QIcon(QtGui.QPixmap(icon_path).scaled(QSize(32, 32), Qt.KeepAspectRatio))
        else:
            icon = self.defaultIcon
        icon.paint(p, margin, top + ICON_PADDING, ROW_HEIGHT, ROW_HEIGHT, Qt.AlignCenter)

        title = index.model().data(index, Qt.DisplayRole)
        summary = index.model().data(index, SummaryRole)
        description = index.model().data(index, DescriptionRole)
        size = index.model().data(index, SizeRole)

        foregroundColor = option.palette.color(QtGui.QPalette.Text)
        normalFont = QtGui.QFont(KGlobalSettings.generalFont().family(), 10, QtGui.QFont.Normal)
        boldFont = QtGui.QFont(KGlobalSettings.generalFont().family(), 10, QtGui.QFont.Bold)
        normalDetailFont = QtGui.QFont(KGlobalSettings.generalFont().family(), 9, QtGui.QFont.Normal)
        boldDetailFont = QtGui.QFont(KGlobalSettings.generalFont().family(), 9, QtGui.QFont.Bold)

        p.setPen(foregroundColor)

        # Package Name
        p.setFont(boldFont)
        p.drawText(left + textInner, top, width - textInner, itemHeight / 2, Qt.AlignBottom | Qt.AlignLeft, title.toString())

        # Package Summary
        p.setFont(normalFont)
        p.drawText(left + textInner, top + itemHeight / 2, width - textInner, itemHeight / 2, Qt.TextWordWrap, summary.toString())

        if self.rowAnimator.currentRow() == index.row():

            repository = index.model().data(index, RepositoryRole)
            version = index.model().data(index, VersionRole)

            # Package Detail Label
            position = top + ROW_HEIGHT

            p.setFont(boldDetailFont)
            p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, i18n("Description:"))

            p.setFont(normalDetailFont)

            fontMetrics = QtGui.QFontMetrics(normalDetailFont)
            rect = fontMetrics.boundingRect(option.rect, Qt.TextWordWrap, description.toString())
            p.drawText(left + 2 * ROW_HEIGHT, position, width - textInner - ROW_HEIGHT, rect.height(), Qt.TextWordWrap, description.toString())

            # Package Detail Version
            position += rect.height()

            p.setFont(boldDetailFont)
            p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, i18n("Release:"))

            p.setFont(normalDetailFont)
            rect = fontMetrics.boundingRect(option.rect, Qt.TextWordWrap, version.toString())
            p.drawText(left + 2 * ROW_HEIGHT, position, width - textInner - ROW_HEIGHT, rect.height(), Qt.TextWordWrap, version.toString())

            # Package Detail Repository
            position += rect.height()

            p.setFont(boldDetailFont)
            p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, i18n("Repository:"))

            p.setFont(normalDetailFont)
            p.drawText(left + 2 * ROW_HEIGHT, position, width - textInner - ROW_HEIGHT, itemHeight / 2, Qt.TextWordWrap, repository.toString())

            # Package Detail Size
            position += rect.height()

            p.setFont(boldDetailFont)
            p.drawText(left + ICON_SIZE , position, width - textInner, itemHeight / 2, Qt.AlignLeft, i18n("Package Size:"))

            p.setFont(normalDetailFont)
            p.drawText(left + 2 * ROW_HEIGHT, position, width - textInner - ROW_HEIGHT, itemHeight / 2, Qt.TextWordWrap, size.toString())

        p.end()
        painter.drawPixmap(option.rect.topLeft(), pixmap)

    def editorEvent(self, event, model, option, index):
        if event.type() == QEvent.MouseButtonRelease and index.column() == 0:
            toggled = Qt.Checked if model.data(index, Qt.CheckStateRole) == QVariant(Qt.Unchecked) else Qt.Unchecked
            return model.setData(index, toggled, Qt.CheckStateRole)
        if event.type() == QEvent.MouseButtonRelease and index.column() == 1 and self.animatable:
            self.rowAnimator.animate(index.row())
        return QtGui.QItemDelegate(self).editorEvent(event, model, option, index)

    def sizeHint(self, option, index):
        if self.rowAnimator.currentRow() == index.row():
            return self.rowAnimator.size()
        else:
            width = ICON_SIZE if index.column() == 0 else 0
            return QSize(width, ROW_HEIGHT)

    def setAnimatable(self, animatable):
        self.animatable = animatable

    def reset(self):
        self.rowAnimator.reset()
Example #12
0
class PackageDelegate(QtGui.QItemDelegate):

    AppStyle = QtGui.qApp.style

    def __init__(self, parent=None):
        QtGui.QItemDelegate.__init__(self, parent)
        self.rowAnimator = RowAnimator(parent.packageList)
        self.defaultIcon = KIcon(DEFAULT_ICON, 32)
        self.animatable = True
        self._max_height = ROW_HEIGHT

        self.types = {"critical": (RED, i18n("critical")), "security": (DARKRED, i18n("security"))}

        self.font = Pds.settings("font", "Sans").split(",")[0]

        self.normalFont = QtGui.QFont(self.font, 10, QtGui.QFont.Normal)
        self.boldFont = QtGui.QFont(self.font, 11, QtGui.QFont.Bold)
        self.normalDetailFont = QtGui.QFont(self.font, 9, QtGui.QFont.Normal)
        self.boldDetailFont = QtGui.QFont(self.font, 9, QtGui.QFont.Bold)
        self.tagFont = QtGui.QFont(self.font, 7, QtGui.QFont.Normal)

        self.tagFontFM = QtGui.QFontMetrics(self.tagFont)
        self.boldFontFM = QtGui.QFontMetrics(self.boldFont)
        self.boldDetailFontFM = QtGui.QFontMetrics(self.boldDetailFont)
        self.normalFontFM = QtGui.QFontMetrics(self.normalFont)
        self.normalDetailFontFM = QtGui.QFontMetrics(self.normalDetailFont)

        self._titles = {
            "description": i18n("Description:"),
            "website": i18n("Website:"),
            "release": i18n("Release:"),
            "repository": i18n("Repository:"),
            "size": i18n("Package Size:"),
            "installVers": i18n("Installed Version:"),
        }

        self._titleFM = {}
        for key, value in self._titles.items():
            self._titleFM[key] = self.boldDetailFontFM.width(value) + ICON_SIZE + 3

        self.baseWidth = self.boldFontFM.width(max(self._titles.values(), key=len)) + ICON_SIZE
        self.parent = parent.packageList

    def paint(self, painter, option, index):
        if not index.isValid():
            return
        if index.flags() & Qt.ItemIsUserCheckable:
            if index.column() == 0:
                self.paintCheckBoxColumn(painter, option, index)
            else:
                self.paintInfoColumn(painter, option, index)
        else:
            self.paintInfoColumn(painter, option, index, width_limit=10)

    def paintCheckBoxColumn(self, painter, option, index):
        opt = QtGui.QStyleOptionViewItemV4(option)

        buttonStyle = QtGui.QStyleOptionButton()
        buttonStyle.state = (
            QtGui.QStyle.State_On
            if index.model().data(index, Qt.CheckStateRole) == QVariant(Qt.Checked)
            else QtGui.QStyle.State_Off
        )

        if option.state & QtGui.QStyle.State_MouseOver:
            buttonStyle.state |= QtGui.QStyle.State_HasFocus

        buttonStyle.rect = opt.rect.adjusted(4, -opt.rect.height() + 54, 0, -2)
        PackageDelegate.AppStyle().drawControl(QtGui.QStyle.CE_CheckBox, buttonStyle, painter, None)

    def paintInfoColumn(self, painter, option, index, width_limit=0):
        left = option.rect.left() + 3
        top = option.rect.top()
        width = option.rect.width() - width_limit

        pixmap = QtGui.QPixmap(option.rect.size())
        pixmap.fill(Qt.transparent)

        p = QtGui.QPainter(pixmap)
        p.setRenderHint(QtGui.QPainter.Antialiasing, True)
        p.translate(-option.rect.topLeft())

        textInner = 2 * ICON_PADDING + ROW_HEIGHT - 10
        itemHeight = ROW_HEIGHT + 2 * ICON_PADDING

        margin = left + ICON_PADDING - 10

        title = index.model().data(index, Qt.DisplayRole).toString()
        summary = index.model().data(index, SummaryRole).toString()
        ptype = str(index.model().data(index, TypeRole).toString())

        icon = index.model().data(index, Qt.DecorationRole).toString()
        if icon:
            pix = KIconLoader.load(icon, forceCache=True)
            if not pix.isNull():
                icon = QtGui.QIcon(pix.scaled(QSize(32, 32), Qt.KeepAspectRatio, Qt.SmoothTransformation))
            else:
                icon = self.defaultIcon
        else:
            icon = self.defaultIcon

        icon.paint(p, margin, top + ICON_PADDING, ROW_HEIGHT, ROW_HEIGHT, Qt.AlignCenter)

        foregroundColor = option.palette.color(QtGui.QPalette.Text)
        p.setPen(foregroundColor)

        # Package Name
        p.setFont(self.boldFont)
        p.drawText(left + textInner, top, width - textInner, itemHeight / 2, Qt.AlignBottom | Qt.AlignLeft, title)

        tagWidth = 0

        if self.parent.showComponents:
            component = str(index.model().data(index, ComponentRole).toString())
            widthOfTitle = self.boldFontFM.width(title) + 6 + left + textInner

            p.setFont(self.tagFont)
            rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, component)
            p.setPen(GRAY)
            p.setBrush(GRAY)
            p.drawRoundRect(widthOfTitle, top + 12, rect.width() + 4, rect.height(), 10, 10)
            p.setPen(WHITE)
            p.drawText(widthOfTitle + 2, top + 12, rect.width(), rect.height(), Qt.AlignCenter, component)
            p.setPen(foregroundColor)

        if ptype not in ("None", "normal"):
            p.setFont(self.tagFont)
            rect = self.tagFontFM.boundingRect(option.rect, Qt.TextWordWrap, ptype)
            p.setPen(self.types[ptype][0])
            p.setBrush(self.types[ptype][0])
            p.drawRoundRect(
                width - rect.width() - 1,
                top + (itemHeight / 2) - (rect.height() / 2),
                rect.width() + 4,
                rect.height(),
                10,
                10,
            )
            p.setPen(WHITE)
            p.drawText(
                width - rect.width() + 1,
                top + (itemHeight / 2) - (rect.height() / 2),
                rect.width(),
                rect.height(),
                Qt.AlignCenter,
                self.types[ptype][1],
            )
            p.setPen(foregroundColor)
            tagWidth = rect.width()

        # Package Summary
        p.setFont(self.normalFont)
        foregroundColor.setAlpha(160)
        p.setPen(foregroundColor)
        elided_summary = self.normalFontFM.elidedText(summary, Qt.ElideRight, width - textInner - tagWidth - 22)
        p.drawText(
            left + textInner, top + itemHeight / 2, width - textInner, itemHeight / 2, Qt.TextDontClip, elided_summary
        )
        foregroundColor.setAlpha(255)
        p.setPen(foregroundColor)

        if self.rowAnimator.currentRow() == index.row():
            description = index.model().data(index, DescriptionRole).toString()
            size = index.model().data(index, SizeRole).toString()
            homepage = index.model().data(index, HomepageRole).toString()
            installedVersion = str(index.model().data(index, InstalledVersionRole).toString())
            version = index.model().data(index, VersionRole)

            # Package Detail Label
            position = top + ROW_HEIGHT

            p.setFont(self.normalDetailFont)
            baseRect = QRect(left, position, width - 8, option.rect.height())
            rect = self.normalDetailFontFM.boundingRect(baseRect, Qt.TextWordWrap | Qt.TextDontClip, description)
            p.drawText(left + 2, position, width - 8, rect.height(), Qt.TextWordWrap | Qt.TextDontClip, description)

            # Package Detail Homepage
            position += rect.height() + 4

            p.setFont(self.boldDetailFont)
            p.drawText(
                left + ICON_SIZE, position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles["website"]
            )

            p.setFont(self.normalDetailFont)
            homepage = self.normalDetailFontFM.elidedText(homepage, Qt.ElideRight, width - self._titleFM["website"])
            rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextSingleLine, homepage)
            self.rowAnimator.hoverLinkFilter.link_rect = QRect(
                left + self._titleFM["website"] + 2, position + 2, rect.width(), rect.height()
            )

            p.setPen(option.palette.color(QtGui.QPalette.Link))
            p.drawText(left + self._titleFM["website"], position, width, rect.height(), Qt.TextSingleLine, homepage)
            p.setPen(foregroundColor)

            # Package Detail Version
            position += rect.height()

            p.setFont(self.boldDetailFont)
            p.drawText(
                left + ICON_SIZE, position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles["release"]
            )

            p.setFont(self.normalDetailFont)
            rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextWordWrap, version.toString())
            p.drawText(
                left + self._titleFM["release"], position, width, rect.height(), Qt.TextWordWrap, version.toString()
            )

            if not installedVersion == "":
                position += rect.height()

                p.setFont(self.boldDetailFont)
                p.drawText(
                    left + ICON_SIZE,
                    position,
                    width - textInner,
                    itemHeight / 2,
                    Qt.AlignLeft,
                    self._titles["installVers"],
                )

                p.setFont(self.normalDetailFont)
                rect = self.normalDetailFontFM.boundingRect(option.rect, Qt.TextWordWrap, installedVersion)
                p.drawText(
                    left + self._titleFM["installVers"],
                    position,
                    width,
                    rect.height(),
                    Qt.TextWordWrap,
                    installedVersion,
                )

            # Package Detail Repository
            repository = index.model().data(index, RepositoryRole).toString()
            if not repository == "":
                position += rect.height()

                p.setFont(self.boldDetailFont)
                p.drawText(
                    left + ICON_SIZE,
                    position,
                    width - textInner,
                    itemHeight / 2,
                    Qt.AlignLeft,
                    self._titles["repository"],
                )

                p.setFont(self.normalDetailFont)
                p.drawText(
                    left + self._titleFM["repository"], position, width, itemHeight / 2, Qt.TextWordWrap, repository
                )

            # Package Detail Size
            position += rect.height()

            p.setFont(self.boldDetailFont)
            p.drawText(
                left + ICON_SIZE, position, width - textInner, itemHeight / 2, Qt.AlignLeft, self._titles["size"]
            )

            p.setFont(self.normalDetailFont)
            p.drawText(left + self._titleFM["size"], position, width, itemHeight / 2, Qt.TextWordWrap, size)
            position += rect.height()
            self.rowAnimator.max_height = position - top + 8

        p.end()
        painter.drawPixmap(option.rect.topLeft(), pixmap)

    def editorEvent(self, event, model, option, index):
        if event.type() == QEvent.MouseButtonRelease and index.column() == 0:
            toggled = Qt.Checked if model.data(index, Qt.CheckStateRole) == QVariant(Qt.Unchecked) else Qt.Unchecked
            return model.setData(index, toggled, Qt.CheckStateRole)
        __event = QtGui.QItemDelegate(self).editorEvent(event, model, option, index)
        if event.type() == QEvent.MouseButtonRelease and index.column() == 1 and self.animatable:
            if self.rowAnimator.row == index.row():
                if self.rowAnimator.hoverLinkFilter.link_rect.contains(event.pos()):
                    url = QUrl(model.data(index, HomepageRole).toString())
                    QtGui.QDesktopServices.openUrl(url)
                    return __event
            self.rowAnimator.animate(index.row())
        return __event

    def sizeHint(self, option, index):
        if self.rowAnimator.currentRow() == index.row():
            return self.rowAnimator.size()
        else:
            width = ICON_SIZE if index.column() == 0 else 0
            return QSize(width, ROW_HEIGHT)

    def setAnimatable(self, animatable):
        self.animatable = animatable

    def reset(self):
        self.rowAnimator.reset()