- bug fixes in error.py - add from * to raise statements - fix py35 compatibility - finalize omit_unchanged_within feature - fix follwup bug (missing Param.override) in proxy.py Change-Id: I621c01a0d5e1ec6696fb06f39666f3316fb53649
224 lines
8.5 KiB
Python
224 lines
8.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
# *****************************************************************************
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free Software
|
|
# Foundation; either version 2 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
#
|
|
# Module authors:
|
|
# Sandra Seger <sandra.seger@frm2.tum.de>
|
|
#
|
|
# *****************************************************************************
|
|
|
|
from secop.gui.cfg_editor.utils import loadUi, \
|
|
set_name_edit_style, setIcon, setTreeIcon
|
|
from secop.gui.qt import QDialog, QFont, QHBoxLayout, \
|
|
QLabel, QPushButton, QSize, QSizePolicy, QTextEdit, \
|
|
QTreeWidgetItem, QVBoxLayout, QWidget, pyqtSignal
|
|
from secop.gui.valuewidgets import get_widget
|
|
from secop.properties import Property
|
|
|
|
NODE = 'node'
|
|
INTERFACE = 'interface'
|
|
MODULE = 'module'
|
|
PARAMETER = 'parameter'
|
|
PROPERTY = 'property'
|
|
COMMENT = 'comment'
|
|
|
|
|
|
class TreeWidgetItem(QTreeWidgetItem):
|
|
def __init__(self, kind=None, name='', value=None, class_object=None,
|
|
parameters=None, properties=None, parent=None):
|
|
"""object_class: for interfaces and modules = class
|
|
for parameter and properties = their objects
|
|
the datatype passed onto ValueWidget should be on of secop.datatypes"""
|
|
# TODO: like stated in docstring the datatype for parameters and
|
|
# properties must be found out through their object
|
|
super().__init__(parent)
|
|
self.kind = kind
|
|
self.name = name
|
|
self.class_object = class_object
|
|
self.parameters = parameters or {}
|
|
self.properties = properties or {}
|
|
if self.kind and self.kind != 'node':
|
|
setTreeIcon(self, '%s.png' % self.kind)
|
|
else:
|
|
setTreeIcon(self, 'empty.png')
|
|
font = QFont()
|
|
font.setWeight(QFont.Bold)
|
|
self.setFont(0, font)
|
|
self.setText(0, self.name)
|
|
self.duplicates = 0
|
|
datatype = None if type(class_object) != Property else \
|
|
class_object.datatype
|
|
self.widget = ValueWidget(name, value, datatype, kind)
|
|
if kind in [NODE, MODULE, INTERFACE]:
|
|
self.widget.edit_btn.clicked.connect(self.change_name)
|
|
|
|
def addChild(self, item):
|
|
QTreeWidgetItem.addChild(self, item)
|
|
item.setExpanded(True)
|
|
|
|
def duplicate(self):
|
|
self.duplicates += 1
|
|
duplicate = TreeWidgetItem(self.kind, '%s_%i' % (self.name,
|
|
self.duplicates), self.get_value(),
|
|
self.class_object)
|
|
self.parent().addChild(duplicate)
|
|
for i in range(self.childCount()):
|
|
child = self.child(i)
|
|
duplicate.addChild(TreeWidgetItem(child.kind,
|
|
child.name, child.widget.get_value()))
|
|
for k in range(child.childCount()):
|
|
sub_child = child.child(k)
|
|
duplicate.child(i).addChild(TreeWidgetItem(sub_child.kind,
|
|
sub_child.name,
|
|
sub_child.widget.get_value(),
|
|
sub_child.datatype))
|
|
|
|
def set_name(self, name):
|
|
self.name = name
|
|
self.setText(0, self.name)
|
|
self.widget.set_name(name)
|
|
|
|
def get_value(self):
|
|
return self.widget.get_value()
|
|
|
|
def set_value(self, value):
|
|
self.widget.set_value(value)
|
|
|
|
def set_class_object(self, class_obj, value=''):
|
|
# TODO: should do stuff here if module or interface class is changed or
|
|
# datatype
|
|
self.class_object = class_obj
|
|
datatype = None if type(self.class_object) != Property else \
|
|
self.class_object.datatype
|
|
self.widget.set_datatype(datatype, value)
|
|
|
|
def get_children_names(self):
|
|
children = []
|
|
for i in range(0, self.childCount()):
|
|
children.append(self.child(i).name)
|
|
return children
|
|
|
|
def change_name(self):
|
|
if self.parent():
|
|
invalid_names = self.parent().get_children_names()
|
|
invalid_names.remove(self.name)
|
|
else:
|
|
invalid_names = ['']
|
|
dialog = ChangeNameDialog(self.name, invalid_names)
|
|
new_name = dialog.get_values()
|
|
if new_name:
|
|
self.set_name(new_name)
|
|
|
|
|
|
class ValueWidget(QWidget):
|
|
|
|
save_status_changed = pyqtSignal(bool)
|
|
|
|
def __init__(self, name='', value='', datatype=None, kind='', parent=None):
|
|
# TODO: implement: change module/interface class
|
|
super().__init__(parent)
|
|
self.datatype = datatype
|
|
self.layout = QVBoxLayout()
|
|
self.name_label = QLabel(name)
|
|
self.name_label.setStyleSheet('font-weight: bold')
|
|
self.kind = kind
|
|
if self.kind in [NODE, MODULE, INTERFACE]:
|
|
self.edit_btn = QPushButton()
|
|
setIcon(self.edit_btn, 'edit.png')
|
|
self.edit_btn.setIconSize(QSize(18, 18))
|
|
self.edit_btn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
|
|
self.edit_btn.setFlat(True)
|
|
layout = QHBoxLayout()
|
|
layout.addWidget(self.name_label)
|
|
layout.addWidget(self.edit_btn)
|
|
self.layout.addLayout(layout)
|
|
else:
|
|
self.layout.addWidget(self.name_label)
|
|
# TODO value_display.valueChanged.connect(emit_save_status_changed) ->
|
|
# implement or map a valueChanged signal for all possible
|
|
# value_displays:
|
|
# String = QLineEdit = textChanged
|
|
# Enum = QComboBox = editTextChanged
|
|
# Bool = QCheckBox = stateChanged
|
|
# Int, Float = Q(Double)SpinBox = ValueChanged
|
|
# Struct, Array = QGroupBox = clicked
|
|
# Tuple = QFrame = ???
|
|
if self.kind == PROPERTY and datatype and name != 'datatype':
|
|
# TODO what to do if property is datatype
|
|
self.value_display = get_widget(datatype)
|
|
self.value_display.set_value(value)
|
|
elif self.kind in [NODE, COMMENT]:
|
|
self.value_display = QTextEdit()
|
|
self.value_display.text = self.value_display.toPlainText
|
|
self.value_display.setText = self.value_display.setPlainText
|
|
self.value_display.textChanged.connect(self.emit_save_status_changed)
|
|
self.set_value(value)
|
|
else:
|
|
self.value_display = QLabel(value)
|
|
self.layout.addWidget(self.value_display)
|
|
self.setLayout(self.layout)
|
|
|
|
def get_value(self):
|
|
if self.datatype:
|
|
return self.value_display.get_value()
|
|
return self.value_display.text()
|
|
|
|
def set_value(self, value):
|
|
# TODO try block
|
|
if self.datatype:
|
|
self.value_display.set_value(value)
|
|
else:
|
|
self.value_display.setText(value)
|
|
|
|
def set_name(self, name):
|
|
if name != self.name_label.text():
|
|
self.emit_save_status_changed(False)
|
|
self.name_label.setText(name)
|
|
|
|
def set_datatype(self, datatype, value=''):
|
|
if datatype == self.datatype:
|
|
return
|
|
# TODO: remove old value_display
|
|
self.datatype = datatype
|
|
if self.kind == PROPERTY and datatype:
|
|
self.value_display = get_widget(datatype)
|
|
self.value_display.set_value(value)
|
|
else:
|
|
self.value_display = QLabel(value)
|
|
|
|
def emit_save_status_changed(self, status=False):
|
|
self.save_status_changed.emit(status)
|
|
|
|
|
|
class ChangeNameDialog(QDialog):
|
|
def __init__(self, current_name='', invalid_names=None, parent=None):
|
|
super().__init__(parent)
|
|
loadUi(self, 'change_name_dialog.ui')
|
|
self.invalid_names = invalid_names
|
|
self.name.setText(current_name)
|
|
self.name.selectAll()
|
|
# TODO: input mask
|
|
self.name.textChanged.connect(self.check_input)
|
|
|
|
def get_values(self):
|
|
if self.exec_() == QDialog.Accepted:
|
|
return self.name.text()
|
|
return None
|
|
|
|
def check_input(self, name):
|
|
set_name_edit_style(name in self.invalid_names or name == '', self.name,
|
|
self.button_box)
|