/
PLabelTableModel.py
136 lines (111 loc) · 4.54 KB
/
PLabelTableModel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
from PyQt5.QtCore import QAbstractTableModel, pyqtSignal, Qt, QModelIndex
from PyQt5.QtGui import QFont
from urh.signalprocessing.Message import Message
from urh.signalprocessing.MessageType import MessageType
from urh.signalprocessing.ProtocoLabel import ProtocolLabel
class PLabelTableModel(QAbstractTableModel):
header_labels = ["Name", "Start", "End", 'Color', 'Apply decoding']
label_removed = pyqtSignal(ProtocolLabel)
special_status_label_changed = pyqtSignal(ProtocolLabel)
apply_decoding_changed = pyqtSignal(ProtocolLabel)
def __init__(self, message: Message, field_types, parent=None):
"""
:param message:
:type field_types: list of FieldType
:param parent:
"""
super().__init__(parent)
self.row_count = len(message.message_type)
self.proto_view = 0
self.__message = None
self.message = message
self.message_type = message.message_type # type: MessageType
self.field_types_by_caption = {ft.caption: ft for ft in field_types}
self.update()
@property
def message(self) -> Message:
return self.__message
@message.setter
def message(self, value: Message):
self.__message = value
# Ensure bit alignment positions in message are set
self.__message.split(decode=True)
def update(self):
self.beginResetModel()
self.endResetModel()
def columnCount(self, parent: QModelIndex = None, *args, **kwargs):
return len(self.header_labels)
def rowCount(self, parent: QModelIndex = None, *args, **kwargs):
return len(self.message_type)
def headerData(self, section, orientation, role=Qt.DisplayRole):
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
return self.header_labels[section]
return super().headerData(section, orientation, role)
def data(self, index: QModelIndex, role=Qt.DisplayRole):
i, j = index.row(), index.column()
if role == Qt.DisplayRole:
try:
lbl = self.message_type[i]
except IndexError:
return False
if j == 0:
return lbl.name
elif j == 1:
return self.message.get_label_range(lbl, view=self.proto_view, decode=True)[0] + 1
elif j == 2:
return self.message.get_label_range(lbl, view=self.proto_view, decode=True)[1]
elif j == 3:
return lbl.color_index
elif j == 4:
return lbl.apply_decoding
elif role == Qt.TextAlignmentRole:
return Qt.AlignCenter
elif role == Qt.FontRole and j == 0:
font = QFont()
font.setItalic(self.message_type[i].field_type is None)
return font
else:
return None
def setData(self, index: QModelIndex, value, role=Qt.EditRole):
if value == "":
return True
i = index.row()
j = index.column()
if i >= len(self.message_type):
return False
lbl = self.message_type[i]
if j == 0:
lbl.name = value
type_before = type(lbl)
self.message_type.change_field_type_of_label(lbl, self.field_types_by_caption.get(value, None))
if type_before != ProtocolLabel or type(self.message_type[i]) != ProtocolLabel:
self.special_status_label_changed.emit(self.message_type[i])
elif j == 1:
lbl.start = self.message.convert_index(int(value - 1), from_view=self.proto_view, to_view=0, decoded=True)[0]
elif j == 2:
lbl.end = self.message.convert_index(int(value), from_view=self.proto_view, to_view=0, decoded=True)[0]
elif j == 3:
lbl.color_index = value
elif j == 4:
if bool(value) != lbl.apply_decoding:
lbl.apply_decoding = bool(value)
self.apply_decoding_changed.emit(lbl)
return True
def flags(self, index):
if not index.isValid():
return Qt.NoItemFlags
try:
_ = self.message_type[index.row()]
except IndexError:
return Qt.NoItemFlags
return Qt.ItemIsEditable | Qt.ItemIsEnabled | Qt.ItemIsSelectable
def remove_label(self, label):
self.message_type.remove(label)
self.update()
self.label_removed.emit(label)
def remove_label_at(self, index: int):
try:
label = self.message_type[index]
self.remove_label(label)
except IndexError:
pass