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:
parent
19a8c01f4f
commit
e07cc96ae5
@ -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)
|
||||
|
@ -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()
|
||||
|
||||
|
@ -14,7 +14,6 @@ WorldListItemWidget:pressed {
|
||||
|
||||
QTreeView::item {
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
border-right: 1px solid #d9d9d9;
|
||||
}
|
||||
|
||||
QTreeView::item:selected:active{
|
||||
|
@ -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/>
|
||||
|
@ -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/>
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
Reference in New Issue
Block a user