NBT editor can add/remove from lists, displays root item as root instead of its children

NBTTreeView -> NBTEditorWidget
editor is a QWidget again
added add/remove buttons
expands first column when child is expanded
removed vertical borders from tree views
items have isCompound and isList
This commit is contained in:
David Vierra 2015-02-01 03:32:38 -10:00
parent 19a8c01f4f
commit e07cc96ae5
7 changed files with 117 additions and 82 deletions

View File

@ -126,15 +126,15 @@ class ChunkTool(EditorTool):
def updateNBTView(self):
chunk = self.currentChunk
if chunk is None:
self.toolWidget.nbtTreeView.setModel(None)
self.toolWidget.nbtEditor.setModel(None)
return
model = NBTTreeModel(chunk.rootTag)
self.toolWidget.nbtTreeView.setModel(model)
self.toolWidget.nbtTreeView.expandToDepth(0)
self.toolWidget.nbtTreeView.resizeColumnToContents(0)
self.toolWidget.nbtTreeView.resizeColumnToContents(1)
self.toolWidget.nbtEditor.setModel(model)
# self.toolWidget.nbtEditor.expandToDepth(0)
# self.toolWidget.nbtEditor.resizeColumnToContents(0)
# self.toolWidget.nbtEditor.resizeColumnToContents(1)
self.toolWidget.cxSpinBox.setValue(chunk.cx)
self.toolWidget.czSpinBox.setValue(chunk.cz)

View File

@ -10,12 +10,11 @@ from PySide.QtCore import Qt
from mcedit2.command import SimpleRevisionCommand
from mcedit2.util.screen import centerWidgetInScreen
from mcedit2.widgets.nbttree.nbttreemodel import NBTTreeModel, NBTTreeList
from mcedit2.widgets.nbttree.nbttreemodel import NBTTreeModel
from mcedit2.util.load_ui import load_ui
from mcedit2.util.resources import resourcePath
from mcedit2.widgets.propertylist import PropertyListModel
from mceditlib.exceptions import PlayerNotFound
from mceditlib import nbt
log = logging.getLogger(__name__)
@ -112,17 +111,17 @@ class PlayerPanel(QtGui.QWidget):
def updateNBTTree(self):
model = NBTTreeModel(self.selectedPlayer.rootTag)
model.dataChanged.connect(self.nbtDataDidChange)
self.treeView.setModel(model)
self.nbtEditor.setModel(model)
def revisionDidChange(self):
self.initPropertiesWidget()
self.updateNBTTree()
def nbtDataDidChange(self, index):
model = self.treeView.model().sourceModel() # xxx filter model this is confusing
model = self.nbtEditor.model
parent = model.parent(index)
item = model.getItem(index)
if parent is not None and isinstance(parent, NBTTreeList):
if parent is not None and parent.isList:
name = str(parent.tag.index(item.tag))
else:
name = item.tag.name
@ -170,7 +169,7 @@ class PlayerPanel(QtGui.QWidget):
self.selectedUUID = UUID
except PlayerNotFound:
log.info("PlayerPanel: player %s not found!", UUID)
self.treeView.setModel(None)
self.nbtEditor.setModel(None)
else:
self.updateNBTTree()

View File

@ -14,7 +14,6 @@ WorldListItemWidget:pressed {
QTreeView::item {
border-bottom: 1px solid #d9d9d9;
border-right: 1px solid #d9d9d9;
}
QTreeView::item:selected:active{

View File

@ -64,7 +64,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="propertiesTab">
<attribute name="title">
@ -203,11 +203,7 @@
<number>0</number>
</property>
<item>
<widget class="NBTTreeView" name="nbtTreeView">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
<widget class="NBTEditorWidget" name="nbtEditor" native="true"/>
</item>
</layout>
</widget>
@ -217,9 +213,10 @@
</widget>
<customwidgets>
<customwidget>
<class>NBTTreeView</class>
<extends>QTreeView</extends>
<header>nbttreeview.h</header>
<class>NBTEditorWidget</class>
<extends>QWidget</extends>
<header>nbteditorwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>356</width>
<width>604</width>
<height>675</height>
</rect>
</property>
@ -49,7 +49,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -87,14 +87,7 @@
<number>0</number>
</property>
<item>
<widget class="NBTTreeView" name="treeView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
<widget class="NBTEditorWidget" name="nbtEditor" native="true"/>
</item>
</layout>
</widget>
@ -109,9 +102,10 @@
<header>propertylistwidget.h</header>
</customwidget>
<customwidget>
<class>NBTTreeView</class>
<extends>QTreeView</extends>
<header>nbttreeview.h</header>
<class>NBTEditorWidget</class>
<extends>QWidget</extends>
<header>nbteditorwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>

View File

@ -52,6 +52,9 @@ def MakeNBTTreeItem(tag, parent):
class NBTTreeCompound(object):
isCompound = True
isList = False
def __init__(self, tag, parent=None):
self.parentItem = parent
self.tag = tag
@ -68,9 +71,6 @@ class NBTTreeCompound(object):
return self.parentItem.childItems.index(self)
return 0
def columnCount(self):
return 2
def data(self, column):
if column == 0:
return self.tag.name or self.tagCompoundName()
@ -98,16 +98,16 @@ class NBTTreeCompound(object):
return "%s items" % len(tag)
return summary
def insertChildren(self, position, count, columns):
def insertChildren(self, position, count):
if position < 0 or position > len(self.childItems):
return False
for row in range(count):
data = nbt.TAG_Byte()
self.tag.insert(position, data)
self.tag.insert(position + row, data)
item = NBTTreeItem(data, self)
self.childItems.insert(position, item)
self.childItems.insert(position + row, item)
return True
@ -128,6 +128,9 @@ class NBTTreeCompound(object):
class NBTTreeList(object):
isCompound = False
isList = True
def __init__(self, tag, parent=None):
self.parentItem = parent
self.tag = tag
@ -144,9 +147,6 @@ class NBTTreeList(object):
return self.parentItem.childItems.index(self)
return 0
def columnCount(self):
return 2
def data(self, column):
if column == 0:
return self.tag.name
@ -163,15 +163,15 @@ class NBTTreeList(object):
return ", ".join((fmt % i.value) for i in self.tag)
def insertChildren(self, position, count, columns):
def insertChildren(self, position, count):
if position < 0 or position > len(self.childItems):
return False
for row in range(count):
data = self.tag.list_type()
self.tag.insert(position, data)
data = nbt.tag_classes[self.tag.list_type or nbt.ID_BYTE]()
self.tag.insert(position + row, data)
item = NBTTreeItem(data, self)
self.childItems.insert(position, item)
self.childItems.insert(position + row, item)
return True
@ -192,6 +192,9 @@ class NBTTreeList(object):
class NBTTreeItem(object):
isCompound = False
isList = False
def __init__(self, tag, parent=None):
self.parentItem = parent
self.tag = tag
@ -213,9 +216,6 @@ class NBTTreeItem(object):
return self.parentItem.childItems.index(self)
return 0
def columnCount(self):
return 2
def data(self, column):
if column == 0:
return self.tag.name or str(self.childNumber())
@ -233,41 +233,39 @@ class NBTTreeModel(QtCore.QAbstractItemModel):
def __init__(self, rootTag, parent=None):
super(NBTTreeModel, self).__init__(parent)
self.rootItem = MakeNBTTreeItem(rootTag, self)
self.rootItem = MakeNBTTreeItem(rootTag, None)
self.rootTag = rootTag
self.allowNameChanges = True
self.addIcon = QtGui.QIcon(resourcePath("mcedit2/assets/mcedit2/icons/add.png"))
self.removeIcon = QtGui.QIcon(resourcePath("mcedit2/assets/mcedit2/icons/remove.png"))
def columnCount(self, parent=QtCore.QModelIndex()):
return self.rootItem.columnCount()
return 4
def tagID(self, index):
if not index.isValid():
return None
return self.getItem(index).tag.tagID
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
item = self.getItem(index)
column = index.column()
if role == QtCore.Qt.DecorationRole and column == 0:
return NBTIcon(item.tag.tagID)
if role == QtCore.Qt.DecorationRole:
if column == 0:
return NBTIcon(item.tag.tagID)
if column == 2:
return self.addIcon if item.isList or item.isCompound else None
if column == 3:
return self.removeIcon
if role in (QtCore.Qt.DisplayRole, QtCore.Qt.EditRole):
return item.data(column)
def flags(self, index):
if not index.isValid():
return 0
flags = QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
item = self.getItem(index)
parent = self.parent(index)
parentItem = self.getItem(parent) if parent else None
if index.column() == 1 or (self.allowNameChanges and isinstance(parentItem, NBTTreeCompound)):
if index.column() == 1 or (index.column() == 0 and self.allowNameChanges and parentItem and parentItem.isCompound):
flags |= QtCore.Qt.ItemIsEditable
return flags
@ -277,18 +275,18 @@ class NBTTreeModel(QtCore.QAbstractItemModel):
item = index.internalPointer()
if item:
return item
return self.rootItem
else:
return self.rootItem
def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return ("Name", "Value")[section]
return ("Name", "Value", "", "")[section]
return None
def index(self, row, column, parent=QtCore.QModelIndex()):
if parent.isValid() and parent.column() != 0:
return QtCore.QModelIndex()
if not parent.isValid():
return self.createIndex(row, column, self.rootItem)
parentItem = self.getItem(parent)
childItem = parentItem.child(row)
@ -297,11 +295,13 @@ class NBTTreeModel(QtCore.QAbstractItemModel):
else:
return QtCore.QModelIndex()
def insertRows(self, position, rows, parent=QtCore.QModelIndex()):
def insertRow(self, position, parent=QtCore.QModelIndex()):
return self.insertRows(position, 1, parent)
def insertRows(self, row, count, parent=QtCore.QModelIndex()):
parentItem = self.getItem(parent)
self.beginInsertRows(parent, position, position + rows - 1)
success = parentItem.insertChildren(position, rows,
self.rootItem.columnCount())
self.beginInsertRows(parent, row, row + count - 1)
success = parentItem.insertChildren(row, count)
self.endInsertRows()
return success
@ -313,11 +313,14 @@ class NBTTreeModel(QtCore.QAbstractItemModel):
childItem = self.getItem(index)
parentItem = childItem.parent()
if parentItem == self.rootItem:
if parentItem is None:
return QtCore.QModelIndex()
return self.createIndex(parentItem.childNumber(), 0, parentItem)
def removeRow(self, position, parent=QtCore.QModelIndex()):
self.removeRows(position, 1, parent)
def removeRows(self, position, rows, parent=QtCore.QModelIndex()):
parentItem = self.getItem(parent)
@ -328,6 +331,8 @@ class NBTTreeModel(QtCore.QAbstractItemModel):
return success
def rowCount(self, parent=QtCore.QModelIndex()):
if not parent.isValid():
return 1
parentItem = self.getItem(parent)
return parentItem.childCount()
@ -356,6 +361,7 @@ class NBTTreeModel(QtCore.QAbstractItemModel):
return result
_NBTTagTypeSortOrder = [
'TAG_Compound',
'TAG_List',
@ -390,3 +396,8 @@ class NBTFilterProxyModel(QtGui.QSortFilterProxyModel):
return leftIndex < rightIndex
return super(NBTFilterProxyModel, self).lessThan(left, right)
def sort(self, column, order):
if column > 1:
return
super(NBTFilterProxyModel, self).sort(column, order)

View File

@ -4,25 +4,60 @@
from __future__ import absolute_import, division, print_function, unicode_literals
import logging
from PySide import QtGui
from PySide import QtGui, QtCore
from PySide.QtCore import Qt
from mcedit2.util.resources import resourcePath
from mcedit2.widgets.nbttree.nbttreemodel import NBTFilterProxyModel
from mcedit2.util.load_ui import registerCustomWidget
from mcedit2.widgets.layout import Row
from mcedit2.widgets.layout import Row, Column
log = logging.getLogger(__name__)
@registerCustomWidget
class NBTTreeView(QtGui.QTreeView):
class NBTEditorWidget(QtGui.QWidget):
def __init__(self, *args, **kwargs):
super(NBTEditorWidget, self).__init__(*args, **kwargs)
self.model = None
self.treeView = QtGui.QTreeView()
self.treeView.setAlternatingRowColors(True)
self.treeView.clicked.connect(self.itemClicked)
self.treeView.expanded.connect(self.itemExpanded)
self.setLayout(Column(self.treeView))
def setModel(self, model):
proxyModel = NBTFilterProxyModel(self)
self.model = model
self.proxyModel = proxyModel = NBTFilterProxyModel(self)
proxyModel.setSourceModel(model)
proxyModel.setDynamicSortFilter(True)
super(NBTTreeView, self).setModel(proxyModel)
self.treeView.setModel(proxyModel)
header = self.treeView.header()
header.setStretchLastSection(False)
header.setResizeMode(1, header.ResizeMode.Stretch)
header.setResizeMode(2, header.ResizeMode.Fixed)
header.setResizeMode(3, header.ResizeMode.Fixed)
self.sortByColumn(0, Qt.AscendingOrder)
self.resizeColumnToContents(0)
self.resizeColumnToContents(1)
self.treeView.sortByColumn(0, Qt.AscendingOrder)
self.treeView.resizeColumnToContents(0)
self.treeView.resizeColumnToContents(1)
self.treeView.resizeColumnToContents(2)
self.treeView.resizeColumnToContents(3)
def itemExpanded(self, index):
self.treeView.resizeColumnToContents(0)
def itemClicked(self, index):
index = self.proxyModel.mapToSource(index)
item = self.model.getItem(index)
if index.column() == 2:
if item.isList:
self.model.insertRow(item.childCount(), index)
elif item.isCompound:
""" show tag type menu """
if index.column() == 3:
parent = self.model.parent(index)
self.model.removeRow(index.row(), parent)