<commit_before>"""
    inventory
"""
from __future__ import absolute_import, division, print_function
import contextlib
import logging
from mcedit2.command import SimpleRevisionCommand
from mceditlib import nbt

from PySide import QtGui, QtCore
from PySide.QtCore import Qt
import itertools

from mcedit2.widgets.itemtype_list import ItemTypeListModel, ItemTypeIcon, ICON_SIZE
from mcedit2.widgets.layout import Row, Column
from mcedit2.widgets.nbttree.nbteditor import NBTEditorWidget


log = logging.getLogger(__name__)


class InventoryItemModel(QtCore.QAbstractItemModel):
    ItemIDRole = Qt.UserRole
    ItemRawIDRole = ItemIDRole + 1
    ItemIconRole = ItemRawIDRole + 1
    ItemDamageRole = ItemIconRole + 1
    ItemCountRole = ItemDamageRole + 1

    def __init__(self, itemListRef, editorSession):
        super(InventoryItemModel, self).__init__()
        self.editorSession = editorSession
        self.itemListRef = itemListRef
        self.textureCache = {}

    def index(self, slot, parentIndex=QtCore.QModelIndex()):
        if parentIndex.isValid():
            return QtCore.QModelIndex()
        return self.createIndex(slot, 0)

    def rowCount(self, parent):
        # slot numbers are defined by the view's slotLayout
        # maybe that should be the model's slotLayout instead
        return 0

    def data(self, index, role):
        if not index.isValid():
            return 0

        slot = index.row()
        itemStack = self.itemListRef.getItemInSlot(slot)
        if itemStack is None:
            return None
        try:
            itemType = itemStack.itemType
        except ValueError as e:  # itemType not mapped
            return None
        except KeyError as e:  # missing NBT tag?
            log.exception("Error while reading item data: %r", e)
            return None

        if role == self.ItemIconRole:
            return ItemTypeIcon(itemType, self.editorSession, itemStack)

        if role == self.ItemIDRole:
            return itemStack.id
        if role == self.ItemRawIDRole:
            return itemStack.raw_id
        if role == self.ItemCountRole:
            return itemStack.Count
        if role == self.ItemDamageRole:
            return itemStack.Damage

        return None

    def setData(self, index, value, role):
        if not index.isValid():
            return 0

        slot = index.row()
        itemStack = self.itemListRef.getItemInSlot(slot)
        if itemStack is None:
            return

        if role == self.ItemIDRole:
            itemStack.id = value
        elif role == self.ItemRawIDRole:
            itemStack.raw_id = int(value)
        elif role == self.ItemCountRole:
            itemStack.Count = value
        elif role == self.ItemDamageRole:
            itemStack.Damage = value
        else:
            return

        self.dataChanged.emit(index, index)


class InventoryItemWidget(QtGui.QPushButton):
    BLANK = None

    def __init__(self, inventoryView, slotNumber):
        super(InventoryItemWidget, self).__init__()
        self.inventoryView = inventoryView
        self.slotNumber = slotNumber
        self.countText = None

        self.setIconSize(QtCore.QSize(ICON_SIZE, ICON_SIZE))

        if InventoryItemWidget.BLANK is None:
            pm = QtGui.QPixmap(ICON_SIZE, ICON_SIZE)
            pm.fill(Qt.transparent)
            InventoryItemWidget.BLANK = QtGui.QIcon(pm)

        self.setIcon(InventoryItemWidget.BLANK)

        self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)

    def setCount(self, val):
        if val == 1:
            self.countText = None
        else:
            self.countText = str(val)

    def paintEvent(self, event):
        super(InventoryItemWidget, self).paintEvent(event)
        if self.countText is None:
            return
        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
        painter.setRenderHint(QtGui.QPainter.TextAntialiasing, True)
        font = QtGui.QFont("Arial", 12, 75)
        outlinePen = QtGui.QPen(Qt.black)
        outlinePen.setWidth(3.0)
        fillBrush = QtGui.QBrush(Qt.white)
        # painter.setFont(font)

        x, y = 0, 0
        path = QtGui.QPainterPath()
        path.addText(x, y, font, self.countText)
        rect = path.boundingRect()
        rect.moveBottomRight(QtCore.QPointF(ICON_SIZE + 3, ICON_SIZE + rect.height()))
        path.translate(rect.topLeft())

        painter.setPen(outlinePen)
        painter.drawPath(path)
        painter.setBrush(fillBrush)
        painter.setPen(None)
        painter.drawPath(path)
        # outlinePen = QtGui.QPen(color=Qt.black, width=4.0)
        # painter.strokePath(path, outlinePen)
        #painter.fillPath(path, fillBrush)


class InventoryView(QtGui.QWidget):
    def __init__(self, slotLayout, rows=None, columns=None):
        """
        slotLayout should be a list of (x, y, slotNumber) tuples.

        rows and columns are optional. Pass them if you need the grid to be larger than the slotLayout.

        :param slotLayout:
        :type slotLayout: list[tuple(int, int, int)]
        :type rows: int | None
        :type columns: int | None
        :return:
        :rtype:
        """
        super(InventoryView, self).__init__()
        self.slotWidgets = {}
        gridLayout = QtGui.QGridLayout()
        self.setLayout(gridLayout)

        # Add placeholders to stretch grid - QGridLayout has no setRow/ColumnCount
        if rows:
            gridLayout.addWidget(QtGui.QWidget(), rows-1, 0)
        if columns:
            gridLayout.addWidget(QtGui.QWidget(), 0, columns-1)


        def _makeClicked(slot):
            def _clicked():
                self.slotClicked.emit(slot)
            return _clicked

        self.slots = []
        for (x, y, slotNumber) in slotLayout:
            itemWidget = InventoryItemWidget(self, slotNumber)
            itemWidget._clicked = _makeClicked(slotNumber)
            self.slotWidgets[slotNumber] = itemWidget
            gridLayout.addWidget(itemWidget, y, x)
            itemWidget.clicked.connect(itemWidget._clicked)
            self.slots.append(slotNumber)

        self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)

        self.model = None

    slotClicked = QtCore.Signal(int)

    def setModel(self, model):
        assert isinstance(model, InventoryItemModel)
        self.model = model
        self.model.dataChanged.connect(self.dataChanged)
        self.updateItems()

    def dataChanged(self, topLeft, bottomRight):
        self.updateSlot(topLeft)

    def updateItems(self):
        for slot in self.slots:
            index = self.model.index(slot)
            self.updateSlot(index)

    def updateSlot(self, index):
        slot = index.row()
        icon = index.data(InventoryItemModel.ItemIconRole)
        slotWidget = self.slotWidgets[slot]
        if icon is not None:
            slotWidget.setIcon(icon)
        else:
            slotWidget.setIcon(InventoryItemWidget.BLANK)

        count = index.data(InventoryItemModel.ItemCountRole)
        if count is None:<commit_msg>InventoryView slot buttons now highlight when clicked<commit_after>"""
    inventory
"""
from __future__ import absolute_import, division, print_function
import contextlib
import logging
from mcedit2.command import SimpleRevisionCommand
from mceditlib import nbt

from PySide import QtGui, QtCore
from PySide.QtCore import Qt
import itertools

from mcedit2.widgets.itemtype_list import ItemTypeListModel, ItemTypeIcon, ICON_SIZE
from mcedit2.widgets.layout import Row, Column
from mcedit2.widgets.nbttree.nbteditor import NBTEditorWidget


log = logging.getLogger(__name__)


class InventoryItemModel(QtCore.QAbstractItemModel):
    ItemIDRole = Qt.UserRole
    ItemRawIDRole = ItemIDRole + 1
    ItemIconRole = ItemRawIDRole + 1
    ItemDamageRole = ItemIconRole + 1
    ItemCountRole = ItemDamageRole + 1

    def __init__(self, itemListRef, editorSession):
        super(InventoryItemModel, self).__init__()
        self.editorSession = editorSession
        self.itemListRef = itemListRef
        self.textureCache = {}

    def index(self, slot, parentIndex=QtCore.QModelIndex()):
        if parentIndex.isValid():
            return QtCore.QModelIndex()
        return self.createIndex(slot, 0)

    def rowCount(self, parent):
        # slot numbers are defined by the view's slotLayout
        # maybe that should be the model's slotLayout instead
        return 0

    def data(self, index, role):
        if not index.isValid():
            return 0

        slot = index.row()
        itemStack = self.itemListRef.getItemInSlot(slot)
        if itemStack is None:
            return None
        try:
            itemType = itemStack.itemType
        except ValueError as e:  # itemType not mapped
            return None
        except KeyError as e:  # missing NBT tag?
            log.exception("Error while reading item data: %r", e)
            return None

        if role == self.ItemIconRole:
            return ItemTypeIcon(itemType, self.editorSession, itemStack)

        if role == self.ItemIDRole:
            return itemStack.id
        if role == self.ItemRawIDRole:
            return itemStack.raw_id
        if role == self.ItemCountRole:
            return itemStack.Count
        if role == self.ItemDamageRole:
            return itemStack.Damage

        return None

    def setData(self, index, value, role):
        if not index.isValid():
            return 0

        slot = index.row()
        itemStack = self.itemListRef.getItemInSlot(slot)
        if itemStack is None:
            return

        if role == self.ItemIDRole:
            itemStack.id = value
        elif role == self.ItemRawIDRole:
            itemStack.raw_id = int(value)
        elif role == self.ItemCountRole:
            itemStack.Count = value
        elif role == self.ItemDamageRole:
            itemStack.Damage = value
        else:
            return

        self.dataChanged.emit(index, index)


class InventoryItemWidget(QtGui.QPushButton):
    BLANK = None

    def __init__(self, inventoryView, slotNumber):
        super(InventoryItemWidget, self).__init__()
        self.inventoryView = inventoryView
        self.slotNumber = slotNumber
        self.countText = None

        self.setIconSize(QtCore.QSize(ICON_SIZE, ICON_SIZE))
        self.setCheckable(True)

        if InventoryItemWidget.BLANK is None:
            pm = QtGui.QPixmap(ICON_SIZE, ICON_SIZE)
            pm.fill(Qt.transparent)
            InventoryItemWidget.BLANK = QtGui.QIcon(pm)

        self.setIcon(InventoryItemWidget.BLANK)

        self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)

    def setCount(self, val):
        if val == 1:
            self.countText = None
        else:
            self.countText = str(val)

    def paintEvent(self, event):
        super(InventoryItemWidget, self).paintEvent(event)
        if self.countText is None:
            return
        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
        painter.setRenderHint(QtGui.QPainter.TextAntialiasing, True)
        font = QtGui.QFont("Arial", 12, 75)
        outlinePen = QtGui.QPen(Qt.black)
        outlinePen.setWidth(3.0)
        fillBrush = QtGui.QBrush(Qt.white)
        # painter.setFont(font)

        x, y = 0, 0
        path = QtGui.QPainterPath()
        path.addText(x, y, font, self.countText)
        rect = path.boundingRect()
        rect.moveBottomRight(QtCore.QPointF(ICON_SIZE + 3, ICON_SIZE + rect.height()))
        path.translate(rect.topLeft())

        painter.setPen(outlinePen)
        painter.drawPath(path)
        painter.setBrush(fillBrush)
        painter.setPen(None)
        painter.drawPath(path)
        # outlinePen = QtGui.QPen(color=Qt.black, width=4.0)
        # painter.strokePath(path, outlinePen)
        #painter.fillPath(path, fillBrush)


class InventoryView(QtGui.QWidget):
    def __init__(self, slotLayout, rows=None, columns=None):
        """
        slotLayout should be a list of (x, y, slotNumber) tuples.

        rows and columns are optional. Pass them if you need the grid to be larger than the slotLayout.

        :param slotLayout:
        :type slotLayout: list[tuple(int, int, int)]
        :type rows: int | None
        :type columns: int | None
        :return:
        :rtype:
        """
        super(InventoryView, self).__init__()
        self.slotWidgets = {}
        gridLayout = QtGui.QGridLayout()
        self.setLayout(gridLayout)

        # Add placeholders to stretch grid - QGridLayout has no setRow/ColumnCount
        if rows:
            gridLayout.addWidget(QtGui.QWidget(), rows-1, 0)
        if columns:
            gridLayout.addWidget(QtGui.QWidget(), 0, columns-1)


        def _makeClicked(slot):
            def _clicked():
                self.slotClicked.emit(slot)
            return _clicked

        self.slots = []
        self.buttonGroup = QtGui.QButtonGroup()

        for (x, y, slotNumber) in slotLayout:
            itemWidget = InventoryItemWidget(self, slotNumber)
            itemWidget._clicked = _makeClicked(slotNumber)
            self.slotWidgets[slotNumber] = itemWidget
            gridLayout.addWidget(itemWidget, y, x)
            itemWidget.clicked.connect(itemWidget._clicked)
            self.slots.append(slotNumber)
            self.buttonGroup.addButton(itemWidget)

        self.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)

        self.model = None

        self.slotClicked.connect(self.slotWasClicked)

    slotClicked = QtCore.Signal(int)

    def slotWasClicked(self, slotNumber):
        self.slotWidgets[slotNumber].setChecked(True)

    def setModel(self, model):
        assert isinstance(model, InventoryItemModel)
        self.model = model
        self.model.dataChanged.connect(self.dataChanged)
        self.updateItems()

    def dataChanged(self, topLeft, bottomRight):
        self.updateSlot(topLeft)

    def updateItems(self):
        for slot in self.slots:
            index = self.model.index(slot)
            self.updateSlot(index)

    def updateSlot(self, index):
        slot = index.row()
        icon = index.data(InventoryItemModel.ItemIconRole)
        slotWidget = self.slotWidgets[slot]
        if icon is not None:
            slotWidget.setIcon(icon)
        else:
            slotWidget.setIcon(InventoryItemWidget.BLANK)

        count = index.data(InventoryItemModel.ItemCountRole)
        if count is None:
{'fraction_non_alphanumeric': 0.08639857260499588, 'fraction_numerical': 0.0038429865495470767, 'mean_word_length': 2.3378378378378377, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6253339', 'n_tokens_mistral': 4347, 'n_tokens_neox': 4211, 'n_words': 972}