Skip to content

Commit

Permalink
fix(JsonWidget): fix remove undo
Browse files Browse the repository at this point in the history
fix(widgets): use jsonWidget for editing comboBox or listBox items
  • Loading branch information
azagoruyko committed Sep 19, 2024
1 parent 19a58aa commit a12b62d
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 73 deletions.
31 changes: 2 additions & 29 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,33 +54,6 @@ def __init__(self, runFunction):
def run(self):
self.runFunction()

class EditJsonDialog(QDialog):
saved = Signal(dict)

def __init__(self, data, *, title="Edit"):
super().__init__(parent=QApplication.activeWindow())

self.setWindowTitle(title)
self.setGeometry(0, 0, 600, 400)

layout = QVBoxLayout()
self.setLayout(layout)

self.jsonWidget = widgets.JsonWidget(data)

okBtn = QPushButton("OK")
okBtn.clicked.connect(self.saveAndClose)

layout.addWidget(self.jsonWidget)
layout.addWidget(okBtn)
centerWindow(self)

def saveAndClose(self):
dataList = self.jsonWidget.toJsonList()
if dataList:
self.saved.emit(dataList[0]) # keep the first item only
self.accept()

class AttributesWidget(QWidget):
def __init__(self, moduleItem, attributes, *, mainWindow=None, **kwargs):
super().__init__(**kwargs)
Expand Down Expand Up @@ -292,13 +265,13 @@ def editData(self, attrWidgetIndex):
def save(data):
@AttributesWidget._wrapper
def _save(_, attrWidgetIndex):
attr.setData(data)
attr.setData(data[0]) # use [0] because data is a list
self.updateWidget(attrWidgetIndex)
self.updateWidgetStyle(attrWidgetIndex)
_save(self, attrWidgetIndex)

attr, _, _ = self._attributeAndWidgets[attrWidgetIndex]
w = EditJsonDialog(attr.localData(), title="Edit data")
w = widgets.EditJsonDialog(attr.localData(), title="Edit data")
w.saved.connect(save)
w.show()

Expand Down
17 changes: 15 additions & 2 deletions jsonWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,21 @@ def removeItem(self):
selectedItems = self.selectedItems()

# add undo
_undoData = []
parentItems = []
for item in selectedItems:
parent = item.parent()
skip = False
while parent:
if parent in selectedItems:
skip = True
break
parent = parent.parent()

if not skip:
parentItems.append(item)

_undoData = []
for item in parentItems:
parent = item.parent() or self.invisibleRootItem()
idx = parent.indexOfChild(item)
_undoData.append([self.getPathIndex(parent), item.clone(), idx])
Expand All @@ -600,7 +613,7 @@ def f():
parent.insertChild(idx, item)
self._undoSystem.push("Remove", f)

for item in selectedItems:
for item in parentItems:
(item.parent() or self.invisibleRootItem()).removeChild(item)
self.itemRemoved.emit(item)

Expand Down
123 changes: 81 additions & 42 deletions widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,32 @@ def saveAndClose(self):
self.saved.emit(self.textWidget.toPlainText())
self.accept()

class EditJsonDialog(QDialog):
saved = Signal(object)

def __init__(self, data, *, title="Edit"):
super().__init__(parent=QApplication.activeWindow())

self.setWindowTitle(title)
self.setGeometry(0, 0, 600, 400)

layout = QVBoxLayout()
self.setLayout(layout)

self.jsonWidget = JsonWidget(data)

okBtn = QPushButton("OK")
okBtn.clicked.connect(self.saveAndClose)

layout.addWidget(self.jsonWidget)
layout.addWidget(okBtn)
centerWindow(self)

def saveAndClose(self):
dataList = self.jsonWidget.toJsonList()
self.saved.emit(dataList)
self.accept()

class LabelTemplateWidget(TemplateWidget):
def __init__(self, **kwargs):
super().__init__(**kwargs)
Expand Down Expand Up @@ -224,13 +250,13 @@ def comboBoxContextMenuEvent(self, event):
menu.popup(event.globalPos())

def editItems(self):
items = ";".join([self.comboBox.itemText(i) for i in range(self.comboBox.count())])
newItems, ok = QInputDialog.getText(self, "Rig Builder", "Items separated with ';'", QLineEdit.Normal, items)
if ok and newItems:
value = self.getJsonData()
value["items"] = [smartConversion(item.strip()) for item in newItems.split(";") if item.strip()]
self.setJsonData(value)
self.somethingChanged.emit()
def save(newData):
self.setItems(newData)

data = self.getItems()
w = EditJsonDialog(data, title="Edit items")
w.saved.connect(save)
w.show()

def clearItems(self):
ok = QMessageBox.question(self, "Rig Builder", "Really clear all items?", QMessageBox.Yes and QMessageBox.No, QMessageBox.Yes) == QMessageBox.Yes
Expand All @@ -249,31 +275,37 @@ def removeItem(self):
self.comboBox.removeItem(self.comboBox.currentIndex())
self.somethingChanged.emit()

def getItems(self):
return [smartConversion(self.comboBox.itemText(i)) for i in range(self.comboBox.count())]

def setItems(self, items):
with blockedWidgetContext(self.comboBox) as w:
w.clear()

for i, item in enumerate(items):
w.addItem(fromSmartConversion(item))
w.setItemData(i, jsonColor(item), Qt.ForegroundRole)

self.somethingChanged.emit()

def getDefaultData(self):
return {"items": ["a", "b"], "current": "a", "default": "current"}

def getJsonData(self):
return {"items": [smartConversion(self.comboBox.itemText(i)) for i in range(self.comboBox.count())],
return {"items": self.getItems(),
"current": smartConversion(self.comboBox.currentText()),
"default": "current"}

def setJsonData(self, value):
with blockedWidgetContext(self.comboBox) as w:
w.clear()

items = value["items"]
items.append(value["current"]) # make sure current is in items
skip = []
for i, item in enumerate(items):
if item in skip: # don't add duplicates
continue
items = list(value["items"])

if value["current"] not in items:
items.append(value["current"]) # make sure current is in items

self.comboBox.addItem(fromSmartConversion(item))
self.comboBox.setItemData(i, jsonColor(item), Qt.ForegroundRole)
skip.append(item)
self.setItems(items)

with blockedWidgetContext(self.comboBox) as w:
w.setCurrentIndex(value["items"].index(value["current"]))
w.setCurrentIndex(items.index(value["current"]))

class LineEditOptionsDialog(QDialog):
def __init__(self, **kwargs):
Expand Down Expand Up @@ -592,7 +624,7 @@ def listContextMenuEvent(self, event):

menu.addAction("Append", self.appendItem)
menu.addAction("Remove", self.removeItem)
menu.addAction("Edit", self.editItem)
menu.addAction("Edit", self.editItems)

def f():
self.listWidget.sortItems()
Expand All @@ -618,6 +650,16 @@ def itemChanged(self, item):
self.somethingChanged.emit()
self.resizeWidget()

def editItems(self):
def save(newData):
self.setItems(newData)
self.resizeWidget()

data = self.getItems()
w = EditJsonDialog(data, title="Edit items")
w.saved.connect(save)
w.show()

def resizeWidget(self):
width = self.listWidget.sizeHintForColumn(0) + 50
height = 0
Expand All @@ -626,19 +668,6 @@ def resizeWidget(self):
height += 2*self.listWidget.frameWidth() + 50
self.listWidget.setFixedSize(clamp(width, 100, 500), clamp(height, 100, 500))

def editItem(self):
items = ";".join([self.listWidget.item(i).text() for i in range(self.listWidget.count())])
newItems, ok = QInputDialog.getText(self, "Rig Builder", "Items separated with ';'", QLineEdit.Normal, items)
if ok and newItems:
with blockedWidgetContext(self.listWidget) as w:
w.clear()

for x in newItems.split(";"):
item = ListBoxItem(smartConversion(x.strip()))
self.listWidget.addItem(item)
self.somethingChanged.emit()
self.resizeWidget()

def selectInDCC(self, allItems=True):
items = [self.listWidget.item(i).text() for i in range(self.listWidget.count()) if allItems or self.listWidget.item(i).isSelected()]

Expand Down Expand Up @@ -676,25 +705,35 @@ def appendItem(self):
self.somethingChanged.emit()

def removeItem(self):
self.listWidget.takeItem(self.listWidget.currentRow())
for item in self.listWidget.selectedItems():
self.listWidget.takeItem(self.listWidget.row(item))

self.resizeWidget()
self.somethingChanged.emit()

def getItems(self):
return [self.listWidget.item(i).data(ListBoxItem.ValueRole) for i in range(self.listWidget.count())]

def setItems(self, items):
with blockedWidgetContext(self.listWidget) as w:
w.clear()
for v in items:
w.addItem(ListBoxItem(v))

self.somethingChanged.emit()

def getDefaultData(self):
return {"items": ["a", "b"], "current":0, "selected":[], "default": "items"}

def getJsonData(self):
return {"items": [self.listWidget.item(i).data(ListBoxItem.ValueRole) for i in range(self.listWidget.count())],
return {"items": self.getItems(),
"selected": [self.listWidget.row(item) for item in self.listWidget.selectedItems()],
"default": "items"}

def setJsonData(self, value):
with blockedWidgetContext(self.listWidget) as w:
w.clear()
self.setItems(value["items"])

for v in value["items"]:
w.addItem(ListBoxItem(v))

with blockedWidgetContext(self.listWidget) as w:
for i in value.get("selected", []):
item = w.item(i)
if item:
Expand Down

0 comments on commit a12b62d

Please sign in to comment.