From 5b2614d83297fab5c00010db0d33eb88f7df025e Mon Sep 17 00:00:00 2001
From: artem30801 <38689676+artem30801@users.noreply.github.com>
Date: Fri, 29 Nov 2019 23:26:47 +0300
Subject: [PATCH] wip4
---
Server/config_editor.py | 2 +-
Server/config_editor.ui | 69 +++++++++---
Server/config_editor_models.py | 192 +++++++++++++++++++++++++++------
requirements.txt | 7 +-
4 files changed, 219 insertions(+), 51 deletions(-)
diff --git a/Server/config_editor.py b/Server/config_editor.py
index 2ace49f..ca488a2 100644
--- a/Server/config_editor.py
+++ b/Server/config_editor.py
@@ -13,7 +13,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_config_dialog(object):
def setupUi(self, config_dialog):
config_dialog.setObjectName("config_dialog")
- config_dialog.resize(317, 247)
+ config_dialog.resize(600, 700)
config_dialog.setModal(False)
self.gridLayout = QtWidgets.QGridLayout(config_dialog)
self.gridLayout.setObjectName("gridLayout")
diff --git a/Server/config_editor.ui b/Server/config_editor.ui
index a65b2b1..e76c48f 100644
--- a/Server/config_editor.ui
+++ b/Server/config_editor.ui
@@ -6,8 +6,8 @@
0
0
- 317
- 247
+ 310
+ 399
@@ -17,22 +17,9 @@
false
- -
-
-
- -
+
-
-
-
-
- Delete
-
-
- Del
-
-
-
- -
Restart
@@ -42,7 +29,7 @@
- -
+
-
Qt::Horizontal
@@ -57,6 +44,54 @@
+ -
+
+
+ -
+
+
-
+
+
+ Delete
+
+
+ Del
+
+
+
+ -
+
+
+ Add option
+
+
+
+ -
+
+
+ Add section
+
+
+ Ctrl+A
+
+
+
+ -
+
+
+ Mark for deletion
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
diff --git a/Server/config_editor_models.py b/Server/config_editor_models.py
index 47f3a65..179eb05 100644
--- a/Server/config_editor_models.py
+++ b/Server/config_editor_models.py
@@ -1,13 +1,20 @@
+from copy import deepcopy
+
+import pickle
+
import config_editor
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt as Qt
+from PyQt5.QtGui import QCursor, QStandardItemModel
+from PyQt5.QtWidgets import QAbstractItemView, QTreeView, QMenu
class ConfigModelItem:
- def __init__(self, label, value="", is_section=False, parent=None):
+ def __init__(self, label, value="", is_section=False, state='default', parent=None):
self.itemData = [label, value]
+ self.is_section = is_section
+ self.state = state
- self.is_section=is_section
self.childItems = []
self.parentItem = parent
@@ -18,6 +25,19 @@ class ConfigModelItem:
self.childItems.append(item)
item.parentItem = self
+ def addChildren(self, items, row):
+ if row == -1:
+ self.childItems.extend(items)
+ else:
+ #row -= 1
+ print('row', row)
+ self.childItems[row:row] = items
+
+ print(self.childItems)
+
+ for item in items:
+ item.parentItem = self
+
def child(self, row):
return self.childItems[row]
@@ -53,11 +73,21 @@ class ConfigModelItem:
def removeChild(self, position):
if position < 0 or position > len(self.childItems):
return False
-
+ print('removing', position)
child = self.childItems.pop(position)
child.parentItem = None
return True
+ def removeChildren(self, row, count):
+ print(range(row, row+count))
+ for pos in range(row, row+count):
+ self.removeChild(pos)
+
+ return True
+
+ def __repr__(self):
+ return str(self.itemData)
+
class ConfigModel(QtCore.QAbstractItemModel):
def __init__(self, data, parent=None):
@@ -88,11 +118,7 @@ class ConfigModel(QtCore.QAbstractItemModel):
if not self.hasIndex(row, column, parent):
return QtCore.QModelIndex()
- if not parent.isValid():
- parentItem = self.rootItem
- else:
- parentItem = parent.internalPointer()
-
+ parentItem = self.nodeFromIndex(parent)
childItem = parentItem.child(row)
if childItem:
@@ -112,6 +138,11 @@ class ConfigModel(QtCore.QAbstractItemModel):
return self.createIndex(parentItem.row(), 0, parentItem)
+ def nodeFromIndex(self, index):
+ if index.isValid():
+ return index.internalPointer()
+ return self.rootItem
+
def data(self, index, role):
if not index.isValid():
return None
@@ -138,31 +169,86 @@ class ConfigModel(QtCore.QAbstractItemModel):
def flags(self, index):
if not index.isValid():
- return Qt.NoItemFlags
+ return QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled # Qt.NoItemFlags
item = index.internalPointer()
flags = Qt.ItemIsEnabled | Qt.ItemIsSelectable
+ if index.column() == 0:
+ flags |= int(QtCore.Qt.ItemIsDragEnabled)
+ if item.is_section:
+ flags |= int(QtCore.Qt.ItemIsDropEnabled)
+
if index.column() == 1 and not item.is_section:
flags |= Qt.ItemIsEditable
return flags
+ def supportedDropActions(self):
+ return QtCore.Qt.CopyAction | QtCore.Qt.MoveAction
+
+ def mimeTypes(self):
+ return ['bstream', 'text/xml']
+
+ def mimeData(self, indexes):
+ mimedata = QtCore.QMimeData()
+ index = indexes[0]
+ mimedata.setData('bstream', pickle.dumps(self.nodeFromIndex(index)))
+ return mimedata
+
+ def dropMimeData(self, mimedata, action, row, column, parentIndex):
+ print(action)
+ print('mim', row)
+ if action == Qt.IgnoreAction:
+ return True
+
+ parentNode = self.nodeFromIndex(parentIndex)
+ droppedNode = deepcopy(pickle.loads(mimedata.data('bstream')))
+ print(droppedNode.itemData, 'node')
+ #droppedNode = pickle.loads(mimedata.data('bstream')) #
+ #self.removeRow()#self.index(row, column, parentIndex))#parentNode.child(row))
+ self.insertItems(row, [droppedNode], parentIndex)
+ self.dataChanged.emit(parentIndex, parentIndex)
+
+ return True
+
+ def removeRows1(self, row, count, parent):
+ print('rem', row, count)
+ self.beginRemoveRows(parent, row, row+count-1)
+ parentItem = self.nodeFromIndex(parent)
+ print(parentItem, parentItem.itemData)
+
+ #parentItem.removeChild(row)
+ parentItem.removeChildren(row, count)
+ print(parentItem.childItems)
+
+ self.endRemoveRows()
+ print('removed')
+ return True
+
@QtCore.pyqtSlot()
def removeRow(self, index):
parent = index.parent()
self.beginRemoveRows(parent, index.row(), index.row())
- if not parent.isValid():
- parentNode = self.rootItem
- else:
- parentNode = parent.internalPointer()
-
- parentNode.removeChild(index.row())
+ parentItem = self.nodeFromIndex(parent)
+ parentItem.removeChild(index.row())
self.endRemoveRows()
return True
+ def insertItems(self, row, items, parentIndex):
+ print('ins', row)
+ parent = self.nodeFromIndex(parentIndex)
+ self.beginInsertRows(parentIndex, row, row+len(items)-1)
+
+ parent.addChildren(items, row)
+ print(parent.childItems)
+
+ self.endInsertRows()
+ self.dataChanged.emit(parentIndex, parentIndex)
+ return True
+
def setup(self, data: dict, parent=None):
if parent is None:
parent = self.rootItem
@@ -174,19 +260,23 @@ class ConfigModel(QtCore.QAbstractItemModel):
else:
parent.appendChild(ConfigModelItem(key, value))
- def to_dict(self): # TODO recursive
- d = {}
- for section in self.rootItem.childItems:
- section_d = {}
- section_name, _ = section.itemData
+ def to_dict(self, parent=None) -> dict:
+ if parent is None:
+ parent = self.rootItem
- for item in section.childItems:
- option, value = item.itemData
- section_d[option] = value
+ data = {}
+ for item in parent.childItems:
+ item_name, item_data = item.itemData
+ if item.childItems:
+ data[item_name] = self.to_dict(item)
+ else:
+ data[item_name] = item_data
- d[section_name] = section_d
+ return data
- return d
+ @property
+ def dict(self):
+ return self.to_dict()
class ConfigDialog(config_editor.Ui_config_dialog):
@@ -197,17 +287,59 @@ class ConfigDialog(config_editor.Ui_config_dialog):
def setupUi(self, config_dialog):
super(ConfigDialog, self).setupUi(config_dialog)
+ #self.config_view = Tree()
+
+ self.config_view = Tree()
+ self.config_view.setObjectName("config_view")
self.config_view.setModel(self.model)
+ self.gridLayout.addWidget(self.config_view, 0, 0, 1, 1)
+
self.config_view.expandAll()
+ #self.config_view.setDragDropMode(True)
+ #self.setDragDropMode(QAbstractItemView.InternalMove)
+ #self.setDragEnabled(True)
+ #self.setAcceptDrops(True)
+ #self.setDropIndicatorShown(True)
self.delete_button.pressed.connect(self.remove_selected)
def remove_selected(self):
index = self.config_view.selectedIndexes()[0]
- self.model.removeRow(index)
+ self.model.removeRow(index)\
- #print(self.model.to_dict())
+class Tree(QTreeView):
+ def __init__(self):
+ QTreeView.__init__(self)
+ data = {"section 1": {"opt1": "str", "opt2": 123, "opt3": 1.23, "opt4": False, "...": {'subopt': 'bal'}},
+ "section 2": {"opt1": "str", "opt2": [1.1, 2.3, 34], "opt3": 1.23, "opt4": False, "...": ""}}
+ #model = ConfigModel(data)
+
+ #self.setModel(model)
+ self.setContextMenuPolicy(Qt.CustomContextMenu)
+ self.customContextMenuRequested.connect(self.open_menu)
+
+ self.setSelectionMode(self.SingleSelection)
+ self.setDragDropMode(QAbstractItemView.InternalMove)
+ self.setDragEnabled(True)
+ self.setAcceptDrops(True)
+ self.setDropIndicatorShown(True)
+
+ # def dropEvent(self, e):
+ # print(e.dropAction()==QtCore.Qt.MoveAction)
+ # if e.keyboardModifiers() & QtCore.Qt.AltModifier:
+ # e.setDropAction()
+ # print('copy')
+ # else:
+ # e.setDropAction(QtCore.Qt.MoveAction)
+ # print("drop")
+ # print(e)
+ # e.accept()
+
+ def open_menu(self):
+ menu = QMenu()
+ menu.addAction("Create new folder")
+ menu.exec_(QCursor.pos())
if __name__ == '__main__':
import sys
@@ -221,13 +353,13 @@ if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
- data = {"section 1": {"opt1": "str", "opt2": 123, "opt3": 1.23, "opt4": False, "...": {'subopt': 'bal'}},
- "section 2": {"opt1": "str", "opt2": [1.1, 2.3, 34], "opt3": 1.23, "opt4": False, "...": ""}}
+ data = {"section 1": {"opt1": "str", "opt2": 123, "opt3": 1.23, "opt4": False, }}#"...": {'subopt': 'bal'}},}
+ #"section 2": {"opt1": "str", "opt2": [1.1, 2.3, 34], "opt3": 1.23, "opt4": False, "...": ""}}
ui = ConfigDialog(data)
ui.setupUi(Dialog)
-
+ print(Qt.DisplayRole)
Dialog.show()
print(app.exec_())
diff --git a/requirements.txt b/requirements.txt
index 728753f..c991080 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,6 @@
+configobj
indexed.py==0.0.1
-numpy==1.16.4
-PyQt5==5.13.0
-PyQt5-sip==4.19.18
+numpy==1.17.4
+PyQt5==5.13.2
+PyQt5-sip==12.7.0
selectors2==2.0.1