Updated analyze UI
Implement all of CW's feedback/change requests, and updated the analyze UI. Next up is export buttons.
This commit is contained in:
parent
fa65763c10
commit
eed2c52b78
2
.gitignore
vendored
2
.gitignore
vendored
@ -45,3 +45,5 @@ src/mcedit2/rendering/blockmodels.c
|
||||
src/mcedit2/rendering/modelmesh.c
|
||||
*.pyd
|
||||
src/mceditlib/nbt.html
|
||||
.settings/de.loskutov.anyedit.AnyEditTools.prefs
|
||||
*.prefs
|
||||
|
@ -4,6 +4,7 @@
|
||||
from __future__ import absolute_import
|
||||
from PySide import QtGui, QtCore
|
||||
import logging
|
||||
import operator
|
||||
|
||||
from mcedit2.util.load_ui import load_ui
|
||||
|
||||
@ -16,52 +17,75 @@ class AnalyzeOutputDialog(QtGui.QDialog):
|
||||
self.blocktypes = editorSession.worldEditor.blocktypes
|
||||
|
||||
load_ui("analyze.ui", baseinstance=self)
|
||||
blockTable = self.blockOutputTable
|
||||
self.setupBlockTable(blockCount, blockTable)
|
||||
|
||||
entityTable = self.entityOutputTable
|
||||
self.setupEntityTable(entityCount, tileEntityCount, entityTable)
|
||||
|
||||
self.sizeHint()
|
||||
self.exec_()
|
||||
|
||||
|
||||
|
||||
def setupBlockTable(self, blockCount, table):
|
||||
|
||||
blockTableView = self.blockOutputTableView
|
||||
blockCounts = sorted([(self.editorSession.worldEditor.blocktypes[ i & 0xfff, i >> 12], blockCount[i])
|
||||
for i in blockCount.nonzero()[0]])
|
||||
table.setRowCount(len(blockCounts))
|
||||
table.setColumnCount(4)
|
||||
table.setHorizontalHeaderLabels(['Name', 'ID', 'Data', 'Count'])
|
||||
self.blockArrayData = [(output[0].displayName, output[0].ID,
|
||||
output[0].meta, output[1])
|
||||
for n, output in enumerate(blockCounts)]
|
||||
blockArrayHeaders = ['Name', 'ID', 'Data', 'Count']
|
||||
self.setupTable(self.blockArrayData, blockArrayHeaders, blockTableView)
|
||||
|
||||
|
||||
entityTableView = self.entityOutputTableView
|
||||
self.entityArrayData = []
|
||||
for c in entityCount, tileEntityCount:
|
||||
for (id, count) in sorted(c.items()):
|
||||
self.entityArrayData.append((id, count,))
|
||||
entityArrayHeaders = ['Name', 'Count']
|
||||
self.setupTable(self.entityArrayData, entityArrayHeaders, entityTableView)
|
||||
|
||||
|
||||
self.adjustSize()
|
||||
self.exec_()
|
||||
|
||||
def setupTable(self, arraydata, headerdata, tableView):
|
||||
tableModel = CustomTableModel(arraydata, headerdata)
|
||||
|
||||
tableView.setModel(tableModel)
|
||||
tableView.verticalHeader().setVisible(False)
|
||||
tableView.horizontalHeader().setStretchLastSection(True)
|
||||
tableView.resizeColumnsToContents()
|
||||
tableView.resizeRowsToContents()
|
||||
tableView.setSortingEnabled(True)
|
||||
|
||||
for n, output in enumerate(blockCounts):
|
||||
nameItem = QtGui.QTableWidgetItem(output[0].displayName)
|
||||
idItem = QtGui.QTableWidgetItem(str(output[0].ID))
|
||||
dataItem = QtGui.QTableWidgetItem(str(output[0].meta))
|
||||
countItem = QtGui.QTableWidgetItem(str(output[1]))
|
||||
table.setItem(n, 0, nameItem)
|
||||
table.setItem(n, 1, idItem)
|
||||
table.setItem(n, 2, dataItem)
|
||||
table.setItem(n, 3, countItem)
|
||||
|
||||
table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
|
||||
table.resizeColumnsToContents()
|
||||
table.resizeRowsToContents()
|
||||
table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||
|
||||
class CustomTableModel(QtCore.QAbstractTableModel):
|
||||
def __init__(self, arraydata, headerdata, parent=None, *args, **kwargs):
|
||||
QtCore.QAbstractTableModel.__init__(self, parent, *args, **kwargs)
|
||||
self.arraydata = arraydata
|
||||
self.headerdata = ['Name', 'ID', 'Data', 'Count']
|
||||
|
||||
def setupEntityTable(self, entityCount, tileEntityCount, table):
|
||||
table.setRowCount(len(entityCount.items())+len(tileEntityCount.items()))
|
||||
table.setColumnCount(2)
|
||||
table.setHorizontalHeaderLabels(['Name', 'Count'])
|
||||
def rowCount(self, parent):
|
||||
return len(self.arraydata)
|
||||
|
||||
def columnCount(self, parent):
|
||||
return len(self.arraydata[0])
|
||||
|
||||
def data(self, index, role):
|
||||
if not index.isValid():
|
||||
return None
|
||||
elif role != QtCore.Qt.DisplayRole:
|
||||
return None
|
||||
return str(self.arraydata[index.row()][index.column()])
|
||||
|
||||
def headerData(self, col, orientation, role):
|
||||
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
|
||||
return str(self.headerdata[col])
|
||||
return None
|
||||
|
||||
def sort(self, Ncol, order):
|
||||
"""
|
||||
Sort table by given column number.
|
||||
"""
|
||||
self.emit(QtCore.SIGNAL("layoutAboutToBeChanged()"))
|
||||
self.arraydata = sorted(self.arraydata, key=operator.itemgetter(Ncol))
|
||||
if order == QtCore.Qt.DescendingOrder:
|
||||
self.arraydata.reverse()
|
||||
self.emit(QtCore.SIGNAL("layoutChanged()"))
|
||||
|
||||
|
||||
for c in (entityCount, tileEntityCount):
|
||||
for n, (id, count) in enumerate(sorted(c.iteritems())):
|
||||
idItem = QtGui.QTableWidgetItem(str(id))
|
||||
countItem = QtGui.QTableWidgetItem(str(count))
|
||||
table.setItem(n, 0, idItem)
|
||||
table.setItem(n, 1, countItem)
|
||||
|
||||
table.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
|
||||
table.resizeColumnsToContents()
|
||||
table.resizeRowsToContents()
|
||||
table.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||
|
@ -509,11 +509,13 @@ class EditorSession(QtCore.QObject):
|
||||
self.findReplaceDialog.exec_()
|
||||
|
||||
def analyze(self):
|
||||
if self.currentSelection is None:
|
||||
return
|
||||
task = self.currentDimension.analyzeIter(self.currentSelection)
|
||||
showProgress("Analyzing...", task)
|
||||
outputDialog = AnalyzeOutputDialog(self, self.worldEditor.analyzeBlockOutput,
|
||||
self.worldEditor.analyzeEntityOutput,
|
||||
self.worldEditor.analyzeTileEntityOutput)
|
||||
outputDialog = AnalyzeOutputDialog(self, task.blocks,
|
||||
task.entityCounts,
|
||||
task.tileEntityCounts)
|
||||
|
||||
def deleteSelection(self):
|
||||
command = SimpleRevisionCommand(self, "Delete")
|
||||
|
@ -15,14 +15,90 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,2">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="blockOutputTable">
|
||||
<widget class="QLabel">
|
||||
<property name="text">
|
||||
<string>Blocks Found:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableWidget" name="entityOutputTable">
|
||||
<widget class="QTableView" name="blockOutputTableView">
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel">
|
||||
<property name="text">
|
||||
<string>Entities Found:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableView" name="entityOutputTableView">
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="txtButton">
|
||||
<property name="text">
|
||||
<string>Export txt</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="csvButton">
|
||||
<property name="text">
|
||||
<string>Export csv</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>closeButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>384</x>
|
||||
<y>175</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>20</x>
|
||||
<y>188</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
|
@ -19,13 +19,6 @@ class AnalyzeOperation(Operation):
|
||||
"""
|
||||
Analyze all blocks in a selection.
|
||||
|
||||
If blocksToReplace is given, it may be a list or tuple of blocktypes to replace with the given blocktype.
|
||||
|
||||
Additionally, blockType may be given as a list of (oldBlockType, newBlockType) pairs
|
||||
to perform multiple replacements.
|
||||
|
||||
If updateLights is True, also checks to see if block changes require lighting updates and performs them.
|
||||
|
||||
:type dimension: WorldEditorDimension
|
||||
:type selection: `~.BoundingBox`
|
||||
"""
|
||||
@ -44,9 +37,9 @@ class AnalyzeOperation(Operation):
|
||||
|
||||
def done(self):
|
||||
log.info(u"Analyze: Skipped {0}/{1} sections".format(self.skipped, self.sections))
|
||||
self.dimension.worldEditor.analyzeBlockOutput = self.blocks
|
||||
self.dimension.worldEditor.analyzeEntityOutput = self.entityCounts
|
||||
self.dimension.worldEditor.analyzeTileEntityOutput = self.tileEntityCounts
|
||||
#self.dimension.worldEditor.analyzeBlockOutput = self.blocks
|
||||
#self.dimension.worldEditor.analyzeEntityOutput = self.entityCounts
|
||||
#self.dimension.worldEditor.analyzeTileEntityOutput = self.tileEntityCounts
|
||||
|
||||
def operateOnChunk(self, chunk):
|
||||
self.chunkCount += 1
|
||||
@ -69,19 +62,22 @@ class AnalyzeOperation(Operation):
|
||||
self.skipped += 1
|
||||
continue
|
||||
|
||||
for ref in chunk.Entities:
|
||||
if ref.Position in self.selection:
|
||||
self.entityCounts[ref.rootTag["id"].value] += 1
|
||||
|
||||
for ref in chunk.TileEntities:
|
||||
if ref.Position in self.selection:
|
||||
self.tileEntityCounts[ref.rootTag["id"].value] += 1
|
||||
|
||||
|
||||
blocks = numpy.array(section.Blocks[sectionMask], dtype='uint16')
|
||||
blocks |= (numpy.array(section.Data[sectionMask], dtype='uint16') << 12)
|
||||
b = numpy.bincount(blocks.ravel())
|
||||
|
||||
self.blocks[:b.shape[0]] += b
|
||||
|
||||
for ref in chunk.Entities:
|
||||
if ref.Position in self.selection:
|
||||
self.entityCounts[ref.id] += 1
|
||||
|
||||
for ref in chunk.TileEntities:
|
||||
if ref.Position in self.selection:
|
||||
self.tileEntityCounts[ref.id] += 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -599,8 +599,6 @@ class WorldEditor(object):
|
||||
if not len(matches):
|
||||
raise ValueError("Could not parse a dimension number from %s", dimName)
|
||||
return int(matches[-1])
|
||||
|
||||
analyzeOutput = None
|
||||
|
||||
class WorldEditorDimension(object):
|
||||
def __init__(self, worldEditor, dimName):
|
||||
@ -780,9 +778,6 @@ class WorldEditorDimension(object):
|
||||
|
||||
def analyzeIter(self, selection):
|
||||
return AnalyzeOperation(self, selection)
|
||||
|
||||
def analyze(self, selection):
|
||||
return exhaust(self.analyzeIter(selection))
|
||||
|
||||
# --- Blocks by single coordinate ---
|
||||
|
||||
|
Reference in New Issue
Block a user