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...')
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()