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:
Rubisk 2015-05-12 13:16:38 +02:00
parent fa65763c10
commit eed2c52b78
6 changed files with 164 additions and 69 deletions

2
.gitignore vendored
View File

@ -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

View File

@ -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)

View File

@ -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")

View File

@ -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>

View File

@ -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

View File

@ -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 ---