Beispiel #1
0
    def __configureUI(self):
        """
        @type self.__progressWindow: QProgressWindow
        """
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.progressWindow = None

        self.followIcon = QIcon()
        self.followIcon.addPixmap(QPixmap(_fromUtf8(":/shovel/icons/follow.png")), QIcon.Normal, QIcon.Off)

        self.ui.treeWidgetContainers.setColumnWidth(0, 40)
        self.ui.treeWidgetContainers.header().setResizeMode(0, QHeaderView.Fixed)
        self.ui.treeWidgetContainers.header().setResizeMode(1, QHeaderView.Stretch)
        self.ui.treeWidgetContainers.header().setStretchLastSection(False)
        self.ui.treeWidgetContainers.setRootIsDecorated(False)
        self.ui.treeWidgetContainers.setItemDelegate(ShovelUIItemDelegate(self.followIcon, columnsCount=2))

        self.ui.treeWidgetMatObjs.setColumnWidth(0, 40)
        self.ui.treeWidgetMatObjs.header().setResizeMode(0, QHeaderView.Fixed)
        self.ui.treeWidgetMatObjs.header().setResizeMode(1, QHeaderView.Stretch)
        self.ui.treeWidgetMatObjs.header().setResizeMode(2, QHeaderView.Fixed)
        self.ui.treeWidgetMatObjs.header().setStretchLastSection(False)
        self.ui.treeWidgetMatObjs.setItemDelegate(ShovelUIItemDelegate(self.followIcon, columnsCount=3))

        self.ui.treeWidgetAffixes.header().setResizeMode(0, QHeaderView.Stretch)
        self.ui.treeWidgetAffixes.header().setResizeMode(1, QHeaderView.Fixed)
        self.ui.treeWidgetAffixes.header().setStretchLastSection(False)

        self.ui.menuLoadRecent.setDisabled(True)
        self.setupRecentFilesAccess()
        self.ui.checkBoxSetupIgnoreLOD.hide()

        self.ui.statusbar.showMessage('Waiting for data to be loaded...')
Beispiel #2
0
class ShovelWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.__configureUI()
        self.__setupInitialStates()

    def __configureUI(self):
        """
        @type self.__progressWindow: QProgressWindow
        """
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.progressWindow = None

        self.followIcon = QIcon()
        self.followIcon.addPixmap(QPixmap(_fromUtf8(":/shovel/icons/follow.png")), QIcon.Normal, QIcon.Off)

        self.ui.treeWidgetContainers.setColumnWidth(0, 40)
        self.ui.treeWidgetContainers.header().setResizeMode(0, QHeaderView.Fixed)
        self.ui.treeWidgetContainers.header().setResizeMode(1, QHeaderView.Stretch)
        self.ui.treeWidgetContainers.header().setStretchLastSection(False)
        self.ui.treeWidgetContainers.setRootIsDecorated(False)
        self.ui.treeWidgetContainers.setItemDelegate(ShovelUIItemDelegate(self.followIcon, columnsCount=2))

        self.ui.treeWidgetMatObjs.setColumnWidth(0, 40)
        self.ui.treeWidgetMatObjs.header().setResizeMode(0, QHeaderView.Fixed)
        self.ui.treeWidgetMatObjs.header().setResizeMode(1, QHeaderView.Stretch)
        self.ui.treeWidgetMatObjs.header().setResizeMode(2, QHeaderView.Fixed)
        self.ui.treeWidgetMatObjs.header().setStretchLastSection(False)
        self.ui.treeWidgetMatObjs.setItemDelegate(ShovelUIItemDelegate(self.followIcon, columnsCount=3))

        self.ui.treeWidgetAffixes.header().setResizeMode(0, QHeaderView.Stretch)
        self.ui.treeWidgetAffixes.header().setResizeMode(1, QHeaderView.Fixed)
        self.ui.treeWidgetAffixes.header().setStretchLastSection(False)

        self.ui.menuLoadRecent.setDisabled(True)
        self.setupRecentFilesAccess()
        self.ui.checkBoxSetupIgnoreLOD.hide()

        self.ui.statusbar.showMessage('Waiting for data to be loaded...')

    def __setupInitialStates(self):
        self.__dataItemsReady = False
        self.__displayFullNamesForContainers = False
        self.__displayFullNamesForBatchElements = False
        self.__progressWindowState = 0
        self.__progressWindowMaxStates = 0
        self.__multiSelection = False

    def setupRecentFilesAccess(self):
        self.ui.actionLoadRecent = QAction(self)
        self.ui.actionLoadRecent.setObjectName(_fromUtf8('menuLoadRecent'))
        self.ui.actionLoadRecent.setText(QString('Load Recent'))
        self.ui.menuLoadRecent.addAction(self.ui.actionLoadRecent)

    def performFileLoad(self):
        fileExtensionFilter = '*.' + STATISTICS_FILE_EXTENSION
        statFileName = QFileDialog.getOpenFileName(QFileDialog(self), 'Open File', fileExtensionFilter,
                                                   fileExtensionFilter)
        if not statFileName:
            return
        if not processor.loadRawInputData(str(statFileName)):
            # noinspection PyArgumentList
            QMessageBox.warning(QMessageBox(self), 'Error loading file', 'Unable to parse statistics file!')
            return

        self.ui.labelOpenFileName.setText(statFileName)
        resolvedSceneName = StatisticsFileParser.resolveSceneNameFromFileName(str(statFileName))
        if resolvedSceneName:
            self.ui.labelSetupSceneName.setText(QString(resolvedSceneName))
        else:
            self.ui.labelSetupSceneName.setText(QString('<UNKNOWN>'))

        if processor.rebuildDataItems():
            self.__dataItemsReady = True
            self.updateItemsUI(DATA_ITEM_TYPES.SCENE_LAYER,
                               processor.getCurrentItemsByType(DATA_ITEM_TYPES.SCENE_LAYER))
            self.ui.statusbar.showMessage('Data is loaded.')

    def selectItems(self, itemType, itemIdx, multiIdx=False):
        """
        @type itemType: int
        """
        if itemType == DATA_ITEM_TYPES.MERGE_CONTAINER:
            assert not multiIdx
            item = self.ui.treeWidgetContainers.topLevelItem(itemIdx)
            self.ui.treeWidgetContainers.setItemSelected(item, True)
        if itemType == DATA_ITEM_TYPES.BATCHED_OBJECT:
            assert multiIdx
            for textureSetIdx, batchedObjectIdxes in processor.currentBatchedObjectItemIdxMap.iteritems():
                for batchedObjectIdx in batchedObjectIdxes:
                    item = self.ui.treeWidgetMatObjs.topLevelItem(textureSetIdx).child(batchedObjectIdx)
                    self.ui.treeWidgetMatObjs.setItemSelected(item, True)

    def clearItemsUI(self, itemType):
        """
        @type itemType: int
        """
        if itemType == DATA_ITEM_TYPES.SCENE_LAYER:
            self.ui.comboBoxSetupSceneBlockFilter.blockSignals(True)
            self.ui.comboBoxSetupSceneBlockFilter.clear()
            self.ui.comboBoxSetupSceneBlockFilter.blockSignals(False)
        if itemType == DATA_ITEM_TYPES.MERGE_CONTAINER:
            self.ui.treeWidgetContainers.blockSignals(True)
            for i in range(self.ui.treeWidgetContainers.topLevelItemCount()):
                self.ui.treeWidgetContainers.takeTopLevelItem(i)
            self.ui.treeWidgetContainers.clear()
            self.ui.treeWidgetContainers.blockSignals(False)
        elif itemType == DATA_ITEM_TYPES.TEXTURE_SET:
            self.ui.treeWidgetMatObjs.blockSignals(True)
            for i in range(self.ui.treeWidgetMatObjs.topLevelItemCount()):
                self.ui.treeWidgetMatObjs.takeTopLevelItem(i)
            self.ui.treeWidgetMatObjs.clear()
            self.ui.treeWidgetMatObjs.blockSignals(False)
        elif itemType == DATA_ITEM_TYPES.AFFIX:
            for i in range(self.ui.treeWidgetAffixes.topLevelItemCount()):
                self.ui.treeWidgetAffixes.takeTopLevelItem(i)
            self.ui.treeWidgetAffixes.clear()
        elif itemType == DATA_ITEM_TYPES.BATCH_ELEMENT:
            for i in range(self.ui.listWidgetSourceMeshes.count()):
                self.ui.listWidgetSourceMeshes.takeItem(i)
            self.ui.listWidgetSourceMeshes.clear()

    def updateItemsUI(self, itemType, items, resetCurrentState=True):
        """
        @type itemType: int
        @type items: list of GenericItem
        """
        if not self.__dataItemsReady:
            return

        if itemType == DATA_ITEM_TYPES.SCENE_LAYER:
            self.clearItemsUI(DATA_ITEM_TYPES.SCENE_LAYER)
            itemStrings = [item.getName(useFullName=False) for item in items]
            if resetCurrentState:
                processor.currentSceneLayerItemIdx = 0
            self.ui.comboBoxSetupSceneBlockFilter.addItems(itemStrings)

        elif itemType == DATA_ITEM_TYPES.MERGE_CONTAINER:
            self.clearItemsUI(DATA_ITEM_TYPES.MERGE_CONTAINER)
            if resetCurrentState:
                processor.currentMergeContainerItemIdx = 0
            for mergeContainerItem in items:
                mergeContainerItemName = mergeContainerItem.getName(useFullName=self.__displayFullNamesForContainers)
                storageCountersStr = str(mergeContainerItem.batchedObjectsCount) + ' | ' + str(mergeContainerItem.maxBatchedObjectsPerTextureSet)
                mergeContainerWidgetItem = ShovelTreeWidgetItem()
                font = QFont("", 8, QFont.Bold)
                mergeContainerWidgetItem.setFont(0, font)
                mergeContainerWidgetItem.setTextAlignment(0, Qt.AlignCenter)
                mergeContainerWidgetItem.setText(0, QString(storageCountersStr))
                mergeContainerWidgetItem.setText(1, QString(mergeContainerItemName))
                self.ui.treeWidgetContainers.addTopLevelItem(mergeContainerWidgetItem)
            self.ui.treeWidgetContainers.resizeColumnToContents(0)
            self.selectItems(DATA_ITEM_TYPES.MERGE_CONTAINER, processor.currentMergeContainerItemIdx)

        elif itemType == DATA_ITEM_TYPES.TEXTURE_SET:
            self.clearItemsUI(DATA_ITEM_TYPES.TEXTURE_SET)
            if resetCurrentState:
                processor.currentBatchedObjectItemIdxMap = {0: [0]}
            for textureSetItem in items:
                textureSetItemName = textureSetItem.getName(useFullName=False).split(':', 1)
                textureSetWidgetItem = ShovelTreeWidgetItem()
                font = QFont("", 8, QFont.Bold)
                textureSetWidgetItem.setFont(0, font)
                textureSetWidgetItem.setFont(1, font)
                textureSetWidgetItem.setText(1, QString(textureSetItemName[0]))
                textureSetWidgetItem.setText(2, QString(textureSetItemName[1]))
                textureSetWidgetItem.setFlags(Qt.ItemIsEnabled)
                self.ui.treeWidgetMatObjs.addTopLevelItem(textureSetWidgetItem)

                batchedObjectItemsCount = len(textureSetItem.batchedObjectItems)
                textureSetWidgetItem.setText(0, QString(str(batchedObjectItemsCount)))
                for batchedObjectItem in textureSetItem.batchedObjectItems:
                    batchedObjectItemName = batchedObjectItem.getName(useFullName=False)
                    batchedObjectWidgetItem = ShovelTreeWidgetItem()
                    batchedObjectWidgetItem.setText(1, QString(' matID: ' + str(batchedObjectItem.materialID) + ' | ' + batchedObjectItemName))
                    batchedObjectWidgetItem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
                    textureSetWidgetItem.addChild(batchedObjectWidgetItem)

                if batchedObjectItemsCount > 1 or textureSetItem.idx == 0:
                    textureSetWidgetItem.setExpanded(True)
            self.ui.treeWidgetMatObjs.resizeColumnToContents(2)
            self.selectItems(DATA_ITEM_TYPES.BATCHED_OBJECT, processor.currentBatchedObjectItemIdxMap, multiIdx=True)

        elif itemType == DATA_ITEM_TYPES.AFFIX:
            self.clearItemsUI(DATA_ITEM_TYPES.AFFIX)
            for affixItem in items:
                affixItemName = affixItem.getName(useFullName=False)
                affixWidgetItem = QTreeWidgetItem()
                font = QFont("", 8, QFont.Bold)
                affixWidgetItem.setFont(0, font)
                affixWidgetItem.setText(0, QString(affixItemName))
                if affixItem.isClone:
                    if affixItem.isShared:
                        affixWidgetItem.setFlags(Qt.NoItemFlags)
                    elif not affixItem.unmatchingParams:
                        affixWidgetItem.setForeground(0, QBrush(Qt.red))
                self.ui.treeWidgetAffixes.addTopLevelItem(affixWidgetItem)

                if not affixItem.affixParams:
                    continue
                for affixParamName, affixParamValue in affixItem.affixParams.iteritems():
                    affixParamWidgetItem = QTreeWidgetItem()
                    if affixItem.isClone and affixItem.unmatchingParams:
                        if affixParamName in affixItem.unmatchingParams:
                            affixParamWidgetItem.setForeground(0, QBrush(Qt.red))
                            affixParamWidgetItem.setForeground(1, QBrush(Qt.red))
                    affixParamWidgetItem.setText(0, QString(affixParamName))
                    affixParamWidgetItem.setText(1, QString('=  ' + affixParamValue))
                    affixWidgetItem.addChild(affixParamWidgetItem)
                affixWidgetItem.setExpanded(True)
            self.ui.treeWidgetAffixes.resizeColumnToContents(1)

        elif itemType == DATA_ITEM_TYPES.BATCH_ELEMENT:
            self.clearItemsUI(DATA_ITEM_TYPES.BATCH_ELEMENT)
            itemStrings = [item.getName(useFullName=self.__displayFullNamesForBatchElements) for item in items]
            for itemStr in itemStrings:
                mergeContainerWidgetItem = QListWidgetItem(self.ui.listWidgetSourceMeshes)
                mergeContainerWidgetItem.setText(itemStr)
                self.ui.listWidgetSourceMeshes.addItem(mergeContainerWidgetItem)

    def onFileLoadRequest(self):
        self.performFileLoad()

    def onSceneBlockChanged(self):
        if self.__dataItemsReady:
            processor.currentSceneLayerItemIdx = self.ui.comboBoxSetupSceneBlockFilter.currentIndex()
        self.updateItemsUI(DATA_ITEM_TYPES.MERGE_CONTAINER,
                           processor.getCurrentItemsByType(DATA_ITEM_TYPES.MERGE_CONTAINER))

    def onContainersSelectionChanged(self):
        selectedItem = self.ui.treeWidgetContainers.selectedItems()[0]
        selectedItemIndex = self.ui.treeWidgetContainers.indexOfTopLevelItem(selectedItem)
        if selectedItemIndex != processor.currentMergeContainerItemIdx:
            processor.currentMergeContainerItemIdx = selectedItemIndex
        self.updateItemsUI(DATA_ITEM_TYPES.TEXTURE_SET, processor.getCurrentItemsByType(DATA_ITEM_TYPES.TEXTURE_SET))

    def onMatObjsSelectionChanged(self):
        selectedItems = self.ui.treeWidgetMatObjs.selectedItems()
        if not selectedItems:
            self.clearItemsUI(DATA_ITEM_TYPES.AFFIX)
            self.clearItemsUI(DATA_ITEM_TYPES.BATCH_ELEMENT)
            return
        processor.currentBatchedObjectItemIdxMap = defaultdict(list)
        for selectedItem in selectedItems:
            parentItem = selectedItem.parent()
            parentItemIdx = self.ui.treeWidgetMatObjs.indexOfTopLevelItem(parentItem)
            processor.currentBatchedObjectItemIdxMap[parentItemIdx].append(parentItem.indexOfChild(selectedItem))
        self.__multiSelection = True if len(selectedItems) > 1 else False
        self.updateItemsUI(DATA_ITEM_TYPES.AFFIX, processor.getCurrentItemsByType(DATA_ITEM_TYPES.AFFIX, multiSelection=self.__multiSelection))
        self.updateItemsUI(DATA_ITEM_TYPES.BATCH_ELEMENT, processor.getCurrentItemsByType(DATA_ITEM_TYPES.BATCH_ELEMENT, multiSelection=self.__multiSelection))

    def onContainersFullNameToggle(self):
        self.__displayFullNamesForContainers = self.ui.checkBoxContainersFullName.isChecked()
        self.ui.treeWidgetContainers.blockSignals(True)
        self.updateItemsUI(DATA_ITEM_TYPES.MERGE_CONTAINER,
                           processor.getCurrentItemsByType(DATA_ITEM_TYPES.MERGE_CONTAINER), resetCurrentState=False)
        self.ui.treeWidgetContainers.blockSignals(False)

    def onSourceMeshesFullNameToggle(self):
        self.__displayFullNamesForBatchElements = self.ui.checkBoxSourceMeshesFullName.isChecked()
        self.updateItemsUI(DATA_ITEM_TYPES.BATCH_ELEMENT,
                           processor.getCurrentItemsByType(DATA_ITEM_TYPES.BATCH_ELEMENT, multiSelection=self.__multiSelection), resetCurrentState=False)

    def onIgnoreLODChildsToggle(self):
        pass

    def closeEvent(self, event):
        # reply = QMessageBox.question(QMessageBox(self), 'Exit confirmation',
        #                              "Are you sure to exit Shovel?", QMessageBox.Yes, QMessageBox.No)
        # if reply == QMessageBox.Yes:
        #     event.accept()
        # else:
        #     event.ignore()
        pass

    def showProgress(self, caption, progressLength):
        """
        @param caption: str
        @param progressLength: int
        """
        self.__progressWindowState = 0
        self.__progressWindowMaxStates = progressLength
        self.progressWindow = ShovelProgressWindow(self.tr(caption), progressLength, self)
        self.ui.statusbar.showMessage(caption)
        QCoreApplication.processEvents()

    def incrementProgressState(self):
        if not self.progressWindow:
            return
        self.__progressWindowState += 1
        self.progressWindow.setValue(self.__progressWindowState)
        QCoreApplication.processEvents()

    def finishProgress(self):
        if not self.progressWindow:
            return
        self.__progressWindowState = self.__progressWindowMaxStates
        self.progressWindow.setValue(self.__progressWindowState)
        self.ui.statusbar.showMessage('')
        QCoreApplication.processEvents()