Beispiel #1
0
    def __init__(self, element, model):
        super(ModelerGraphicItem, self).__init__(None, None)
        self.model = model
        self.element = element
        if isinstance(element, ModelerParameter):
            icon = QIcon(os.path.dirname(__file__) + '/../images/input.png')
            self.pixmap = icon.pixmap(20, 20, state=QIcon.On)
            self.text = element.param.description
        elif isinstance(element, ModelerOutput):
            # Output name
            icon = QIcon(os.path.dirname(__file__) + '/../images/output.png')
            self.pixmap = icon.pixmap(20, 20, state=QIcon.On)
            self.text = element.description
        else:
            self.text = element.description
            self.pixmap = element.algorithm.getIcon().pixmap(15, 15)
        self.arrows = []
        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
        self.setZValue(1000)

        if not isinstance(element, ModelerOutput):
            icon = QIcon(os.path.dirname(__file__) + '/../images/edit.png')
            pt = QPointF(
                ModelerGraphicItem.BOX_WIDTH / 2 -
                FlatButtonGraphicItem.WIDTH / 2,
                ModelerGraphicItem.BOX_HEIGHT / 2 -
                FlatButtonGraphicItem.HEIGHT / 2 + 1)
            self.editButton = FlatButtonGraphicItem(icon, pt, self.editElement)
            self.editButton.setParentItem(self)
            icon = QIcon(os.path.dirname(__file__) + '/../images/delete.png')
            pt = QPointF(
                ModelerGraphicItem.BOX_WIDTH / 2 -
                FlatButtonGraphicItem.WIDTH / 2,
                -ModelerGraphicItem.BOX_HEIGHT / 2 +
                FlatButtonGraphicItem.HEIGHT / 2 + 1)
            self.deleteButton = FlatButtonGraphicItem(icon, pt,
                                                      self.removeElement)
            self.deleteButton.setParentItem(self)

        if isinstance(element, Algorithm):
            alg = element.algorithm
            if alg.parameters:
                pt = self.getLinkPointForParameter(-1)
                pt = QPointF(0, pt.y() + 2)
                self.inButton = FoldButtonGraphicItem(
                    pt, self.foldInput, self.element.paramsFolded)
                self.inButton.setParentItem(self)
            if alg.outputs:
                pt = self.getLinkPointForOutput(-1)
                pt = QPointF(0, pt.y() + 2)
                self.outButton = FoldButtonGraphicItem(
                    pt, self.foldOutput, self.element.outputsFolded)
                self.outButton.setParentItem(self)
    def __init__(self, template, character, parent=None):
        super(AdvantagesWidget, self).__init__(parent)

        self.ui = Ui_AdvantagesWidget()
        self.ui.setupUi(self)

        self.__character = character
        self.__storage = template

        fontMetrics = QFontMetrics(self.font())
        textRect = fontMetrics.boundingRect("0")

        iconGeneral = QIcon(":/items/images/svg/shield.svg")
        pixmapGeneral = iconGeneral.pixmap(textRect.height(),
                                           10 * textRect.height())
        self.ui.label_armorGeneralSign.setPixmap(pixmapGeneral)
        iconFirearms = QIcon(":/items/images/svg/uzi.svg")
        pixmapFirearms = iconFirearms.pixmap(textRect.height(),
                                             10 * textRect.height())
        self.ui.label_armorFirearmsSign.setPixmap(pixmapFirearms)

        self.ui.dots_health.setReadOnly(True)

        self.ui.dots_willpower.setMaximum(Config.TRAIT_WILLPOWER_VALUE_MAX)
        self.ui.dots_willpower.setReadOnly(True)

        self.ui.dots_powerstat.setMaximum(Config.TRAIT_POWERSTAT_VALUE_MAX)
        self.ui.dots_powerstat.setMinimum(Config.TRAIT_POWERSTAT_VALUE_MIN)
        # Damit später der Wert stimmt muß ich irgendeinen Wert != 1 geben, sonst wird kein Signal gesandt.
        self.ui.dots_powerstat.setValue(9)

        self.ui.squares_fuel.columnMax = 10

        self.__character.speciesChanged.connect(self.setShapeSize)
        self.sizeChanged.connect(self.setShapeSize)
        self.__character.speciesChanged.connect(self.setShapeInitiaitve)
        self.initiativeChanged.connect(self.setShapeInitiaitve)
        self.__character.speciesChanged.connect(self.setShapeSpeed)
        self.speedChanged.connect(self.setShapeSpeed)
        self.__character.speciesChanged.connect(self.setShapeDefense)
        self.__character.traits["Attribute"]["Mental"][
            "Wits"].valueChanged.connect(self.setShapeDefense)
        self.__character.traits["Attribute"]["Physical"][
            "Dexterity"].valueChanged.connect(self.setShapeDefense)
        self.__character.speciesChanged.connect(self.setShapeHealth)
        self.healthChanged.connect(self.setShapeHealth)
        self.__character.armorChanged.connect(self.updateArmor)
        self.ui.dots_powerstat.valueChanged.connect(
            self.__character.setPowerstat)
        self.__character.powerstatChanged.connect(
            self.ui.dots_powerstat.setValue)
        self.__character.powerstatChanged.connect(self.setFuel)
        self.__character.speciesChanged.connect(self.setFuel)
        self.__character.speciesChanged.connect(self.renamePowerstatHeading)
        self.__character.speciesChanged.connect(self.hideSuper)
Beispiel #3
0
    def __init__(self, element, model):
        super(ModelerGraphicItem, self).__init__(None, None)
        self.model = model
        self.element = element
        if isinstance(element, ModelerParameter):
            icon = QIcon(os.path.join(pluginPath, 'images', 'input.png'))
            self.pixmap = icon.pixmap(20, 20, state=QIcon.On)
            self.text = element.param.description
        elif isinstance(element, ModelerOutput):
            # Output name
            icon = QIcon(os.path.join(pluginPath, 'images', 'output.png'))
            self.pixmap = icon.pixmap(20, 20, state=QIcon.On)
            self.text = element.description
        else:
            self.text = element.description
            self.pixmap = element.algorithm.getIcon().pixmap(15, 15)
        self.arrows = []
        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
        self.setZValue(1000)

        if not isinstance(element, ModelerOutput):
            icon = QIcon(os.path.join(pluginPath, 'images', 'edit.png'))
            pt = QPointF(ModelerGraphicItem.BOX_WIDTH / 2
                         - FlatButtonGraphicItem.WIDTH / 2,
                         ModelerGraphicItem.BOX_HEIGHT / 2
                         - FlatButtonGraphicItem.HEIGHT / 2 + 1)
            self.editButton = FlatButtonGraphicItem(icon, pt, self.editElement)
            self.editButton.setParentItem(self)
            icon = QIcon(os.path.join(pluginPath, 'images', 'delete.png'))
            pt = QPointF(ModelerGraphicItem.BOX_WIDTH / 2
                         - FlatButtonGraphicItem.WIDTH / 2,
                         - ModelerGraphicItem.BOX_HEIGHT / 2
                         + FlatButtonGraphicItem.HEIGHT / 2 + 1)
            self.deleteButton = FlatButtonGraphicItem(icon, pt,
                                                      self.removeElement)
            self.deleteButton.setParentItem(self)

        if isinstance(element, Algorithm):
            alg = element.algorithm
            if alg.parameters:
                pt = self.getLinkPointForParameter(-1)
                pt = QPointF(0, pt.y() + 2)
                self.inButton = FoldButtonGraphicItem(pt, self.foldInput, self.element.paramsFolded)
                self.inButton.setParentItem(self)
            if alg.outputs:
                pt = self.getLinkPointForOutput(-1)
                pt = QPointF(0, pt.y() + 2)
                self.outButton = FoldButtonGraphicItem(pt, self.foldOutput, self.element.outputsFolded)
                self.outButton.setParentItem(self)
	def __init__(self, template, character, parent=None):
		super(AdvantagesWidget, self).__init__(parent)

		self.ui = Ui_AdvantagesWidget()
		self.ui.setupUi(self)

		self.__character = character
		self.__storage = template

		fontMetrics = QFontMetrics(self.font())
		textRect = fontMetrics.boundingRect("0")

		iconGeneral = QIcon(":/items/images/svg/shield.svg")
		pixmapGeneral = iconGeneral.pixmap(textRect.height(), 10 * textRect.height())
		self.ui.label_armorGeneralSign.setPixmap(pixmapGeneral)
		iconFirearms = QIcon(":/items/images/svg/uzi.svg")
		pixmapFirearms = iconFirearms.pixmap(textRect.height(), 10 * textRect.height())
		self.ui.label_armorFirearmsSign.setPixmap(pixmapFirearms)

		self.ui.dots_health.setReadOnly( True )

		self.ui.dots_willpower.setMaximum( Config.TRAIT_WILLPOWER_VALUE_MAX )
		self.ui.dots_willpower.setReadOnly( True )

		self.ui.dots_powerstat.setMaximum( Config.TRAIT_POWERSTAT_VALUE_MAX )
		self.ui.dots_powerstat.setMinimum( Config.TRAIT_POWERSTAT_VALUE_MIN )
		# Damit später der Wert stimmt muß ich irgendeinen Wert != 1 geben, sonst wird kein Signal gesandt.
		self.ui.dots_powerstat.setValue( 9 )

		self.ui.squares_fuel.columnMax = 10

		self.__character.speciesChanged.connect(self.setShapeSize)
		self.sizeChanged.connect(self.setShapeSize)
		self.__character.speciesChanged.connect(self.setShapeInitiaitve)
		self.initiativeChanged.connect(self.setShapeInitiaitve)
		self.__character.speciesChanged.connect(self.setShapeSpeed)
		self.speedChanged.connect(self.setShapeSpeed)
		self.__character.speciesChanged.connect(self.setShapeDefense)
		self.__character.traits["Attribute"]["Mental"]["Wits"].valueChanged.connect(self.setShapeDefense)
		self.__character.traits["Attribute"]["Physical"]["Dexterity"].valueChanged.connect(self.setShapeDefense)
		self.__character.speciesChanged.connect(self.setShapeHealth)
		self.healthChanged.connect(self.setShapeHealth)
		self.__character.armorChanged.connect(self.updateArmor)
		self.ui.dots_powerstat.valueChanged.connect(self.__character.setPowerstat)
		self.__character.powerstatChanged.connect(self.ui.dots_powerstat.setValue)
		self.__character.powerstatChanged.connect(self.setFuel)
		self.__character.speciesChanged.connect(self.setFuel)
		self.__character.speciesChanged.connect(self.renamePowerstatHeading)
		self.__character.speciesChanged.connect(self.hideSuper)
Beispiel #5
0
    def __init__(self,
                 icon_path,
                 enabled=True,
                 size_multiplier=0.7,
                 tooltip=None,
                 parent=None,
                 icon_sz=(32, 32)):
        super(VmIconWidget, self).__init__(parent)

        self.label_icon = QLabel()
        if icon_path[0] in ':/':
            icon = QIcon(icon_path)
        else:
            icon = QIcon.fromTheme(icon_path)
        icon_sz = QSize(row_height * size_multiplier,
                        row_height * size_multiplier)
        icon_pixmap = icon.pixmap(
            icon_sz, QIcon.Disabled if not enabled else QIcon.Normal)
        self.label_icon.setPixmap(icon_pixmap)
        self.label_icon.setFixedSize(icon_sz)
        if tooltip != None:
            self.label_icon.setToolTip(tooltip)

        layout = QHBoxLayout()
        layout.addWidget(self.label_icon)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)
Beispiel #6
0
    def load(self, name, size=128, forceCache=False):
        icon = QIcon()
        size = int(size)
        self.pixmap = QPixmap()
        if not type(name) in (list, tuple):
            name = [str(name)]
        if forceCache or self._forceCache:
            for _name in name:
                for _size in self.iconSizes:
                    if (QPixmapCache.find('$qt' + str(_name) + str(_size),
                                          self.pixmap)):
                        logging.debug('Icon %s returned from cache' % _name)
                        return self.pixmap

        logging.debug('Getting icon : %s size: %s' % (','.join(name), size))
        pix = self.findIcon(name, size)
        if pix.isNull():
            for _size in self.iconSizes:
                pix = self.findIcon(name, _size)
                if not pix.isNull():
                    if size == _size:
                        return pix
                    icon.addPixmap(pix)
            if icon.isNull():
                return self.pixmap
            return icon.pixmap(QSize(size, size))
        return pix
Beispiel #7
0
    def load(self, name, size = 128, forceCache = False):
        icon = QIcon()
        size = int(size)
        self.pixmap = QPixmap()
        if not type(name) in (list, tuple):
            name = [str(name)]
        if forceCache or self._forceCache:
            for _name in name:
                for _size in self.iconSizes:
                    if (QPixmapCache.find('$qt'+str(_name)+str(_size),
                        self.pixmap)):
                        logging.debug('Icon %s returned from cache' % _name)
                        return self.pixmap

        logging.debug('Getting icon : %s size: %s' % (','.join(name), size))
        pix = self.findIcon(name, size)
        if pix.isNull():
            for _size in self.iconSizes:
                pix = self.findIcon(name, _size)
                if not pix.isNull():
                    if size == _size:
                        return pix
                    icon.addPixmap(pix)
            if icon.isNull():
                return self.pixmap
            return icon.pixmap(QSize(size, size))
        return pix
Beispiel #8
0
 def set_icon(self, item_type, tree_item, index = 0, label = None):
     base_path = self.controller.datahandler.app_root + "ui/icons/"
     base_type = item_type.split("/")[0]
     # item type
     if item_type == "folder":
         icon = QIcon(base_path + "folder.png")
     elif item_type == "folder_opened":
         icon = QIcon(base_path + "folder_open.png")
     elif item_type == "n900":
         icon = QIcon(base_path + "n900_small.png")
     elif item_type == "size":
         icon = QIcon(base_path + "calculator.png")
     elif item_type == "time":
         icon = QIcon(base_path + "clock.png")
     elif item_type == "deleted_item":
         icon = QIcon(base_path + "cancel.png")
     elif item_type == "deleted_folder":
         icon = QIcon(base_path + "folder_delete.png")
     # base type (from mimetype pre /)
     elif base_type == "text":
         icon = QIcon(base_path + "document_edit.png")
     elif base_type == "image":
         icon = QIcon(base_path + "picture.png")
     elif base_type == "application":
         icon = QIcon(base_path + "applications.png")
     else:
         icon = QIcon(base_path + "document.png")
     if tree_item != None:
         tree_item.setIcon(index, icon)
     elif label != None:
         label.setPixmap(icon.pixmap(24,24))        
Beispiel #9
0
 def setIcon(self, icon):
     super(RecordButton, self).setIcon(icon)
     on_icon = QIcon(icon)
     off_icon = QIcon(icon)
     for size in off_icon.availableSizes(QIcon.Normal, QIcon.On):
         pixmap = off_icon.pixmap(size, QIcon.Normal, QIcon.Off)
         off_icon.addPixmap(pixmap, QIcon.Normal, QIcon.On)
     self.animation_icons = [on_icon, off_icon]
Beispiel #10
0
 def setIcon(self, icon):
     super(RecordButton, self).setIcon(icon)
     on_icon = QIcon(icon)
     off_icon = QIcon(icon)
     for size in off_icon.availableSizes(QIcon.Normal, QIcon.On):
         pixmap = off_icon.pixmap(size, QIcon.Normal, QIcon.Off)
         off_icon.addPixmap(pixmap, QIcon.Normal, QIcon.On)
     self.animation_icons = [on_icon, off_icon]
 def __init__(self, iconName):
     if QIcon.hasThemeIcon(iconName):
         icon = QIcon.fromTheme(iconName)
     else:
         icon = QIcon(iconName)
     size = icon.availableSizes()[0]
     self.image = icon.pixmap(size).toImage().convertToFormat(QImage.Format_ARGB32)
     self.image = self.image.rgbSwapped()  # otherwise colors are weird :/
 def __init__(self, iconName):
     if QIcon.hasThemeIcon(iconName):
         icon = QIcon.fromTheme(iconName)
     else:
         icon = QIcon(iconName)
     size = icon.availableSizes()[0]
     self.image = icon.pixmap(size).toImage().convertToFormat(
         QImage.Format_ARGB32)
     self.image = self.image.rgbSwapped(
     )  # otherwise colors are weird :/
Beispiel #13
0
def symbolIcon(symbol):
    """ Icon for a symbol.

    @param symbol name of symbol
    @return QIcon instance; transparent but valid if symbol icon not found
    """
    icon = QIcon(":images/tickers/%s.png" % (symbol.lower(),))
    if icon.pixmap(16, 16).isNull():
        pixmap = QPixmap(16, 16)
        pixmap.fill(QColor(0, 0, 0, 0))
        icon = QIcon(pixmap)
    return icon
Beispiel #14
0
def symbolIcon(symbol):
    """ Icon for a symbol.

    @param symbol name of symbol
    @return QIcon instance; transparent but valid if symbol icon not found
    """
    icon = QIcon(':images/tickers/%s.png' % (symbol.lower(), ))
    if icon.pixmap(16, 16).isNull():
        pixmap = QPixmap(16, 16)
        pixmap.fill(QColor(0, 0, 0, 0))
        icon = QIcon(pixmap)
    return icon
Beispiel #15
0
def errorAlert(msgText, infoText):
    icon = QIcon(":/icon_app_error.svg")
    if msgText is None:
        msgText = "An unexpected error has occurred"
    box = QMessageBox()
    box.setText(msgText)
    box.setInformativeText(infoText)
    box.setIconPixmap(icon.pixmap(60, 60))
    box.show()
    if not len(infoText) > 300:
        box.setFixedSize(420, box.height())
    centerOnDesktop(box)
    return box.exec_()
Beispiel #16
0
def errorAlert(msgText, infoText):
    icon = QIcon(":/icon_app_error.svg")
    if msgText is None:
        msgText = "An unexpected error has occurred"
    box=QMessageBox()
    box.setText(msgText)
    box.setInformativeText(infoText)
    box.setIconPixmap(icon.pixmap(60, 60))
    box.show()
    if not len(infoText) > 300:
        box.setFixedSize(420, box.height())
    centerOnDesktop(box)
    return box.exec_()
    def set_on_icon(self):
        if self.vm.last_power_state == "Running":
            icon = QIcon (":/on.png")
        elif self.vm.last_power_state in ["Paused", "Suspended"]:
            icon = QIcon (":/paused.png")
        elif self.vm.last_power_state in ["Transient", "Halting", "Dying"]:
            icon = QIcon (":/transient.png")
        else:
            icon = QIcon (":/off.png")

        icon_sz = QSize (row_height * 0.5, row_height *0.5)
        icon_pixmap = icon.pixmap(icon_sz)
        self.setPixmap (icon_pixmap)
        self.setFixedSize (icon_sz)
Beispiel #18
0
    def set_on_icon(self):
        if self.vm.last_power_state == "Running":
            icon = QIcon(":/on.png")
        elif self.vm.last_power_state in ["Paused", "Suspended"]:
            icon = QIcon(":/paused.png")
        elif self.vm.last_power_state in ["Transient", "Halting", "Dying"]:
            icon = QIcon(":/transient.png")
        else:
            icon = QIcon(":/off.png")

        icon_sz = QSize(row_height * 0.5, row_height * 0.5)
        icon_pixmap = icon.pixmap(icon_sz)
        self.setPixmap(icon_pixmap)
        self.setFixedSize(icon_sz)
Beispiel #19
0
    def paint(self, painter, option, index):
        """ Draw a button-style on root items """
        model = index.model()
        assert model


        if not model.parent(index).isValid():
            # this is a top-level item.
            buttonOption = QStyleOptionButton()

            buttonOption.state = option.state
            buttonOption.state &= ~QStyle.State_HasFocus

            buttonOption.rect = option.rect
            buttonOption.palette = option.palette
            buttonOption.features = QStyleOptionButton.None

            self.m_view.style().drawControl(QStyle.CE_PushButton, buttonOption, painter, self.m_view)

            branchOption = QStyleOption()
            i = 15  ### hardcoded in qcommonstyle.cpp
            r = option.rect
            branchOption.rect = QRect(r.left() + i/2, r.top() + (r.height() - i)/2, i, i)
            branchOption.palette = option.palette
#            branchOption.state = QStyle.State_Children

            if self.m_view.isExpanded(index):
                branchOption.state |= QStyle.State_Open

            self.m_view.style().drawPrimitive(QStyle.PE_IndicatorBranch, branchOption, painter, self.m_view)

            # draw text
            textrect = QRect(r.left() + i*2, r.top(), r.width() - ((5*i)/2), r.height())
            text = self.elidedText(option.fontMetrics, textrect.width(), Qt.ElideMiddle,
                              model.data(index, Qt.DisplayRole).toString())
            self.m_view.style().drawItemText(painter, textrect,Qt.AlignLeft|Qt.AlignVCenter,
                                             option.palette, self.m_view.isEnabled(), text)

            icon_variant = index.data(Qt.DecorationRole)
            icon = QIcon(icon_variant)
            self.m_view.style().drawItemPixmap(
                                               painter, option.rect,
                                               Qt.AlignLeft,
                                               icon.pixmap(icon.actualSize(QSize(20 ,20)))
                                               )

        else:
            QItemDelegate.paint(self, painter, option, index)
Beispiel #20
0
 def setIcon(self, icon):
     """Sets the icon to display in the left area.
     
     May be:
     - None or QIcon()
     - one of 'info', 'warning', 'critical', 'question'
     - a QStyle.StandardPixmap
     - a QIcon.
     
     """
     if icon in standardicons:
         icon = standardicons[icon]
     if isinstance(icon, QStyle.StandardPixmap):
         icon = self.style().standardIcon(icon)
     if icon is None:
         icon = QIcon()
     self._icon = icon
     self.setPixmap(icon.pixmap(self._iconSize))
Beispiel #21
0
 def setIcon(self, icon):
     """Sets the icon to display in the left area.
     
     May be:
     - None or QIcon()
     - one of 'info', 'warning', 'critical', 'question'
     - a QStyle.StandardPixmap
     - a QIcon.
     
     """
     if icon in standardicons:
         icon = standardicons[icon]
     if isinstance(icon, QStyle.StandardPixmap):
         icon = self.style().standardIcon(icon)
     if icon is None:
         icon = QIcon()
     self._icon = icon
     self.setPixmap(icon.pixmap(self._iconSize))
Beispiel #22
0
    def on_iconSelect_clicked(self):
        """ Signal handler for select icon button.

        @return None
        """
        item = self.editItem
        if item:
            formats = str.join(' ', ['*.%s' % str(fmt) for fmt in
                                     QImageReader.supportedImageFormats()])
            filename = QFileDialog.getOpenFileName(
                self, 'Select Symbol Icon', '', 'Images (%s)' % formats)
            if filename:
                icon = QIcon(filename)
                item.setIcon(icon)
                self.iconPreview.setPixmap(icon.pixmap(32,32))
                settings = self.settings
                settings.setValue('%s/icon' % item.symbol, icon)
                self.emit(Signals.modified)
    def startDrag(self, supportedActions):
        """ Overwritten function of QTreeWidget.

        This function creates a QDrag object representing the selected element of this TreeWidget.
        """
        logging.debug(self.__class__.__name__ +": startDrag()")
        indexes = self.selectedIndexes()
        if len(indexes) > 0:
            data = self.model().mimeData(indexes)
            if not data:
                return
            drag = QDrag(self)
            drag.setMimeData(data)
            if self.model().data(indexes[0], Qt.DecorationRole).type() == QVariant.Icon:
                icon = QIcon(self.model().data(indexes[0], Qt.DecorationRole))
                drag.setPixmap(icon.pixmap(QSize(50, 50)))
                drag.setHotSpot(QPoint(drag.pixmap().width()/2, drag.pixmap().height()/2))  # center icon in respect to cursor
            defaultDropAction = Qt.IgnoreAction
            drag.exec_(supportedActions, defaultDropAction)
Beispiel #24
0
    def on_iconSelect_clicked(self):
        """ Signal handler for select icon button.

        @return None
        """
        item = self.editItem
        if item:
            formats = str.join(' ', [
                '*.%s' % str(fmt)
                for fmt in QImageReader.supportedImageFormats()
            ])
            filename = QFileDialog.getOpenFileName(self, 'Select Symbol Icon',
                                                   '', 'Images (%s)' % formats)
            if filename:
                icon = QIcon(filename)
                item.setIcon(icon)
                self.iconPreview.setPixmap(icon.pixmap(32, 32))
                settings = self.settings
                settings.setValue('%s/icon' % item.symbol, icon)
                self.emit(Signals.modified)
    def __init__(self, icon_path, enabled=True, size_multiplier=0.7,
                 tooltip  = None, parent=None, icon_sz = (32, 32)):
        super(VmIconWidget, self).__init__(parent)

        self.label_icon = QLabel()
        if icon_path[0] in ':/':
            icon = QIcon (icon_path)
        else:
            icon = QIcon.fromTheme(icon_path)
        icon_sz = QSize (row_height * size_multiplier, row_height * size_multiplier)
        icon_pixmap = icon.pixmap(icon_sz, QIcon.Disabled if not enabled else QIcon.Normal)
        self.label_icon.setPixmap (icon_pixmap)
        self.label_icon.setFixedSize (icon_sz)
        if tooltip != None:
            self.label_icon.setToolTip(tooltip)

        layout = QHBoxLayout()
        layout.addWidget(self.label_icon)
        layout.setContentsMargins(0,0,0,0)
        self.setLayout(layout)
Beispiel #26
0
 def _determineIcon(self, iconName, defaultIconName=None):
     """ Determines the icon identified by the given name. """
         
     icon = None
     if iconName in self._loadedIcons:
         icon = self._loadedIcons[iconName]
     else:
         registeredIcon = self._iconHandler.getIcon(iconName)
         if registeredIcon is None:
             icon = QIcon(_ICON_RESOURCE_PREFIX + iconName + SMALL_ICONFILENAME_SUFFIX)
         else:
             icon = QIcon(registeredIcon.smallIconLocalPath)
         if icon.isNull() and not defaultIconName is None:
             icon = QIcon(_ICON_RESOURCE_PREFIX + defaultIconName + SMALL_ICONFILENAME_SUFFIX)
         
         if icon.pixmap(1, 1).isNull():
             icon = None
         else:
             self._loadedIcons[iconName] = icon
     return icon
 def paint(self, painter, option, index):
     style = option.widget.style()
     style.drawControl(QStyle.CE_ItemViewItem, option, painter)
     artist, title = [unicode(val) for val in index.data(Qt.DisplayRole).toStringList()]
     font = QFont(index.data(Qt.FontRole))
     icon = QIcon(index.data(Qt.DecorationRole))
     painter.setFont(font)
     rect = option.rect
     rect.adjust(1, 0, -2, 0)
     iconSize = self.height - 2
     pixmap = icon.pixmap(iconSize, iconSize)
     left = rect.left() + ((iconSize - pixmap.width()) / 2)
     top = rect.top()+1 + ((iconSize - pixmap.height()) / 2)
     painter.drawPixmap(left, top, pixmap)
     rect.setLeft(rect.left() + iconSize + 2)
     if self.oneLine:
         painter.drawText(rect, Qt.AlignBottom, ' - '.join((artist, title)))
     else:
         painter.drawText(rect, Qt.AlignTop, title)
         painter.drawText(rect, Qt.AlignBottom, artist)
Beispiel #28
0
def chooseAction(parent, msgText, infoText, doAction, discardAction=None):
    icon = QIcon(":/icon_app.svg")
    box=QMessageBox(parent)
    if parent is not None:
        box.setWindowFlags(Qt.Sheet)
    box.setText(msgText)
    box.setInformativeText(infoText)
    buttons = QMessageBox.Cancel | QMessageBox.Yes
    if discardAction is not None:
        buttons |= QMessageBox.Discard
    box.setStandardButtons(buttons)
    button = box.button(QMessageBox.Yes)
    button.setText(doAction)
    if discardAction is not None:
        button = box.button(QMessageBox.Discard)
        button.setText(discardAction)
    box.setDefaultButton(QMessageBox.Yes)
    box.setIconPixmap(icon.pixmap(60, 60))
    box.show()
    centerOnDesktop(box)
    return box.exec_()
Beispiel #29
0
def chooseAction(parent, msgText, infoText, doAction, discardAction=None):
    icon = QIcon(":/icon_app.svg")
    box = QMessageBox(parent)
    if parent is not None:
        box.setWindowFlags(Qt.Sheet)
    box.setText(msgText)
    box.setInformativeText(infoText)
    buttons = QMessageBox.Cancel | QMessageBox.Yes
    if discardAction is not None:
        buttons |= QMessageBox.Discard
    box.setStandardButtons(buttons)
    button = box.button(QMessageBox.Yes)
    button.setText(doAction)
    if discardAction is not None:
        button = box.button(QMessageBox.Discard)
        button.setText(discardAction)
    box.setDefaultButton(QMessageBox.Yes)
    box.setIconPixmap(icon.pixmap(60, 60))
    box.show()
    centerOnDesktop(box)
    return box.exec_()
Beispiel #30
0
def get_icon(name, default=None, resample=False):
    """Return image inside a QIcon object
    default: default image name or icon
    resample: if True, manually resample icon pixmaps for usual sizes
    (16, 24, 32, 48, 96, 128, 256). This is recommended for QMainWindow icons 
    created from SVG images on non-Windows platforms due to a Qt bug (see 
    http://code.google.com/p/spyderlib/issues/detail?id=1314)."""
    if default is None:
        icon = QIcon(get_image_path(name))
    elif isinstance(default, QIcon):
        icon_path = get_image_path(name, default=None)
        icon = default if icon_path is None else QIcon(icon_path)
    else:
        icon = QIcon(get_image_path(name, default))
    if resample:
        icon0 = QIcon()
        for size in (16, 24, 32, 48, 96, 128, 256, 512):
            icon0.addPixmap(icon.pixmap(size, size))
        return icon0 
    else:
        return icon
Beispiel #31
0
def get_icon(name, default=None, resample=False):
    """Return image inside a QIcon object
    default: default image name or icon
    resample: if True, manually resample icon pixmaps for usual sizes
    (16, 24, 32, 48, 96, 128, 256). This is recommended for QMainWindow icons 
    created from SVG images on non-Windows platforms due to a Qt bug (see 
    http://code.google.com/p/spyderlib/issues/detail?id=1314)."""
    if default is None:
        icon = QIcon(get_image_path(name))
    elif isinstance(default, QIcon):
        icon_path = get_image_path(name, default=None)
        icon = default if icon_path is None else QIcon(icon_path)
    else:
        icon = QIcon(get_image_path(name, default))
    if resample:
        icon0 = QIcon()
        for size in (16, 24, 32, 48, 96, 128, 256, 512):
            icon0.addPixmap(icon.pixmap(size, size))
        return icon0
    else:
        return icon
 def paint(self, painter, option, index):
     self.initStyleOption(option, index);
     
     icon = QIcon( index.data(ListItemDelegate.IconRole) )
     title = index.data(ListItemDelegate.TitleRole).toString()
     description = index.data(ListItemDelegate.SubtitleRole).toString()		
     
     #widget = option.widget
     
     opt = QStyleOptionViewItemV4( option );
     self.initStyleOption(opt, index);
     if opt.widget != None:
         style = opt.widget.style()
     else:
         style = QApplication.style()
     widget = opt.widget
     
     # highlight selected items
     if opt.state & QStyle.State_Selected:  
         painter.fillRect(option.rect, option.palette.highlight());
     
     style.drawPrimitive(QStyle.PE_PanelItemViewItem, option, painter, widget)
     
     r = option.rect.adjusted(8, 10, 0, 0)
     style.drawItemPixmap(painter,r,Qt.AlignTop|Qt.AlignLeft, icon.pixmap(30,30))
     
     r = option.rect.adjusted(43, 0, 0, -25)
     f = painter.font()
     f.setWeight(QFont.Bold)
     f.setPointSize(9)
     painter.setFont(f)
     painter.setPen(QColor(0,0,0))
     style.drawItemText(painter,r,Qt.AlignBottom|Qt.AlignLeft, option.palette, True, title)
     
     r = option.rect.adjusted(43, 25, 0, 0)
     f.setWeight(QFont.Normal)
     f.setPointSize(8)
     painter.setFont(f)
     painter.setPen(QColor(90,90,90))
     style.drawItemText(painter,r,Qt.AlignTop|Qt.AlignLeft, option.palette, True, description)
Beispiel #33
0
    def _determineIcon(self, iconName, defaultIconName=None):
        """ Determines the icon identified by the given name. """

        icon = None
        if iconName in self._loadedIcons:
            icon = self._loadedIcons[iconName]
        else:
            registeredIcon = self._iconHandler.getIcon(iconName)
            if registeredIcon is None:
                icon = QIcon(_ICON_RESOURCE_PREFIX + iconName +
                             SMALL_ICONFILENAME_SUFFIX)
            else:
                icon = QIcon(registeredIcon.smallIconLocalPath)
            if icon.isNull() and not defaultIconName is None:
                icon = QIcon(_ICON_RESOURCE_PREFIX + defaultIconName +
                             SMALL_ICONFILENAME_SUFFIX)

            if icon.pixmap(1, 1).isNull():
                icon = None
            else:
                self._loadedIcons[iconName] = icon
        return icon
 def startDrag(self, supportedActions):
     """ Overwritten function of QTreeWidget.
     
     This function creates a QDrag object representing the selected element of this TreeWidget.
     """
     logging.debug(self.__class__.__name__ + ": startDrag()")
     indexes = self.selectedIndexes()
     if len(indexes) > 0:
         data = self.model().mimeData(indexes)
         if not data:
             return
         drag = QDrag(self)
         drag.setMimeData(data)
         if self.model().data(indexes[0],
                              Qt.DecorationRole).type() == QVariant.Icon:
             icon = QIcon(self.model().data(indexes[0], Qt.DecorationRole))
             drag.setPixmap(icon.pixmap(QSize(50, 50)))
             drag.setHotSpot(
                 QPoint(drag.pixmap().width() / 2,
                        drag.pixmap().height() /
                        2))  # center icon in respect to cursor
         defaultDropAction = Qt.IgnoreAction
         drag.exec_(supportedActions, defaultDropAction)
class MainWindow(QWidget):
    """
    Main window
    """
    def __init__(self,
                 pluginName='undefined',
                 pluginType='dummy',
                 debugMode=False,
                 pluginVersion='1.0.0',
                 pluginIcon=None,
                 pluginDescription='undefined',
                 showMaximized=True):
        """
        Constructor
        """
        super(MainWindow, self).__init__()

        self.debugMode = debugMode
        self.bufSdtIn = ''
        self.clientTmpPath = ''
        self.pluginName = pluginName
        self.pluginType = pluginType
        self.pluginVersion = pluginVersion
        self.pluginIcon = pluginIcon
        self.__showMaximized = showMaximized
        self.isRegistered = False

        if self.pluginIcon is None: self.pluginIcon = QIcon(':/plugin.png')
        self.pluginDescription = pluginDescription

        self.mainPage = None
        self.settingsPage = None
        self.TAB_MAIN_PAGE = None
        self.TAB_SETTINGS_PAGE = None

        if not self.debugMode:
            # connect sdtin
            self.stdClient = ReadStdin(self)
            self.stdClient.DataIn.connect(self.on_stdinReadyRead)
            self.stdClient.start()

            self.aliveClient = ClientAlive(self)
            self.aliveClient.ClientDead.connect(self.onClientDead)
            self.aliveClient.start()

        self.createWidgets()

    def configure(self,
                  pluginName='undefined',
                  pluginType='dummy',
                  pluginVersion='1.0.0',
                  pluginIcon=None,
                  pluginDescription='undefined',
                  showMaximized=True):
        """
        """
        self.pluginName = pluginName
        self.pluginType = pluginType
        self.pluginVersion = pluginVersion
        self.pluginIcon = pluginIcon
        self.pluginDescription = pluginDescription
        self.__showMaximized = showMaximized
        if self.pluginIcon is None: self.pluginIcon = QIcon(':/plugin.png')
        self.setWindowTitle("%s - %s - %s" %
                            (Settings.instance().readValue(key='Common/name'),
                             self.pluginName, self.pluginVersion))

        # register the plugin
        if not self.debugMode: self.sendMessage(cmd='register')

    def prepare(self):
        """
        """
        Logger.instance().debug("preparing plugin")

        # convert qicon to base64
        pixmapIcon = self.pluginIcon.pixmap(64,
                                            64,
                                            mode=QIcon.Normal,
                                            state=QIcon.Off)

        byteArray = QByteArray()
        buffer = QBuffer(byteArray)
        buffer.open(QIODevice.WriteOnly)
        pixmapIcon.save(buffer, "png", quality=100)

        iconBase64 = byteArray.toBase64().data()

        Logger.instance().debug("icon converted to base64")

        self.sendMessage(cmd='configure',
                         data=str(iconBase64, 'utf8'),
                         more={"description": self.pluginDescription})

    def createWidgets(self):
        """
        Create all widgets
        """
        self.setWindowIcon(QIcon(':/plugin.png'))

        self.mainTab = QTabWidget()

        self.aboutPage = AboutPage(parent=self)
        self.debugPage = DebugPage(parent=self)

        self.mainTab.addTab(self.aboutPage, "About")
        self.mainTab.addTab(self.debugPage, "Debug")

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.mainTab)
        self.setLayout(mainLayout)

        self.setWindowTitle("%s - %s - %s" %
                            (Settings.instance().readValue(key='Common/name'),
                             self.pluginName, self.pluginVersion))

        flags = Qt.WindowFlags()
        if not self.debugMode: flags |= Qt.WindowStaysOnTopHint
        self.setWindowFlags(flags)

    def debug(self):
        """
        Return debug page
        """
        return self.debugPage

    def about(self):
        """
        Return about page
        """
        return self.aboutPage

    def main(self):
        """
        Return main page
        """
        return self.mainPage

    def settings(self):
        """
        Return about page
        """
        return self.settingsPage

    def closeEvent(self, event):
        """
        On window close event
        """
        if not self.debugMode:
            self.hide()
            event.ignore()

    def addMainPage(self, pageName, widget):
        """
        Add the main page to the tabwidget
        """
        self.mainPage = widget
        if self.settingsPage is not None:
            self.settingsPage.ReloadSettings.connect(
                self.mainPage.onReloadSettings)
        self.mainTab.addTab(widget, pageName)
        self.TAB_MAIN_PAGE = self.mainTab.indexOf(widget)

    def addSettingsPage(self, widget):
        """
        Add the settings page to the tabwidget
        """
        self.settingsPage = widget
        self.mainTab.addTab(widget, "Settings")
        self.TAB_SETTINGS_PAGE = self.mainTab.indexOf(widget)

    def updateAboutPage(self, text):
        """
        Update the about text
        """
        self.aboutPage.updateAbout(text=text)

    def onClientDead(self):
        """"
        On client terminattion, no more keepalive received from the client
        """
        self.stdClient.terminate()
        self.stdClient.wait()

        self.aliveClient.terminate()
        self.aliveClient.wait()

        QApplication.quit()

    def on_stdinReadyRead(self, data):
        """
        On data in  STD in
        """
        try:
            self.bufSdtIn += data

            pdus = self.bufSdtIn.split("\n\n")
            for pdu in pdus[:-1]:
                try:
                    datagramDecoded = base64.b64decode(pdu)
                    if sys.version_info > (3, ):  # python 3 support
                        messageJson = json.loads(str(datagramDecoded, "utf8"))
                    else:
                        messageJson = json.loads(datagramDecoded)
                except Exception as e:
                    self.debugPage.addLogError(txt="decode: %s" % e)
                else:
                    self.onPluginMessage(msg=messageJson)
            self.bufSdtIn = pdus[-1]
        except Exception as e:
            self.debugPage.addLogError(txt=e)

    def onPluginMessage(self, msg):
        """
        On message received from the client
        """
        try:
            if not self.isRegistered and msg['cmd'] == 'registered':
                Logger.instance().debug("plugin registered")
                self.clientTmpPath = msg['tmp-path']
                self.debugPage.addLogSuccess(
                    txt="plugin registered [Type=%s]" % self.pluginType)
                self.isRegistered = True
                self.prepare()

            elif msg['cmd'] == 'keepalive':
                self.aliveClient.lastTimestamp = time.time()
                Logger.instance().debug("keepalive received")

            elif msg['cmd'] == 'run':
                data = None

                #read data
                if msg['in-data']:
                    # read the file
                    f = open("%s/%s" % (self.clientTmpPath, msg['data-id']),
                             'r')
                    all = f.read()
                    f.close()

                    dataJson = json.loads(all)

                    # delete them
                    os.remove("%s/%s" % (self.clientTmpPath, msg['data-id']))

                self.__onPluginRun(data=dataJson)

            elif msg['cmd'] == 'open-main':
                if self.mainPage is None:
                    return

                if self.TAB_MAIN_PAGE is not None:
                    self.mainTab.setCurrentIndex(self.TAB_MAIN_PAGE)

                self.__showWindows()

                if msg['in-data']:
                    # read the file
                    f = open("%s/%s" % (self.clientTmpPath, msg['data-id']),
                             'r')
                    all = f.read()
                    f.close()

                    dataJson = json.loads(all)

                    self.mainPage.insertData(data=dataJson)

                    # delete them
                    os.remove("%s/%s" % (self.clientTmpPath, msg['data-id']))

            else:
                pass
        except Exception as e:
            self.debugPage.addLogError(txt="error: %s" % e)
            self.mainTab.setCurrentIndex(TAB_DEBUG_PAGE)

            self.__showWindows()

    def __showWindows(self):
        """"
        """
        if self.__showMaximized:
            self.showMaximized()
        else:
            self.show()

    def __onPluginRun(self, data):
        """
        Function to reimplement
        """
        try:
            self.onPluginRun(data=data)
            self.sendMessage(cmd="success")
        except Exception as e:
            self.sendMessage(cmd="error", more={"msg": "%s" % e})

    def onPluginRun(self, data):
        """
        """
        pass

    def sendMessage(self, cmd, data='', more={}):
        """
        Send a message to the client
        """
        inData = False
        msg = {'cmd': cmd}

        # save data to temp area
        idFile = ''

        if len(data):
            try:
                idFile = "%s" % uuid.uuid4()
                pluginDataFile = '%s/%s' % (self.clientTmpPath, idFile)
                with open(pluginDataFile, mode='w') as myfile:
                    myfile.write(json.dumps(data))
                inData = True
            except Exception as e:
                print("unable to write data file from plugin: %s" % e)
                Logger.instance().error(
                    "unable to write data file from plugin: %s" % e)
                self.debug().addLogError("internal error on send message")

        msg.update({'in-data': inData})

        # add data parameters
        if inData: msg.update({'data-id': idFile})

        # add more params
        msg.update(more)

        # adding reference
        msg.update({
            'id': self.pluginName,
            'name': self.pluginName,
            'type': self.pluginType
        })
        Logger.instance().debug("%s" % msg)

        # encode message and send to stdout
        datagram = json.dumps(msg)

        datagramEncoded = base64.b64encode(bytes(datagram, "utf8"))
        print(str(datagramEncoded, "utf8"))
        sys.stdout.flush()
class GraphicsIconItem(QGraphicsItem):
    """
    A graphics item displaying an :class:`QIcon`.
    """
    def __init__(self, parent=None, icon=None, iconSize=None, **kwargs):
        QGraphicsItem.__init__(self, parent, **kwargs)
        self.setFlag(QGraphicsItem.ItemUsesExtendedStyleOption, True)

        if icon is None:
            icon = QIcon()

        if iconSize is None:
            style = QApplication.instance().style()
            size = style.pixelMetric(style.PM_LargeIconSize)
            iconSize = QSize(size, size)

        self.__transformationMode = Qt.SmoothTransformation

        self.__iconSize = QSize(iconSize)
        self.__icon = QIcon(icon)

    def setIcon(self, icon):
        """
        Set the icon (:class:`QIcon`).
        """
        if self.__icon != icon:
            self.__icon = QIcon(icon)
            self.update()

    def icon(self):
        """
        Return the icon (:class:`QIcon`).
        """
        return QIcon(self.__icon)

    def setIconSize(self, size):
        """
        Set the icon (and this item's) size (:class:`QSize`).
        """
        if self.__iconSize != size:
            self.prepareGeometryChange()
            self.__iconSize = QSize(size)
            self.update()

    def iconSize(self):
        """
        Return the icon size (:class:`QSize`).
        """
        return QSize(self.__iconSize)

    def setTransformationMode(self, mode):
        """
        Set pixmap transformation mode. (`Qt.SmoothTransformation` or
        `Qt.FastTransformation`).

        """
        if self.__transformationMode != mode:
            self.__transformationMode = mode
            self.update()

    def transformationMode(self):
        """
        Return the pixmap transformation mode.
        """
        return self.__transformationMode

    def boundingRect(self):
        return QRectF(0, 0, self.__iconSize.width(), self.__iconSize.height())

    def paint(self, painter, option, widget=None):
        if not self.__icon.isNull():
            if option.state & QStyle.State_Selected:
                mode = QIcon.Selected
            elif option.state & QStyle.State_Enabled:
                mode = QIcon.Normal
            elif option.state & QStyle.State_Active:
                mode = QIcon.Active
            else:
                mode = QIcon.Disabled

            transform = self.sceneTransform()

            if widget is not None:
                # 'widget' is the QGraphicsView.viewport()
                view = widget.parent()
                if isinstance(view, QGraphicsView):
                    # Combine the scene transform with the view transform.
                    view_transform = view.transform()
                    transform = view_transform * view_transform

            lod = option.levelOfDetailFromTransform(transform)

            w, h = self.__iconSize.width(), self.__iconSize.height()
            target = QRectF(0, 0, w, h)
            source = QRectF(0, 0, w * lod, w * lod).toRect()

            # The actual size of the requested pixmap can be smaller.
            size = self.__icon.actualSize(source.size(), mode=mode)
            source.setSize(size)

            pixmap = self.__icon.pixmap(source.size(), mode=mode)

            painter.setRenderHint(
                QPainter.SmoothPixmapTransform,
                self.__transformationMode == Qt.SmoothTransformation
            )

            painter.drawPixmap(target, pixmap, QRectF(source))
Beispiel #37
0
class CanvasView(QGraphicsView):
    """Canvas View handles the zooming.
    """
    def __init__(self, *args):
        QGraphicsView.__init__(self, *args)
        self.setAlignment(Qt.AlignTop | Qt.AlignLeft)

        self.__backgroundIcon = QIcon()

        self.__autoScroll = False
        self.__autoScrollMargin = 16
        self.__autoScrollTimer = QTimer(self)
        self.__autoScrollTimer.timeout.connect(self.__autoScrollAdvance)

    def setScene(self, scene):
        QGraphicsView.setScene(self, scene)
        self._ensureSceneRect(scene)

    def _ensureSceneRect(self, scene):
        r = scene.addRect(QRectF(0, 0, 400, 400))
        scene.sceneRect()
        scene.removeItem(r)

    def setAutoScrollMargin(self, margin):
        self.__autoScrollMargin = margin

    def autoScrollMargin(self):
        return self.__autoScrollMargin

    def setAutoScroll(self, enable):
        self.__autoScroll = enable

    def autoScroll(self):
        return self.__autoScroll

    def mousePressEvent(self, event):
        QGraphicsView.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            if not self.__autoScrollTimer.isActive() and \
                    self.__shouldAutoScroll(event.pos()):
                self.__startAutoScroll()

        QGraphicsView.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        if event.button() & Qt.LeftButton:
            self.__stopAutoScroll()

        return QGraphicsView.mouseReleaseEvent(self, event)

    def __shouldAutoScroll(self, pos):
        if self.__autoScroll:
            margin = self.__autoScrollMargin
            viewrect = self.contentsRect()
            rect = viewrect.adjusted(margin, margin, -margin, -margin)
            # only do auto scroll when on the viewport's margins
            return not rect.contains(pos) and viewrect.contains(pos)
        else:
            return False

    def __startAutoScroll(self):
        self.__autoScrollTimer.start(10)
        log.debug("Auto scroll timer started")

    def __stopAutoScroll(self):
        if self.__autoScrollTimer.isActive():
            self.__autoScrollTimer.stop()
            log.debug("Auto scroll timer stopped")

    def __autoScrollAdvance(self):
        """Advance the auto scroll
        """
        pos = QCursor.pos()
        pos = self.mapFromGlobal(pos)
        margin = self.__autoScrollMargin

        vvalue = self.verticalScrollBar().value()
        hvalue = self.horizontalScrollBar().value()

        vrect = QRect(0, 0, self.width(), self.height())

        # What should be the speed
        advance = 10

        # We only do auto scroll if the mouse is inside the view.
        if vrect.contains(pos):
            if pos.x() < vrect.left() + margin:
                self.horizontalScrollBar().setValue(hvalue - advance)
            if pos.y() < vrect.top() + margin:
                self.verticalScrollBar().setValue(vvalue - advance)
            if pos.x() > vrect.right() - margin:
                self.horizontalScrollBar().setValue(hvalue + advance)
            if pos.y() > vrect.bottom() - margin:
                self.verticalScrollBar().setValue(vvalue + advance)

            if self.verticalScrollBar().value() == vvalue and \
                    self.horizontalScrollBar().value() == hvalue:
                self.__stopAutoScroll()
        else:
            self.__stopAutoScroll()

        log.debug("Auto scroll advance")

    def setBackgroundIcon(self, icon):
        if not isinstance(icon, QIcon):
            raise TypeError("A QIcon expected.")

        if self.__backgroundIcon != icon:
            self.__backgroundIcon = icon
            self.viewport().update()

    def backgroundIcon(self):
        return QIcon(self.__backgroundIcon)

    def drawBackground(self, painter, rect):
        QGraphicsView.drawBackground(self, painter, rect)

        if not self.__backgroundIcon.isNull():
            painter.setClipRect(rect)
            vrect = QRect(QPoint(0, 0), self.viewport().size())
            vrect = self.mapToScene(vrect).boundingRect()

            pm = self.__backgroundIcon.pixmap(vrect.size().toSize().boundedTo(
                QSize(200, 200)))
            pmrect = QRect(QPoint(0, 0), pm.size())
            pmrect.moveCenter(vrect.center().toPoint())
            if rect.toRect().intersects(pmrect):
                painter.drawPixmap(pmrect, pm)
Beispiel #38
0
class GraphicsIconItem(QGraphicsItem):
    """
    A graphics item displaying an :class:`QIcon`.
    """
    def __init__(self, parent=None, icon=None, iconSize=None, **kwargs):
        QGraphicsItem.__init__(self, parent, **kwargs)
        self.setFlag(QGraphicsItem.ItemUsesExtendedStyleOption, True)

        if icon is None:
            icon = QIcon()

        if iconSize is None:
            style = QApplication.instance().style()
            size = style.pixelMetric(style.PM_LargeIconSize)
            iconSize = QSize(size, size)

        self.__transformationMode = Qt.SmoothTransformation

        self.__iconSize = QSize(iconSize)
        self.__icon = QIcon(icon)

    def setIcon(self, icon):
        """
        Set the icon (:class:`QIcon`).
        """
        if self.__icon != icon:
            self.__icon = QIcon(icon)
            self.update()

    def icon(self):
        """
        Return the icon (:class:`QIcon`).
        """
        return QIcon(self.__icon)

    def setIconSize(self, size):
        """
        Set the icon (and this item's) size (:class:`QSize`).
        """
        if self.__iconSize != size:
            self.prepareGeometryChange()
            self.__iconSize = QSize(size)
            self.update()

    def iconSize(self):
        """
        Return the icon size (:class:`QSize`).
        """
        return QSize(self.__iconSize)

    def setTransformationMode(self, mode):
        """
        Set pixmap transformation mode. (`Qt.SmoothTransformation` or
        `Qt.FastTransformation`).

        """
        if self.__transformationMode != mode:
            self.__transformationMode = mode
            self.update()

    def transformationMode(self):
        """
        Return the pixmap transformation mode.
        """
        return self.__transformationMode

    def boundingRect(self):
        return QRectF(0, 0, self.__iconSize.width(), self.__iconSize.height())

    def paint(self, painter, option, widget=None):
        if not self.__icon.isNull():
            if option.state & QStyle.State_Selected:
                mode = QIcon.Selected
            elif option.state & QStyle.State_Enabled:
                mode = QIcon.Normal
            elif option.state & QStyle.State_Active:
                mode = QIcon.Active
            else:
                mode = QIcon.Disabled

            transform = self.sceneTransform()

            if widget is not None:
                # 'widget' is the QGraphicsView.viewport()
                view = widget.parent()
                if isinstance(view, QGraphicsView):
                    # Combine the scene transform with the view transform.
                    view_transform = view.transform()
                    transform = view_transform * view_transform

            lod = option.levelOfDetailFromTransform(transform)

            w, h = self.__iconSize.width(), self.__iconSize.height()
            target = QRectF(0, 0, w, h)
            source = QRectF(0, 0, w * lod, w * lod).toRect()

            # The actual size of the requested pixmap can be smaller.
            size = self.__icon.actualSize(source.size(), mode=mode)
            source.setSize(size)

            pixmap = self.__icon.pixmap(source.size(), mode=mode)

            painter.setRenderHint(
                QPainter.SmoothPixmapTransform,
                self.__transformationMode == Qt.SmoothTransformation)

            painter.drawPixmap(target, pixmap, QRectF(source))
Beispiel #39
0
class Dialog(QDialog):
    """A Dialog with basic layout features:
    
    a main widget,
    an icon or pixmap,
    a separator,
    buttons (provided by a QDialogButtonBox)
    
    """
    def __init__(self,
                 parent=None,
                 message="",
                 title="",
                 icon=None,
                 iconSize=QSize(64, 64),
                 pixmap=None,
                 separator=True,
                 buttonOrientation=Qt.Horizontal,
                 buttons=('ok', 'cancel'),
                 help=None,
                 **kwargs):
        """Initializes the dialog.
        
        parent = a parent widget or None.
        
        The following keyword arguments are recognized:
        - message: the text to display in the message label
        - title: the window title
        - icon or pixmap: shown in the left area
        - iconSize: size of the icon in the left (QSize, default: 64x64)
        - separator: draw a separator line or not (default: True)
        - buttonOrientation: Qt.Horizontal (default) or Qt.Vertical
        - buttons: which buttons to use (default: Ok, Cancel)
        - help: function to call when a help button is clicked.
        
        Other keyword arguments are passed to QDialog.
        
        """
        super(Dialog, self).__init__(parent, **kwargs)
        self._icon = QIcon()
        self._separatorWidget = Separator()
        self._mainWidget = QWidget()
        self._pixmap = QPixmap()
        self._pixmapLabel = QLabel(self)
        self._messageLabel = QLabel(self)
        self._buttonBox = b = QDialogButtonBox(self)
        b.accepted.connect(self.accept)
        b.rejected.connect(self.reject)
        layout = QGridLayout()
        layout.setSpacing(10)
        self.setLayout(layout)

        # handle keyword args
        self._buttonOrientation = buttonOrientation
        self._iconSize = iconSize
        self._separator = separator
        if title:
            self.setWindowTitle(title)
        self.setMessage(message)
        if icon:
            self.setIcon(icon)
        elif pixmap:
            self.setPixmap(pixmap)
        b.helpRequested.connect(help or self.helpRequest)
        self.setStandardButtons(buttons)
        self.reLayout()

    def helpRequest(self):
        """Called when a help button is clicked."""
        pass

    def setButtonOrientation(self, orientation):
        """Sets the button orientation.
        
        Qt.Horizontal (default) puts the buttons at the bottom of the dialog
        in a horizonzal row, Qt.Vertical puts the buttons at the right in a
        vertical column.
        
        """
        if orientation != self._buttonOrientation:
            self._buttonOrientation = orientation
            self._buttonBox.setOrientation(orientation)
            self.reLayout()

    def buttonOrientation(self):
        """Returns the button orientation."""
        return self._buttonOrientation

    def setIcon(self, icon):
        """Sets the icon to display in the left area.
        
        May be:
        - None or QIcon()
        - one of 'info', 'warning', 'critical', 'question'
        - a QStyle.StandardPixmap
        - a QIcon.
        
        """
        if icon in standardicons:
            icon = standardicons[icon]
        if isinstance(icon, QStyle.StandardPixmap):
            icon = self.style().standardIcon(icon)
        if icon is None:
            icon = QIcon()
        self._icon = icon
        self.setPixmap(icon.pixmap(self._iconSize))

    def icon(self):
        """Returns the currently set icon as a QIcon."""
        return self._icon

    def setIconSize(self, size):
        """Sets the icon size (QSize or int)."""
        if isinstance(size, int):
            size = QSize(size, size)
        changed = size != self._iconSize
        self._iconSize = size
        if changed and not self._icon.isNull():
            self.setPixmap(self._icon.pixmap(size))

    def iconSize(self):
        """Returns the icon size (QSize)."""
        return self._iconSize

    def setPixmap(self, pixmap):
        """Sets the pixmap to display in the left area."""
        changed = self._pixmap.isNull() != pixmap.isNull()
        self._pixmap = pixmap
        self._pixmapLabel.setPixmap(pixmap)
        if not pixmap.isNull():
            self._pixmapLabel.setFixedSize(pixmap.size())
        if changed:
            self.reLayout()

    def pixmap(self):
        """Returns the currently set pixmap."""
        return self._pixmap

    def setMessage(self, text):
        """Sets the main text in the dialog."""
        self._messageLabel.setText(text)

    def message(self):
        """Returns the main text."""
        return self._messageLabel.text()

    def messageLabel(self):
        """Returns the QLabel displaying the message text."""
        return self._messageLabel

    def buttonBox(self):
        """Returns our QDialogButtonBox instance."""
        return self._buttonBox

    def setStandardButtons(self, buttons):
        """Convenience method to set standard buttons in the button box.
        
        Accepts a sequence of string names from the standardbuttons constant,
        or a QDialogButtonBox.StandardButtons value.
        
        """
        if isinstance(buttons, (set, tuple, list)):
            buttons = functools.reduce(operator.or_,
                                       map(standardbuttons.get, buttons),
                                       QDialogButtonBox.StandardButtons())
        self._buttonBox.setStandardButtons(buttons)

    def button(self, button):
        """Returns the given button.
        
        May be a QDialogButtonBox.StandardButton or a key from standardbuttons.
        
        """
        if button in standardbuttons:
            button = standardbuttons[button]
        return self._buttonBox.button(button)

    def setSeparator(self, enabled):
        """Sets whether to show a line between contents and buttons."""
        changed = self._separator != enabled
        self._separator = enabled
        if changed:
            self.reLayout()

    def hasSeparator(self):
        """Returns whether a separator line is shown."""
        return self._separator

    def setMainWidget(self, widget):
        """Sets the specified widget as our main widget."""
        old = self._mainWidget
        if old:
            old.setParent(None)
        self._mainWidget = widget
        self.reLayout()

    def mainWidget(self):
        """Returns the current main widget (an empty QWidget by default)."""
        return self._mainWidget

    def reLayout(self):
        """(Internal) Lays out all items in this dialog."""
        layout = self.layout()
        while layout.takeAt(0):
            pass

        if not self._pixmap.isNull():
            col = 1
            layout.addWidget(self._pixmapLabel, 0, 0, 2, 1)
        else:
            layout.setColumnStretch(1, 0)
            col = 0
        layout.setColumnStretch(col, 1)
        self._pixmapLabel.setVisible(not self._pixmap.isNull())
        layout.addWidget(self._messageLabel, 0, col)
        layout.addWidget(self._mainWidget, 1, col)
        if self._buttonOrientation == Qt.Horizontal:
            if self._separator:
                layout.addWidget(self._separatorWidget, 2, 0, 1, col + 1)
            layout.addWidget(self._buttonBox, 3, 0, 1, col + 1)
        else:
            if self._separator:
                layout.addWidget(self._separatorWidget, 0, col + 1, 2, 1)
            layout.addWidget(self._buttonBox, 0, col + 2, 2, 1)
        self._separatorWidget.setVisible(self._separator)
Beispiel #40
0
class MessageWidget(QWidget):
    """
    A widget displaying a simple message to the user.

    This is an alternative to a full QMessageBox intended for inline
    modeless messages.

    [[icon] {Message text} (Ok) (Cancel)]
    """
    #: Emitted when a button with the AcceptRole is clicked
    accepted = Signal()
    #: Emitted when a button with the RejectRole is clicked
    rejected = Signal()
    #: Emitted when a button with the HelpRole is clicked
    helpRequested = Signal()
    #: Emitted when a button is clicked
    clicked = Signal(QAbstractButton)

    class StandardButton(enum.IntEnum):
        NoButton, Ok, Close, Help = 0x0, 0x1, 0x2, 0x4
    NoButton, Ok, Close, Help = list(StandardButton)

    class ButtonRole(enum.IntEnum):
        InvalidRole, AcceptRole, RejectRole, HelpRole = 0, 1, 2, 3

    InvalidRole, AcceptRole, RejectRole, HelpRole = list(ButtonRole)

    _Button = namedtuple("_Button", ["button", "role", "stdbutton"])

    def __init__(self, parent=None, icon=QIcon(), text="", wordWrap=False,
                 textFormat=Qt.AutoText, standardButtons=NoButton, **kwargs):
        super().__init__(parent, **kwargs)
        self.__text = text
        self.__icon = QIcon()
        self.__wordWrap = wordWrap
        self.__standardButtons = MessageWidget.NoButton
        self.__buttons = []

        layout = QHBoxLayout()
        layout.setContentsMargins(8, 0, 8, 0)

        self.__iconlabel = QLabel(objectName="icon-label")
        self.__iconlabel.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.__textlabel = QLabel(objectName="text-label", text=text,
                                  wordWrap=wordWrap, textFormat=textFormat)

        if sys.platform == "darwin":
            self.__textlabel.setAttribute(Qt.WA_MacSmallSize)

        layout.addWidget(self.__iconlabel)
        layout.addWidget(self.__textlabel)

        self.setLayout(layout)
        self.setIcon(icon)
        self.setStandardButtons(standardButtons)

    def setText(self, text):
        """
        Set the current message text.

        :type message: str
        """
        if self.__text != text:
            self.__text = text
            self.__textlabel.setText(text)

    def text(self):
        """
        Return the current message text.

        :rtype: str
        """
        return self.__text

    def setIcon(self, icon):
        """
        Set the message icon.

        :type icon: QIcon | QPixmap | QString | QStyle.StandardPixmap
        """
        if isinstance(icon, QStyle.StandardPixmap):
            icon = self.style().standardIcon(icon)
        else:
            icon = QIcon(icon)

        if self.__icon != icon:
            self.__icon = QIcon(icon)
            if not self.__icon.isNull():
                size = self.style().pixelMetric(
                    QStyle.PM_SmallIconSize, None, self)
                pm = self.__icon.pixmap(QSize(size, size))
            else:
                pm = QPixmap()

            self.__iconlabel.setPixmap(pm)
            self.__iconlabel.setVisible(not pm.isNull())

    def icon(self):
        """
        Return the current icon.

        :rtype: QIcon
        """
        return QIcon(self.__icon)

    def setWordWrap(self, wordWrap):
        """
        Set the message text wrap property

        :type wordWrap: bool
        """
        if self.__wordWrap != wordWrap:
            self.__wordWrap = wordWrap
            self.__textlabel.setWordWrap(wordWrap)

    def wordWrap(self):
        """
        Return the message text wrap property.

        :rtype: bool
        """
        return self.__wordWrap

    def setTextFormat(self, textFormat):
        """
        Set message text format

        :type textFormat: Qt.TextFormat
        """
        self.__textlabel.setTextFormat(textFormat)

    def textFormat(self):
        """
        Return the message text format.

        :rtype: Qt.TextFormat
        """
        return self.__textlabel.textFormat()

    def changeEvent(self, event):
        # reimplemented
        if event.type() == 177:  # QEvent.MacSizeChange:
            ...
        super().changeEvent(event)

    def setStandardButtons(self, buttons):
        for button in MessageWidget.StandardButton:
            existing = self.button(button)
            if button & buttons and existing is None:
                self.addButton(button)
            elif existing is not None:
                self.removeButton(existing)

    def standardButtons(self):
        return functools.reduce(
            operator.ior,
            (slot.stdbutton for slot in self.__buttons
             if slot.stdbutton is not None),
            MessageWidget.NoButton)

    def addButton(self, button, *rolearg):
        """
        addButton(QAbstractButton, ButtonRole)
        addButton(str, ButtonRole)
        addButton(StandardButton)

        Add and return a button
        """
        stdbutton = None
        if isinstance(button, QAbstractButton):
            if len(rolearg) != 1:
                raise TypeError("Wrong number of arguments for "
                                "addButton(QAbstractButton, role)")
            role = rolearg[0]
        elif isinstance(button, MessageWidget.StandardButton):
            if len(rolearg) != 0:
                raise TypeError("Wrong number of arguments for "
                                "addButton(StandardButton)")
            stdbutton = button
            if button == MessageWidget.Ok:
                role = MessageWidget.AcceptRole
                button = QPushButton("Ok", default=False, autoDefault=False)
            elif button == MessageWidget.Close:
                role = MessageWidget.RejectRole
#                 button = QPushButton(
#                     default=False, autoDefault=False, flat=True,
#                     icon=QIcon(self.style().standardIcon(
#                                QStyle.SP_TitleBarCloseButton)))
                button = SimpleButton(
                    icon=QIcon(self.style().standardIcon(
                               QStyle.SP_TitleBarCloseButton)))
            elif button == MessageWidget.Help:
                role = MessageWidget.HelpRole
                button = QPushButton("Help", default=False, autoDefault=False)
        elif isinstance(button, str):
            if len(rolearg) != 1:
                raise TypeError("Wrong number of arguments for "
                                "addButton(str, ButtonRole)")
            role = rolearg[0]
            button = QPushButton(button, default=False, autoDefault=False)

        if sys.platform == "darwin":
            button.setAttribute(Qt.WA_MacSmallSize)
        self.__buttons.append(MessageWidget._Button(button, role, stdbutton))
        button.clicked.connect(self.__button_clicked)
        self.__relayout()

        return button

    def removeButton(self, button):
        """
        Remove a `button`.

        :type button: QAbstractButton
        """
        slot = [s for s in self.__buttons if s.button is button]
        if slot:
            slot = slot[0]
            self.__buttons.remove(slot)
            self.layout().removeWidget(slot.button)
            slot.button.setParent(None)

    def buttonRole(self, button):
        """
        Return the ButtonRole for button

        :type button: QAbsstractButton
        """
        for slot in self.__buttons:
            if slot.button is button:
                return slot.role
        else:
            return MessageWidget.InvalidRole

    def button(self, standardButton):
        """
        Return the button for the StandardButton.

        :type standardButton: StandardButton
        """
        for slot in self.__buttons:
            if slot.stdbutton == standardButton:
                return slot.button
        else:
            return None

    def __button_clicked(self):
        button = self.sender()
        role = self.buttonRole(button)
        self.clicked.emit(button)

        if role == MessageWidget.AcceptRole:
            self.accepted.emit()
            self.close()
        elif role == MessageWidget.RejectRole:
            self.rejected.emit()
            self.close()
        elif role == MessageWidget.HelpRole:
            self.helpRequested.emit()

    def __relayout(self):
        for slot in self.__buttons:
            self.layout().removeWidget(slot.button)
        order = {
            MessageOverlayWidget.HelpRole: 0,
            MessageOverlayWidget.AcceptRole: 2,
            MessageOverlayWidget.RejectRole: 3,
        }
        orderd = sorted(self.__buttons,
                        key=lambda slot: order.get(slot.role, -1))

        prev = self.__textlabel
        for slot in orderd:
            self.layout().addWidget(slot.button)
            QWidget.setTabOrder(prev, slot.button)
Beispiel #41
0
class CanvasView(QGraphicsView):
    """Canvas View handles the zooming.
    """

    def __init__(self, *args):
        QGraphicsView.__init__(self, *args)
        self.setAlignment(Qt.AlignTop | Qt.AlignLeft)

        self.__backgroundIcon = QIcon()

        self.__autoScroll = False
        self.__autoScrollMargin = 16
        self.__autoScrollTimer = QTimer(self)
        self.__autoScrollTimer.timeout.connect(self.__autoScrollAdvance)

    def setScene(self, scene):
        QGraphicsView.setScene(self, scene)
        self._ensureSceneRect(scene)

    def _ensureSceneRect(self, scene):
        r = scene.addRect(QRectF(0, 0, 400, 400))
        scene.sceneRect()
        scene.removeItem(r)

    def setAutoScrollMargin(self, margin):
        self.__autoScrollMargin = margin

    def autoScrollMargin(self):
        return self.__autoScrollMargin

    def setAutoScroll(self, enable):
        self.__autoScroll = enable

    def autoScroll(self):
        return self.__autoScroll

    def mousePressEvent(self, event):
        QGraphicsView.mousePressEvent(self, event)

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            if not self.__autoScrollTimer.isActive() and \
                    self.__shouldAutoScroll(event.pos()):
                self.__startAutoScroll()

        QGraphicsView.mouseMoveEvent(self, event)

    def mouseReleaseEvent(self, event):
        if event.button() & Qt.LeftButton:
            self.__stopAutoScroll()

        return QGraphicsView.mouseReleaseEvent(self, event)

    def __shouldAutoScroll(self, pos):
        if self.__autoScroll:
            margin = self.__autoScrollMargin
            viewrect = self.contentsRect()
            rect = viewrect.adjusted(margin, margin, -margin, -margin)
            # only do auto scroll when on the viewport's margins
            return not rect.contains(pos) and viewrect.contains(pos)
        else:
            return False

    def __startAutoScroll(self):
        self.__autoScrollTimer.start(10)
        log.debug("Auto scroll timer started")

    def __stopAutoScroll(self):
        if self.__autoScrollTimer.isActive():
            self.__autoScrollTimer.stop()
            log.debug("Auto scroll timer stopped")

    def __autoScrollAdvance(self):
        """Advance the auto scroll
        """
        pos = QCursor.pos()
        pos = self.mapFromGlobal(pos)
        margin = self.__autoScrollMargin

        vvalue = self.verticalScrollBar().value()
        hvalue = self.horizontalScrollBar().value()

        vrect = QRect(0, 0, self.width(), self.height())

        # What should be the speed
        advance = 10

        # We only do auto scroll if the mouse is inside the view.
        if vrect.contains(pos):
            if pos.x() < vrect.left() + margin:
                self.horizontalScrollBar().setValue(hvalue - advance)
            if pos.y() < vrect.top() + margin:
                self.verticalScrollBar().setValue(vvalue - advance)
            if pos.x() > vrect.right() - margin:
                self.horizontalScrollBar().setValue(hvalue + advance)
            if pos.y() > vrect.bottom() - margin:
                self.verticalScrollBar().setValue(vvalue + advance)

            if self.verticalScrollBar().value() == vvalue and \
                    self.horizontalScrollBar().value() == hvalue:
                self.__stopAutoScroll()
        else:
            self.__stopAutoScroll()

        log.debug("Auto scroll advance")

    def setBackgroundIcon(self, icon):
        if not isinstance(icon, QIcon):
            raise TypeError("A QIcon expected.")

        if self.__backgroundIcon != icon:
            self.__backgroundIcon = icon
            self.viewport().update()

    def backgroundIcon(self):
        return QIcon(self.__backgroundIcon)

    def drawBackground(self, painter, rect):
        QGraphicsView.drawBackground(self, painter, rect)

        if not self.__backgroundIcon.isNull():
            painter.setClipRect(rect)
            vrect = QRect(QPoint(0, 0), self.viewport().size())
            vrect = self.mapToScene(vrect).boundingRect()

            pm = self.__backgroundIcon.pixmap(
                vrect.size().toSize().boundedTo(QSize(200, 200))
            )
            pmrect = QRect(QPoint(0, 0), pm.size())
            pmrect.moveCenter(vrect.center().toPoint())
            if rect.toRect().intersects(pmrect):
                painter.drawPixmap(pmrect, pm)
Beispiel #42
0
class Dialog(QDialog):
    """A Dialog with basic layout features:
    
    a main widget,
    an icon or pixmap,
    a separator,
    buttons (provided by a QDialogButtonBox)
    
    """
    def __init__(self,
                 parent = None,
                 message = "",
                 title = "",
                 icon = None,
                 iconSize = QSize(64, 64),
                 pixmap = None,
                 separator = True,
                 buttonOrientation = Qt.Horizontal,
                 buttons = ('ok', 'cancel'),
                 help = None,
                 **kwargs):
        """Initializes the dialog.
        
        parent = a parent widget or None.
        
        The following keyword arguments are recognized:
        - message: the text to display in the message label
        - title: the window title
        - icon or pixmap: shown in the left area
        - iconSize: size of the icon in the left (QSize, default: 64x64)
        - separator: draw a separator line or not (default: True)
        - buttonOrientation: Qt.Horizontal (default) or Qt.Vertical
        - buttons: which buttons to use (default: Ok, Cancel)
        - help: function to call when a help button is clicked.
        
        Other keyword arguments are passed to QDialog.
        
        """
        super(Dialog, self).__init__(parent, **kwargs)
        self._icon = QIcon()
        self._separatorWidget = Separator()
        self._mainWidget = QWidget()
        self._pixmap = QPixmap()
        self._pixmapLabel = QLabel(self)
        self._messageLabel = QLabel(self)
        self._buttonBox = b = QDialogButtonBox(self)
        b.accepted.connect(self.accept)
        b.rejected.connect(self.reject)
        layout = QGridLayout()
        layout.setSpacing(10)
        self.setLayout(layout)
        
        # handle keyword args
        self._buttonOrientation = buttonOrientation
        self._iconSize = iconSize
        self._separator = separator
        if title:
            self.setWindowTitle(title)
        self.setMessage(message)
        if icon:
            self.setIcon(icon)
        elif pixmap:
            self.setPixmap(pixmap)
        b.helpRequested.connect(help or self.helpRequest)
        self.setStandardButtons(buttons)
        self.reLayout()
        
    def helpRequest(self):
        """Called when a help button is clicked."""
        pass
    
    def setButtonOrientation(self, orientation):
        """Sets the button orientation.
        
        Qt.Horizontal (default) puts the buttons at the bottom of the dialog
        in a horizontal row, Qt.Vertical puts the buttons at the right in a
        vertical column.
        
        """
        if orientation != self._buttonOrientation:
            self._buttonOrientation = orientation
            self._buttonBox.setOrientation(orientation)
            self.reLayout()
    
    def buttonOrientation(self):
        """Returns the button orientation."""
        return self._buttonOrientation
        
    def setIcon(self, icon):
        """Sets the icon to display in the left area.
        
        May be:
        - None or QIcon()
        - one of 'info', 'warning', 'critical', 'question'
        - a QStyle.StandardPixmap
        - a QIcon.
        
        """
        if icon in standardicons:
            icon = standardicons[icon]
        if isinstance(icon, QStyle.StandardPixmap):
            icon = self.style().standardIcon(icon)
        if icon is None:
            icon = QIcon()
        self._icon = icon
        self.setPixmap(icon.pixmap(self._iconSize))
    
    def icon(self):
        """Returns the currently set icon as a QIcon."""
        return self._icon
        
    def setIconSize(self, size):
        """Sets the icon size (QSize or int)."""
        if isinstance(size, int):
            size = QSize(size, size)
        changed = size != self._iconSize
        self._iconSize = size
        if changed and not self._icon.isNull():
            self.setPixmap(self._icon.pixmap(size))
    
    def iconSize(self):
        """Returns the icon size (QSize)."""
        return self._iconSize
        
    def setPixmap(self, pixmap):
        """Sets the pixmap to display in the left area."""
        changed = self._pixmap.isNull() != pixmap.isNull()
        self._pixmap = pixmap
        self._pixmapLabel.setPixmap(pixmap)
        if not pixmap.isNull():
            self._pixmapLabel.setFixedSize(pixmap.size())
        if changed:
            self.reLayout()
        
    def pixmap(self):
        """Returns the currently set pixmap."""
        return self._pixmap
    
    def setMessage(self, text):
        """Sets the main text in the dialog."""
        self._messageLabel.setText(text)
    
    def message(self):
        """Returns the main text."""
        return self._messageLabel.text()
    
    def messageLabel(self):
        """Returns the QLabel displaying the message text."""
        return self._messageLabel
        
    def buttonBox(self):
        """Returns our QDialogButtonBox instance."""
        return self._buttonBox
    
    def setStandardButtons(self, buttons):
        """Convenience method to set standard buttons in the button box.
        
        Accepts a sequence of string names from the standardbuttons constant,
        or a QDialogButtonBox.StandardButtons value.
        
        """
        if isinstance(buttons, (set, tuple, list)):
            buttons = functools.reduce(operator.or_,
                map(standardbuttons.get, buttons),
                QDialogButtonBox.StandardButtons())
        self._buttonBox.setStandardButtons(buttons)
    
    def button(self, button):
        """Returns the given button.
        
        May be a QDialogButtonBox.StandardButton or a key from standardbuttons.
        
        """
        if button in standardbuttons:
            button = standardbuttons[button]
        return self._buttonBox.button(button)
    
    def setSeparator(self, enabled):
        """Sets whether to show a line between contents and buttons."""
        changed = self._separator != enabled
        self._separator = enabled
        if changed:
            self.reLayout()
    
    def hasSeparator(self):
        """Returns whether a separator line is shown."""
        return self._separator
        
    def setMainWidget(self, widget):
        """Sets the specified widget as our main widget."""
        old = self._mainWidget
        if old:
            old.setParent(None)
        self._mainWidget = widget
        self.reLayout()
    
    def mainWidget(self):
        """Returns the current main widget (an empty QWidget by default)."""
        return self._mainWidget
    
    def reLayout(self):
        """(Internal) Lays out all items in this dialog."""
        layout = self.layout()
        while layout.takeAt(0):
            pass
        
        if not self._pixmap.isNull():
            col = 1
            layout.addWidget(self._pixmapLabel, 0, 0, 2, 1)
        else:
            layout.setColumnStretch(1, 0)
            col = 0
        layout.setColumnStretch(col, 1)
        self._pixmapLabel.setVisible(not self._pixmap.isNull())    
        layout.addWidget(self._messageLabel, 0, col)
        layout.addWidget(self._mainWidget, 1, col)
        if self._buttonOrientation == Qt.Horizontal:
            if self._separator:
                layout.addWidget(self._separatorWidget, 2, 0, 1, col+1)
            layout.addWidget(self._buttonBox, 3, 0, 1, col+1)
        else:
            if self._separator:
                layout.addWidget(self._separatorWidget, 0, col+1, 2, 1)
            layout.addWidget(self._buttonBox, 0, col+2, 2, 1)
        self._separatorWidget.setVisible(self._separator)