integrate new field types into application + italic font for labels with custom function

This commit is contained in:
Johannes Pohl
2017-01-08 16:07:50 +01:00
parent 2ed468b867
commit f2836d6dfb
5 changed files with 108 additions and 45 deletions

View File

@@ -18,6 +18,7 @@ from urh.models.ProtocolLabelListModel import ProtocolLabelListModel
from urh.models.ProtocolTableModel import ProtocolTableModel
from urh.models.ProtocolTreeModel import ProtocolTreeModel
from urh.plugins.PluginManager import PluginManager
from urh.signalprocessing.FieldType import FieldType
from urh.signalprocessing.MessageType import MessageType
from urh.signalprocessing.ProtocoLabel import ProtocolLabel
from urh.signalprocessing.ProtocolAnalyzer import ProtocolAnalyzer
@@ -139,6 +140,10 @@ class CompareFrameController(QFrame):
self.__set_default_message_type_ui_status()
self.field_types = FieldType.load_from_xml()
self.field_types_by_id = {field_type.id: field_type for field_type in self.field_types}
self.field_types_by_caption = {field_type.caption: field_type for field_type in self.field_types}
@property
def active_group_ids(self):
"""
@@ -192,8 +197,8 @@ class CompareFrameController(QFrame):
self.update_field_type_combobox()
def update_field_type_combobox(self):
field_types = [t.value for t in ProtocolLabel.Type if t.value] + self.active_message_type.custom_field_types
self.ui.listViewLabelNames.setItemDelegate(ComboBoxDelegate(field_types, is_editable=True))
field_types = [ft.caption for ft in self.field_types]
self.ui.listViewLabelNames.setItemDelegate(ComboBoxDelegate(field_types, is_editable=True, return_index=False))
def handle_files_dropped(self, files: list):
@@ -1448,3 +1453,19 @@ class CompareFrameController(QFrame):
self.ui.tblViewProtocol.setRowHidden(i, hide)
self.set_shown_protocols()
def reload_field_types(self):
self.field_types = FieldType.load_from_xml()
self.field_types_by_id = {field_type.id: field_type for field_type in self.field_types}
self.field_types_by_caption = {field_type.caption: field_type for field_type in self.field_types}
def refresh_field_types_for_labels(self):
self.reload_field_types()
for mt in self.proto_analyzer.message_types:
for lbl in (lbl for lbl in mt if lbl.type is not None): # type: ProtocolLabel
if lbl.type.id not in self.field_types_by_id:
lbl.type = None
else:
lbl.type = self.field_types_by_id[lbl.type.id]
self.update_field_type_combobox()

View File

@@ -656,6 +656,7 @@ class MainController(QMainWindow):
for sf in self.signal_tab_controller.signal_frames:
sf.refresh_protocol()
self.compare_frame_controller.refresh_field_types_for_labels()
self.compare_frame_controller.set_shown_protocols()
if "default_view" in changed_options.keys():

View File

@@ -1,6 +1,9 @@
from PyQt5.QtCore import QAbstractListModel, pyqtSignal, Qt, QModelIndex, QMimeData
from PyQt5.QtGui import QFont
from urh import constants
from urh.signalprocessing.FieldType import FieldType
from urh.signalprocessing.MessageType import MessageType
from urh.signalprocessing.ProtocoLabel import ProtocolLabel
from urh.signalprocessing.ProtocolAnalyzer import ProtocolAnalyzer
@@ -13,20 +16,15 @@ class ProtocolLabelListModel(QAbstractListModel):
def __init__(self, proto_analyzer: ProtocolAnalyzer, controller, parent=None):
super().__init__(parent)
self.proto_analyzer = proto_analyzer
self.message_type = controller.active_message_type
""":type urh.signalprocessing.MessageType.MessageType"""
self.message_type = controller.active_message_type # type: MessageType
self.controller = controller
""":type: urh.controller.CompareFrameController.CompareFrameController"""
self.field_types = [t for t in ProtocolLabel.Type if t.value] # without custom
self.controller = controller # type: CompareFrameController
def rowCount(self, QModelIndex_parent=None, *args, **kwargs):
return len(self.message_type)
def update(self):
self.message_type = self.controller.active_message_type
""":type: urh.signalprocessing.MessageType.MessageType """
self.message_type = self.controller.active_message_type # type: MessageType
self.layoutChanged.emit()
@@ -35,12 +33,19 @@ class ProtocolLabelListModel(QAbstractListModel):
if row >= len(self.message_type):
return
label = self.message_type[row]
if role == Qt.DisplayRole:
return self.message_type[row].name
return label.name
elif role == Qt.CheckStateRole:
return self.message_type[row].show
return label.show
elif role == Qt.BackgroundColorRole:
return constants.LABEL_COLORS[self.message_type[row].color_index]
return constants.LABEL_COLORS[label.color_index]
elif role == Qt.FontRole:
font = QFont()
font.setItalic(label.type is None or label.type.function == FieldType.Function.CUSTOM)
return font
def setData(self, index: QModelIndex, value, role=Qt.DisplayRole):
@@ -50,13 +55,11 @@ class ProtocolLabelListModel(QAbstractListModel):
self.protolabel_visibility_changed.emit(proto_label)
elif role == Qt.EditRole:
proto_label = self.message_type[index.row()]
try:
field_type = self.field_types[value]
proto_label.type = field_type
proto_label.name = field_type.value
except IndexError:
proto_label.type = ProtocolLabel.Type.CUSTOM
proto_label.name = self.message_type.custom_field_types[value - len(self.field_types)]
proto_label.name = value
if value in self.controller.field_types_by_caption:
proto_label.type = self.controller.field_types_by_caption[value]
else:
proto_label.type = None
self.protolabel_type_edited.emit()

View File

@@ -1,3 +1,5 @@
import random
import string
from enum import Enum
import xml.etree.cElementTree as ET
from xml.dom import minidom
@@ -7,7 +9,7 @@ from urh import constants
class FieldType(object):
__slots__ = ["caption", "function", "display_format_index"]
__slots__ = ["caption", "function", "display_format_index", "__id"]
class Function(Enum):
PREAMBLE = "preamble"
@@ -19,7 +21,7 @@ class FieldType(object):
CRC = "crc"
CUSTOM = "custom"
def __init__(self, caption: str, function: Function, display_format_index:int = None):
def __init__(self, caption: str, function: Function, display_format_index:int = None, id=None):
self.caption = caption
self.function = function
@@ -35,6 +37,24 @@ class FieldType(object):
else:
self.display_format_index = display_format_index
if id is None:
self.__id = ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(50))
else:
self.__id = id
def __eq__(self, other):
return isinstance(other, FieldType) and self.id_match(other.id)
@property
def id(self):
return self.__id
def id_match(self, id):
return self.__id == id
def __hash__(self):
return hash(self.id)
def __repr__(self):
return "FieldType: {0} - {1} ({2})".format(self.function.name, self.caption, self.display_format_index)
@@ -58,15 +78,32 @@ class FieldType(object):
result = []
for tag in e.findall("field_type"):
caption = tag.get("caption", "")
function = FieldType.Function[tag.get("function", "CUSTOM")]
display_format_index = int(tag.get("display_format_index", -1))
display_format_index = None if display_format_index == -1 else display_format_index
result.append(FieldType(caption, function, display_format_index))
result.append(FieldType.from_xml(tag))
return result
def to_xml(self):
return ET.Element("field_type", attrib={ "id": self.id,
"caption": self.caption,
"function": self.function.name,
"display_format_index": str(self.display_format_index)})
@staticmethod
def from_xml(tag):
"""
:param tag: ET.Element
:rtype: FieldType
"""
caption = tag.get("caption", "")
function = FieldType.Function[tag.get("function", "CUSTOM")]
display_format_index = int(tag.get("display_format_index", -1))
display_format_index = None if display_format_index == -1 else display_format_index
id = tag.get("id", None)
return FieldType(caption, function, display_format_index, id=id)
@staticmethod
def save_to_xml(field_types):
"""
@@ -76,10 +113,7 @@ class FieldType(object):
"""
root = ET.Element("field_types")
for field_type in field_types:
root.append(ET.Element("field_type", attrib={
"caption": field_type.caption,
"function": field_type.function.name,
"display_format_index": str(field_type.display_format_index)}))
root.append(field_type.to_xml())
xmlstr = minidom.parseString(ET.tostring(root)).toprettyxml(indent=" ")
with open(constants.FIELD_TYPE_SETTINGS, "w") as f:

View File

@@ -3,6 +3,7 @@ from enum import Enum
from PyQt5.QtCore import Qt
import xml.etree.ElementTree as ET
from urh.signalprocessing.FieldType import FieldType
from urh.signalprocessing.Interval import Interval
from urh.util.Formatter import Formatter
@@ -17,16 +18,6 @@ class ProtocolLabel(object):
DISPLAY_FORMATS = ["Bit", "Hex", "ASCII", "Decimal"]
SEARCH_TYPES = ["Number", "Bits", "Hex", "ASCII"]
class Type(Enum):
PREAMBLE = "preamble"
SYNC = "synchronization"
SRC_ADDRESS = "source address"
DST_ADDRESS = "destination address"
SEQUENCE_NUMBER = "sequence number"
CRC = "crc"
CUSTOM = ""
def __init__(self, name: str, start: int, end: int, color_index: int, fuzz_created=False, auto_created=False):
self.__name = name
self.start = start
@@ -41,12 +32,24 @@ class ProtocolLabel(object):
self.fuzz_created = fuzz_created
self.__type = ProtocolLabel.Type.CUSTOM
self.__type = None # type: FieldType
self.display_format_index = 0
self.auto_created = auto_created
@property
def type(self) -> FieldType:
return self.__type
@type.setter
def type(self, value: FieldType):
if value != self.type:
self.__type = value
# set viewtype for type
if hasattr(value, "display_format_index"):
self.display_format_index = value.display_format_index
@property
def name(self):
if not self.__name:
@@ -113,7 +116,7 @@ class ProtocolLabel(object):
"apply_decoding": str(self.apply_decoding), "index": str(index),
"show": str(self.show), "display_format_index": str(self.display_format_index),
"fuzz_me": str(self.fuzz_me), "fuzz_values": ",".join(self.fuzz_values),
"auto_created": str(self.auto_created), "type": self.type.name})
"auto_created": str(self.auto_created), "type_id": self.type.id})
@staticmethod
def from_xml(tag: ET.Element):
@@ -128,6 +131,7 @@ class ProtocolLabel(object):
result.fuzz_values = tag.get("fuzz_values", "").split(",")
result.display_format_index = int(tag.get("display_format_index", 0))
result.auto_created = True if tag.get("auto_created", 'False') == "True" else False
result.type = ProtocolLabel.Type[tag.get("type", '')]
type_id = tag.get("type_id", None)
result.type = ProtocolLabel.Type[tag.get("type", None)] # TODO: Need dict with type ids, to assign type
return result