From b73b65c09f2e5bb376a73203a8fec73b80f34d8d Mon Sep 17 00:00:00 2001 From: Artem30801 Date: Sun, 1 Dec 2019 21:06:57 +0300 Subject: [PATCH] gui+functionality update --- Server/config_editor.py | 56 +++++++++---------------- Server/config_editor.ui | 76 +++++++++++----------------------- Server/config_editor_models.py | 59 ++++++++++++++++---------- 3 files changed, 81 insertions(+), 110 deletions(-) diff --git a/Server/config_editor.py b/Server/config_editor.py index a498c63..e6e5f67 100644 --- a/Server/config_editor.py +++ b/Server/config_editor.py @@ -17,44 +17,33 @@ class Ui_config_dialog(object): config_dialog.setModal(False) self.gridLayout = QtWidgets.QGridLayout(config_dialog) self.gridLayout.setObjectName("gridLayout") - self.gridLayout_2 = QtWidgets.QGridLayout() - self.gridLayout_2.setObjectName("gridLayout_2") - self.checkBox = QtWidgets.QCheckBox(config_dialog) - self.checkBox.setObjectName("checkBox") - self.gridLayout_2.addWidget(self.checkBox, 0, 0, 1, 1) - self.buttonBox = QtWidgets.QDialogButtonBox(config_dialog) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Save) - self.buttonBox.setCenterButtons(False) - self.buttonBox.setObjectName("buttonBox") - self.gridLayout_2.addWidget(self.buttonBox, 0, 1, 1, 1) - self.gridLayout.addLayout(self.gridLayout_2, 3, 0, 1, 1) self.config_view = QtWidgets.QTreeView(config_dialog) self.config_view.setEditTriggers(QtWidgets.QAbstractItemView.DoubleClicked|QtWidgets.QAbstractItemView.EditKeyPressed|QtWidgets.QAbstractItemView.SelectedClicked) self.config_view.setObjectName("config_view") self.config_view.header().setCascadingSectionResizes(False) self.config_view.header().setDefaultSectionSize(250) self.gridLayout.addWidget(self.config_view, 0, 0, 1, 1) - self.gridLayout_3 = QtWidgets.QGridLayout() - self.gridLayout_3.setObjectName("gridLayout_3") - self.delete_button = QtWidgets.QPushButton(config_dialog) - self.delete_button.setObjectName("delete_button") - self.gridLayout_3.addWidget(self.delete_button, 0, 1, 1, 1) - self.add_option_button = QtWidgets.QPushButton(config_dialog) - self.add_option_button.setObjectName("add_option_button") - self.gridLayout_3.addWidget(self.add_option_button, 0, 3, 1, 1) - self.add_section_button = QtWidgets.QPushButton(config_dialog) - self.add_section_button.setObjectName("add_section_button") - self.gridLayout_3.addWidget(self.add_section_button, 0, 2, 1, 1) - self.hard_delete = QtWidgets.QPushButton(config_dialog) - self.hard_delete.setObjectName("hard_delete") - self.gridLayout_3.addWidget(self.hard_delete, 0, 0, 1, 1) - self.gridLayout.addLayout(self.gridLayout_3, 1, 0, 1, 1) + self.gridLayout_2 = QtWidgets.QGridLayout() + self.gridLayout_2.setObjectName("gridLayout_2") + self.buttonBox = QtWidgets.QDialogButtonBox(config_dialog) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Save) + self.buttonBox.setCenterButtons(False) + self.buttonBox.setObjectName("buttonBox") + self.gridLayout_2.addWidget(self.buttonBox, 0, 2, 1, 1) + self.do_restart = QtWidgets.QCheckBox(config_dialog) + self.do_restart.setObjectName("do_restart") + self.gridLayout_2.addWidget(self.do_restart, 0, 1, 1, 1) + self.do_coloring = QtWidgets.QCheckBox(config_dialog) + self.do_coloring.setChecked(True) + self.do_coloring.setObjectName("do_coloring") + self.gridLayout_2.addWidget(self.do_coloring, 0, 0, 1, 1) + self.gridLayout.addLayout(self.gridLayout_2, 2, 0, 1, 1) self.line = QtWidgets.QFrame(config_dialog) self.line.setFrameShape(QtWidgets.QFrame.HLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setObjectName("line") - self.gridLayout.addWidget(self.line, 2, 0, 1, 1) + self.gridLayout.addWidget(self.line, 1, 0, 1, 1) self.retranslateUi(config_dialog) self.buttonBox.accepted.connect(config_dialog.accept) @@ -64,14 +53,9 @@ class Ui_config_dialog(object): def retranslateUi(self, config_dialog): _translate = QtCore.QCoreApplication.translate config_dialog.setWindowTitle(_translate("config_dialog", "Config Editor")) - self.checkBox.setText(_translate("config_dialog", "Restart")) - self.checkBox.setShortcut(_translate("config_dialog", "R")) - self.delete_button.setText(_translate("config_dialog", "Delete")) - self.delete_button.setShortcut(_translate("config_dialog", "Del")) - self.add_option_button.setText(_translate("config_dialog", "Add option")) - self.add_section_button.setText(_translate("config_dialog", "Add section")) - self.add_section_button.setShortcut(_translate("config_dialog", "Ctrl+A")) - self.hard_delete.setText(_translate("config_dialog", "Mark for deletion")) + self.do_restart.setText(_translate("config_dialog", "Restart")) + self.do_restart.setShortcut(_translate("config_dialog", "R")) + self.do_coloring.setText(_translate("config_dialog", "Color Indication")) if __name__ == "__main__": diff --git a/Server/config_editor.ui b/Server/config_editor.ui index f33760b..6527d93 100644 --- a/Server/config_editor.ui +++ b/Server/config_editor.ui @@ -17,33 +17,6 @@ false - - - - - - Restart - - - R - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Save - - - false - - - - - @@ -57,45 +30,44 @@ - - - - - - Delete - - - Del - - - - - - - Add option - - - + + - + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Save + + + false + + + + + - Add section + Restart - Ctrl+A + R - + - Mark for deletion + Color Indication + + + true - + Qt::Horizontal diff --git a/Server/config_editor_models.py b/Server/config_editor_models.py index 204bb7c..a184342 100644 --- a/Server/config_editor_models.py +++ b/Server/config_editor_models.py @@ -22,7 +22,7 @@ def dict_walk(d: dict, keys): states_colors = { - 'normal': Qt.white, #Qt.black, + 'normal': Qt.white, 'unchanged': Qt.darkGray, 'default': Qt.lightGray, 'edited': Qt.yellow, @@ -33,18 +33,18 @@ states_colors = { class ConfigModelItem: def __init__(self, values=(), is_section=False, state='normal', default=None, parent=None): - self.default = default + self.spec_default = default values = list(values) if is_section: values[1:1] = ('
',) - self.default = values[1] + self.spec_default = values[1] self.itemData = values - self.is_section = is_section + self.type = 'section' if is_section else None self.state = state - self.defaults = deepcopy(self.itemData) + self.default_values = deepcopy(self.itemData) self.default_state = state self.childItems = [] @@ -53,8 +53,12 @@ class ConfigModelItem: if self.parentItem is not None: self.parentItem.appendChild(self) + @property + def is_section(self): + return self.type == 'section' + def reset(self): - self.set_data(self.default, 1) + self.set_data(self.spec_default, 1) self.check_state() if self.default_state == 'unchanged': @@ -64,8 +68,7 @@ class ConfigModelItem: child.reset() def reset_all(self): - self.itemData = self.defaults - print(self.itemData, self.defaults) + self.itemData = self.default_values self.set_state(self.default_state) for child in self.childItems: @@ -103,15 +106,11 @@ class ConfigModelItem: if old_data is None: data = literal_eval(data) if data else None - print(data, old_data) - try: self.itemData[column] = data except IndexError: return False - print(self.itemData[column]) - if old_data != data: self.set_state('edited') self.check_state() @@ -119,7 +118,8 @@ class ConfigModelItem: return True def check_state(self): - if self.default is not None and self.data(1) == self.default: + if self.spec_default is not None and self.data(1) == self.spec_default \ + and self.data(0) == self.default_values[0]: self.set_state('default') def set_state(self, state): @@ -176,9 +176,16 @@ class ConfigModel(QtCore.QAbstractItemModel): self.widget = widget self.rootItem = ConfigModelItem(headers) + self.do_color = True + self.initial_comment = '' self.final_comment = '' + @QtCore.pyqtSlot(int) + def enable_color(self, value): + self.do_color = value + self.dataChanged.emit(QtCore.QModelIndex(), QtCore.QModelIndex(), (Qt.BackgroundRole, )) + def headerData(self, section, orientation, role): if role == Qt.DisplayRole and orientation == Qt.Horizontal: return self.rootItem.data(section) @@ -234,7 +241,7 @@ class ConfigModel(QtCore.QAbstractItemModel): if role == Qt.DisplayRole or role == Qt.EditRole: return item.data(index.column()) - if role == Qt.BackgroundRole: #Qt.BackgroundRole: + if role == Qt.BackgroundRole and self.do_color: return QtGui.QBrush(states_colors[item.state]) return None @@ -246,12 +253,13 @@ class ConfigModel(QtCore.QAbstractItemModel): item = index.internalPointer() if role == Qt.EditRole: if index.column() == 0 and (self.widget is not None) \ - and not self.widget.edit_caution(): - return False + and value != item.data(index.column()): + if not self.widget.edit_caution(): + return False item.set_data(value, index.column()) if index.column() == 0: - ensure_unique_names(item) + ensure_unique_names(item, include_self=False) self.dataChanged.emit(index, index, (role,)) @@ -403,13 +411,16 @@ class ConfigModel(QtCore.QAbstractItemModel): data['final_comment'] = self.final_comment.split('\n') for item in parent.childItems: - key = item.data(1) + key = item.data(0) if item.is_section: - data[key] = self.to_config_dict(item) + d = self.to_config_dict(item) + if d: # to prevent empty sections + data[key] = d + elif item.state != 'unchanged': d = {'__option__': True, - 'value': item.data(0), + 'value': item.data(1), # 'default': item.default, # 'unchanged': False, 'comments': (item.data(2) or '').split('\n'), @@ -449,6 +460,8 @@ class ConfigDialog(QtWidgets.QDialog): self.ui.gridLayout.addWidget(self.ui.config_view, 0, 0, 1, 1) self.ui.config_view.expandAll() + self.ui.do_coloring.stateChanged.connect(self.model.enable_color) + # self.ui.delete_button.pressed.connect(self.remove_selected) # index = self.config_view.selectedIndexes()[0] @@ -521,6 +534,8 @@ class Tree(QTreeView): menu.addAction(add_section) if item is None: + reset.setDisabled(True) + reset_all.setDisabled(True) duplicate.setDisabled(True) remove.setDisabled(True) @@ -594,10 +609,10 @@ if __name__ == '__main__': 'comments': ['#host = ntp1.stratum2.ru'], 'inline_comment': None}, 'host': {'__option__': True, 'value': 'ntp1.stratum2.ru', 'default': 'ntp1.stratum2.ru', 'unchanged': True, 'comments': [], 'inline_comment': ''}}, 'PRIVATE': { - 'id': {'__option__': True, 'value': '/hostname', 'default': '/hostname', 'unchanged': False, + 'id': {'__option__': True, 'value': '/hostname', 'default': '/hostname', 'unchanged': True, 'comments': ['# avialiable options: /hostname ; /default ; /ip ; any string 63 characters lengh', 'newlibe'], 'inline_comment': None}}, - 'initial_comment': ['# This is generated config_attrs with defaults', '# Modify to configure'], + 'initial_comment': ['# This is generated config_attrs with default_values', '# Modify to configure'], 'final_comment': []} ui = ConfigDialog()