diff --git a/src/urh/controller/CompareFrameController.py b/src/urh/controller/CompareFrameController.py index ba5d9575..f58bd48d 100644 --- a/src/urh/controller/CompareFrameController.py +++ b/src/urh/controller/CompareFrameController.py @@ -9,9 +9,7 @@ from PyQt5.QtWidgets import QMessageBox, QFrame, QAbstractItemView, QUndoStack, from urh import constants from urh.controller.MessageTypeDialogController import MessageTypeDialogController -from urh.controller.OptionsController import OptionsController from urh.controller.ProtocolLabelController import ProtocolLabelController -from urh.controller.ProtocolSniffDialogController import ProtocolSniffDialogController from urh.models.LabelValueTableModel import LabelValueTableModel from urh.models.ParticipantListModel import ParticipantListModel from urh.models.ProtocolLabelListModel import ProtocolLabelListModel @@ -28,7 +26,6 @@ from urh.signalprocessing.ProtocolGroup import ProtocolGroup from urh.ui.delegates.ComboBoxDelegate import ComboBoxDelegate from urh.ui.ui_analysis_frame import Ui_FAnalysis from urh.util import FileOperator -from urh.util.Errors import Errors from urh.util.Formatter import Formatter from urh.util.Logger import logger from urh.util.ProjectManager import ProjectManager @@ -41,16 +38,13 @@ class CompareFrameController(QFrame): participant_changed = pyqtSignal() show_config_field_types_triggered = pyqtSignal() - def __init__(self, plugin_manager: PluginManager, - project_manager: ProjectManager, parent): + def __init__(self, plugin_manager: PluginManager, project_manager: ProjectManager, parent): super().__init__(parent) self.proto_analyzer = ProtocolAnalyzer(None) self.project_manager = project_manager - self.decodings = [] - """:type: list of encoding """ - + self.decodings = [] # type: list[Encoder] self.load_decodings() self.ui = Ui_FAnalysis() @@ -59,82 +53,70 @@ class CompareFrameController(QFrame): self.ui.lDecimalSelection.setText("") self.ui.lHexSelection.setText("") self.plugin_manager = plugin_manager - clocale = QLocale() - self.decimal_point = clocale.decimalPoint() + self.decimal_point = QLocale().decimalPoint() self.__selected_message_type = self.proto_analyzer.default_message_type self.fill_message_type_combobox() - self.participant_list_model = ParticipantListModel(project_manager.participants) self.ui.listViewParticipants.setModel(self.participant_list_model) self.__active_group_ids = [0] self.selected_protocols = set() - self.searchselectsearch_menu = QMenu() - self.search_action = self.searchselectsearch_menu.addAction("Search") - self.select_action = self.searchselectsearch_menu.addAction("Select all") - self.filter_action = self.searchselectsearch_menu.addAction("Filter") - self.ui.btnSearchSelectFilter.setMenu(self.searchselectsearch_menu) + self.search_select_search_menu = QMenu() + self.search_action = self.search_select_search_menu.addAction(self.tr("Search")) + self.select_action = self.search_select_search_menu.addAction(self.tr("Select all")) + self.filter_action = self.search_select_search_menu.addAction(self.tr("Filter")) + self.ui.btnSearchSelectFilter.setMenu(self.search_select_search_menu) - self.analyze_menue = QMenu() - self.assign_participants_action = self.analyze_menue.addAction("Assign participants") + self.analyze_menu = QMenu() + self.assign_participants_action = self.analyze_menu.addAction(self.tr("Assign participants")) self.assign_participants_action.setCheckable(True) self.assign_participants_action.setChecked(True) - self.assign_decodings_action = self.analyze_menue.addAction("Assign decodings") + self.assign_decodings_action = self.analyze_menu.addAction(self.tr("Assign decodings")) self.assign_decodings_action.setCheckable(True) self.assign_decodings_action.setChecked(True) - self.assign_message_type_action = self.analyze_menue.addAction("Assign message type") + self.assign_message_type_action = self.analyze_menu.addAction(self.tr("Assign message type")) self.assign_message_type_action.setCheckable(True) self.assign_message_type_action.setChecked(True) - self.assign_labels_action = self.analyze_menue.addAction("Assign labels") + self.assign_labels_action = self.analyze_menu.addAction(self.tr("Assign labels")) self.assign_labels_action.setCheckable(True) self.assign_labels_action.setChecked(True) - self.ui.btnAnalyze.setMenu(self.analyze_menue) + self.ui.btnAnalyze.setMenu(self.analyze_menu) self.ui.lFilterShown.hide() - self.protocol_model = ProtocolTableModel(self.proto_analyzer, project_manager.participants, self) - """:type: ProtocolTableModel""" - self.protocol_label_list_model = ProtocolLabelListModel(self.proto_analyzer, controller=self) - """:type: ProtocolLabelListModel""" + self.protocol_model = ProtocolTableModel(self.proto_analyzer, project_manager.participants, + self) # type: ProtocolTableModel + self.protocol_label_list_model = ProtocolLabelListModel(self.proto_analyzer, + controller=self) # type: ProtocolLabelListModel - self.label_value_model = LabelValueTableModel(self.proto_analyzer, controller=self) + self.label_value_model = LabelValueTableModel(self.proto_analyzer, + controller=self) # type: LabelValueTableModel self.ui.tblViewProtocol.setModel(self.protocol_model) self.ui.tblViewProtocol.controller = self self.ui.tblLabelValues.setModel(self.label_value_model) self.ui.listViewLabelNames.setModel(self.protocol_label_list_model) - self.create_connects() - - self.fill_decoding_combobox() - #self.ui.splitter.setStretchFactor(1, 1) - self.selection_timer = QTimer() self.selection_timer.setSingleShot(True) - self.selection_timer.timeout.connect(self.on_table_selection_timer_timeout) + self.setFrameStyle(0) self.setAcceptDrops(False) - self.proto_tree_model = ProtocolTreeModel(controller=self) - """:type: ProtocolTreeModel """ - self.proto_tree_model.item_dropped.connect(self.handle_item_in_proto_tree_dropped) + self.proto_tree_model = ProtocolTreeModel(controller=self) # type: ProtocolTreeModel self.ui.treeViewProtocols.setModel(self.proto_tree_model) + self.create_connects() + self.fill_decoding_combobox() + self.rows_for_protocols = {} self.__protocols = None self.min_height = self.minimumHeight() self.max_height = self.maximumHeight() - self.__show_protocol_seperation = True - - self.protocol_model.ref_index_changed.connect(self.handle_ref_index_changed) - self.ui.tblViewProtocol.row_visibilty_changed.connect(self.set_shown_protocols) - self.ui.treeViewProtocols.selection_changed.connect(self.handle_tree_view_selection_changed) - self.proto_tree_model.group_deleted.connect(self.handle_group_deleted) - self.proto_tree_model.proto_to_group_added.connect(self.expand_group_node) - self.proto_tree_model.group_added.connect(self.handle_group_added) + self.__show_protocol_separation = True self.__set_decoding_error_label(None) @@ -144,6 +126,8 @@ class CompareFrameController(QFrame): 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} + # region properties + @property def active_group_ids(self): """ @@ -157,7 +141,6 @@ class CompareFrameController(QFrame): def active_group_ids(self, val: list): self.__active_group_ids = val - @property def groups(self): """ @@ -175,7 +158,6 @@ class CompareFrameController(QFrame): """ return [self.proto_tree_model.group_at(i) for i in self.active_group_ids] - @property def active_message_type(self) -> MessageType: return self.__selected_message_type @@ -196,19 +178,188 @@ class CompareFrameController(QFrame): self.update_field_type_combobox() + @property + def selected_messages(self): + return self.ui.tblViewProtocol.selected_messages + + @property + def protocol_undo_stack(self) -> QUndoStack: + return self.protocol_model.undo_stack + + @property + def protocols(self): + """ + :rtype: dict[int, list of ProtocolAnalyzer] + """ + if self.__protocols is None: + self.__protocols = self.proto_tree_model.protocols + return self.__protocols + + @property + def protocol_list(self): + """ + :rtype: list of ProtocolAnalyzer + """ + result = [] + for group in self.groups: + result.extend(group.protocols) + return result + + @property + def show_protocol_separation(self): + return self.__show_protocol_separation + + @show_protocol_separation.setter + def show_protocol_separation(self, value: bool): + self.__show_protocol_separation = value + + if not value: + for line in self.protocol_model.first_messages: + self.ui.tblViewProtocol.setRowHeight(line, constants.SEPARATION_ROW_HEIGHT) + + self.set_shown_protocols() + + # endregion + + def __set_decoding_error_label(self, message: Message): + if message: + errors = message.decoding_errors + percent = 100 * (errors / len(message)) + color = "green" if errors == 0 else "red" + self.ui.lDecodingErrorsValue.setStyleSheet("color: " + color) + self.ui.lDecodingErrorsValue.setText(locale.format_string("%d (%.02f%%)", (errors, percent))) + + state = message.decoding_state if message.decoding_state != message.decoder.ErrorState.SUCCESS else "" + self.ui.labelDecodingState.setText(state) + self.ui.labelDecodingState.setStyleSheet("color: red") + else: + self.ui.lDecodingErrorsValue.setText("") + self.ui.labelDecodingState.setText("") + + # self.ui.lSupport.setStyleSheet("color: green") + + def create_connects(self): + self.protocol_undo_stack.indexChanged.connect(self.on_undo_stack_index_changed) + self.ui.cbProtoView.currentIndexChanged.connect(self.on_protocol_view_changed) + self.ui.cbDecoding.currentIndexChanged.connect(self.on_combobox_decoding_current_index_changed) + self.ui.cbShowDiffs.clicked.connect(self.on_chkbox_show_differences_clicked) + self.ui.chkBoxOnlyShowLabelsInProtocol.stateChanged.connect(self.on_check_box_show_only_labels_state_changed) + self.ui.chkBoxShowOnlyDiffs.stateChanged.connect(self.on_check_box_show_only_diffs_state_changed) + + self.ui.tblViewProtocol.show_interpretation_clicked.connect(self.show_interpretation_clicked.emit) + self.ui.tblViewProtocol.protocol_view_change_clicked.connect(self.ui.cbProtoView.setCurrentIndex) + self.ui.tblViewProtocol.selection_changed.connect(self.on_table_selection_changed) + self.ui.tblViewProtocol.writeable_changed.connect(self.on_writeable_changed) + self.ui.tblViewProtocol.row_visibility_changed.connect(self.on_tbl_view_protocol_row_visibility_changed) + self.ui.tblViewProtocol.edit_label_clicked.connect(self.on_edit_label_clicked_in_table) + self.ui.tblViewProtocol.participant_changed.connect(self.on_participant_edited) + self.ui.tblViewProtocol.messagetype_selected.connect(self.on_message_type_selected) + self.ui.tblViewProtocol.new_messagetype_clicked.connect(self.on_table_new_message_type_clicked) + self.ui.tblViewProtocol.files_dropped.connect(self.on_files_dropped) + + self.ui.btnSearchSelectFilter.clicked.connect(self.on_btn_search_clicked) + self.ui.btnNextSearch.clicked.connect(self.on_btn_next_search_clicked) + self.ui.btnPrevSearch.clicked.connect(self.on_btn_prev_search_clicked) + self.ui.lineEditSearch.returnPressed.connect(self.ui.btnSearchSelectFilter.click) + self.search_action.triggered.connect(self.on_search_action_triggered) + self.select_action.triggered.connect(self.on_select_action_triggered) + self.filter_action.triggered.connect(self.on_filter_action_triggered) + + self.protocol_label_list_model.protolabel_visibility_changed.connect(self.on_protolabel_visibility_changed) + self.protocol_label_list_model.protolabel_type_edited.connect(self.label_value_model.update) + self.protocol_label_list_model.label_removed.connect(self.on_label_removed) + + self.ui.btnSaveProto.clicked.connect(self.on_btn_save_protocol_clicked) + self.ui.btnAnalyze.clicked.connect(self.on_btn_analyze_clicked) + + self.ui.listViewLabelNames.editActionTriggered.connect(self.on_edit_label_action_triggered) + self.ui.listViewLabelNames.configureActionTriggered.connect(self.show_config_field_types_triggered.emit) + self.ui.listViewLabelNames.selection_changed.connect(self.on_label_selection_changed) + + self.protocol_model.ref_index_changed.connect(self.on_ref_index_changed) + + self.project_manager.project_updated.connect(self.on_project_updated) + self.participant_list_model.show_state_changed.connect(self.on_participant_show_state_changed) + + self.ui.btnAddMessagetype.clicked.connect(self.on_btn_new_message_type_clicked) + self.ui.btnRemoveMessagetype.clicked.connect(self.on_btn_remove_message_type_clicked) + + self.ui.cbMessagetypes.currentIndexChanged.connect(self.on_combobox_messagetype_index_changed) + self.ui.cbMessagetypes.editTextChanged.connect(self.on_message_type_name_edited) + + self.ui.btnMessagetypeSettings.clicked.connect(self.on_btn_message_type_settings_clicked) + self.selection_timer.timeout.connect(self.on_table_selection_timer_timeout) + self.ui.treeViewProtocols.selection_changed.connect(self.on_tree_view_selection_changed) + self.proto_tree_model.item_dropped.connect(self.on_item_in_proto_tree_dropped) + + self.proto_tree_model.group_deleted.connect(self.on_group_deleted) + self.proto_tree_model.proto_to_group_added.connect(self.on_proto_to_group_added) + self.proto_tree_model.group_added.connect(self.on_group_added) + + def get_message_type_for_label(self, lbl: ProtocolLabel) -> MessageType: + for msg_type in self.proto_analyzer.message_types: + if lbl in msg_type: + return msg_type + return None + def update_field_type_combobox(self): field_types = [ft.caption for ft in self.field_types] self.ui.listViewLabelNames.setItemDelegate(ComboBoxDelegate(field_types, is_editable=True, return_index=False)) + def set_decoding(self, decoding: Encoder, messages=None): + """ - def handle_files_dropped(self, files: list): - self.files_dropped.emit(files) + :param decoding: + :param messages: None = set for all messages + :return: + """ + if decoding is None: + self.show_decoding_clicked.emit() + else: + if messages is None: + messages = self.proto_analyzer.messages + if len(messages) > 10: + reply = QMessageBox.question(self, "Set decoding", + "Do you want to apply the selected decoding to {} messages?".format( + len(messages)), QMessageBox.Yes | QMessageBox.No) + if reply != QMessageBox.Yes: + self.ui.cbDecoding.blockSignals(True) + self.ui.cbDecoding.setCurrentText("...") + self.ui.cbDecoding.blockSignals(False) + return + self.show_all_cols() + + for msg in messages: + msg.decoder = decoding + + self.clear_search() + + selected = self.ui.tblViewProtocol.selectionModel().selection() + + if not selected.isEmpty() and self.isVisible() and self.proto_analyzer.num_messages > 0: + max_row = numpy.max([rng.bottom() for rng in selected]) + max_row = max_row if max_row < len(self.proto_analyzer.messages) else -1 + try: + msg = self.proto_analyzer.messages[max_row] + except IndexError: + msg = None + self.__set_decoding_error_label(msg) + else: + self.__set_decoding_error_label(None) + + self.protocol_model.update() + self.protocol_label_list_model.update() + self.label_value_model.update() + + for lbl in self.proto_analyzer.protocol_labels: + self.set_protocol_label_visibility(lbl) + + self.ui.tblViewProtocol.resize_columns() def load_decodings(self): if self.project_manager.project_file: - prefix = os.path.realpath(os.path.dirname( - self.project_manager.project_file)) + prefix = os.path.realpath(os.path.dirname(self.project_manager.project_file)) else: prefix = os.path.realpath(os.path.join(constants.SETTINGS.fileName(), "..")) @@ -229,7 +380,6 @@ class CompareFrameController(QFrame): constants.DECODING_DIFFERENTIAL]) ] - try: f = open(os.path.join(prefix, constants.DECODINGS_FILE), "r") except FileNotFoundError: @@ -256,105 +406,6 @@ class CompareFrameController(QFrame): if len(self.decodings) == 0: self.decodings = fallback - - @property - def selected_messages(self): - return self.ui.tblViewProtocol.selected_messages - - @property - def protocol_undo_stack(self) -> QUndoStack: - return self.protocol_model.undo_stack - - @property - def name(self): - return self.ui.lSignalName.text() - - @name.setter - def name(self, value: str): - self.ui.lSignalName.setText(value) - - @property - def protocols(self): - """ - :rtype: dict[int, list of ProtocolAnalyzer] - """ - if self.__protocols is None: - self.__protocols = self.proto_tree_model.protocols - return self.__protocols - - @property - def protocol_list(self): - """ - :rtype: list of ProtocolAnalyzer - """ - result = [] - for group in self.groups: - result.extend(group.protocols) - return result - - @property - def show_protocol_seperation(self): - return self.__show_protocol_seperation - - @show_protocol_seperation.setter - def show_protocol_seperation(self, value: bool): - self.__show_protocol_seperation = value - - if not value: - for line in self.protocol_model.first_messages: - self.ui.tblViewProtocol.setRowHeight(line, constants.SEPARATION_ROW_HEIGHT) - - self.set_shown_protocols() - - def create_connects(self): - self.protocol_undo_stack.indexChanged.connect(self.on_undo_stack_index_changed) - - self.ui.cbShowDiffs.stateChanged.connect(self.on_chkbox_show_differences_changed) - self.ui.cbProtoView.currentIndexChanged.connect(self.on_protocol_view_changed) - self.ui.tblViewProtocol.protocol_view_change_clicked.connect(self.ui.cbProtoView.setCurrentIndex) - self.ui.cbDecoding.currentIndexChanged.connect(self.on_cbDecoding_currentIndexChanged) - self.ui.tblViewProtocol.show_interpretation_clicked.connect(self.show_interpretation_clicked.emit) - - self.ui.btnSearchSelectFilter.clicked.connect(self.search) - - self.ui.btnNextSearch.clicked.connect(self.next_search_result) - self.ui.btnPrevSearch.clicked.connect(self.prev_search_result) - self.protocol_label_list_model.protolabel_visibility_changed.connect(self.set_protocol_label_visibility) - self.protocol_label_list_model.protolabel_visibility_changed.connect(self.label_value_model.update) - self.ui.btnSaveProto.clicked.connect(self.save_protocol) - self.protocol_label_list_model.protolabel_type_edited.connect(self.label_value_model.update) - self.ui.tblViewProtocol.selection_changed.connect(self.handle_table_selection_changed) - self.ui.listViewLabelNames.editActionTriggered.connect(self.show_protocol_labels) - self.ui.tblViewProtocol.writeable_changed.connect(self.handle_writeable_changed) - self.protocol_label_list_model.label_removed.connect(self.handle_label_removed) - self.ui.listViewLabelNames.selection_changed.connect(self.handle_label_selection_changed) - self.ui.chkBoxOnlyShowLabelsInProtocol.stateChanged.connect(self.handle_show_only_checkbox_changed) - self.ui.chkBoxShowOnlyDiffs.stateChanged.connect(self.handle_show_only_checkbox_changed) - self.protocol_model.ref_index_changed.connect(self.handle_show_only_checkbox_changed) - self.ui.tblViewProtocol.row_visibilty_changed.connect(self.handle_show_only_checkbox_changed) - self.ui.tblViewProtocol.edit_label_clicked.connect(self.on_edit_label_clicked_in_table) - self.ui.btnAnalyze.clicked.connect(self.on_btn_analyze_clicked) - self.ui.tblViewProtocol.files_dropped.connect(self.handle_files_dropped) - self.project_manager.project_updated.connect(self.on_project_updated) - self.participant_list_model.show_state_changed.connect(self.set_participant_visibility) - self.ui.tblViewProtocol.participant_changed.connect(self.on_participant_edited) - self.ui.tblViewProtocol.messagetype_selected.connect(self.on_message_type_selected) - self.ui.tblViewProtocol.new_messagetype_clicked.connect(self.on_new_message_type_clicked) - self.ui.btnAddMessagetype.clicked.connect(self.on_new_message_type_clicked) - self.ui.btnRemoveMessagetype.clicked.connect(self.on_remove_message_type_clicked) - self.ui.listViewLabelNames.configureActionTriggered.connect(self.show_config_field_types_triggered.emit) - self.ui.lineEditSearch.returnPressed.connect(self.ui.btnSearchSelectFilter.click) - - self.ui.cbMessagetypes.currentIndexChanged.connect(self.on_cbmessagetype_index_changed) - self.ui.cbMessagetypes.editTextChanged.connect(self.on_messagetype_name_edited) - - self.search_action.triggered.connect(self.__set_mode_to_search) - self.select_action.triggered.connect(self.__set_mode_to_select_all) - self.filter_action.triggered.connect(self.__set_mode_to_filter) - - self.ui.btnMessagetypeSettings.clicked.connect(self.on_btn_messagetype_settings_clicked) - - def refresh_existing_encodings(self): """ Refresh existing encodings for messages, when encoding was changed by user in dialog @@ -398,32 +449,6 @@ class CompareFrameController(QFrame): if self.ui.cbMessagetypes.count() <= 1: self.ui.cbMessagetypes.setEditable(False) - def on_chkbox_show_differences_changed(self): - chkd = self.ui.cbShowDiffs.isChecked() - - if chkd: - if self.protocol_model.refindex == -1: - self.protocol_model.refindex = 0 - else: - self.ui.chkBoxShowOnlyDiffs.setChecked(False) - self.protocol_model.refindex = -1 - - def mousePressEvent(self, event): - return - - def get_message_numbers_for_groups(self) -> dict: - result = {} - prev = 0 - for i in sorted(self.protocols.keys()): - group_protos = self.protocols[i] - num_messages = prev - for gp in group_protos: - if gp.show: - num_messages += gp.num_messages - result[i] = (prev, num_messages) - prev = num_messages - return result - def add_protocol(self, protocol: ProtocolAnalyzer, group_id: int = 0) -> ProtocolAnalyzer: self.__protocols = None self.proto_tree_model.add_protocol(protocol, group_id) @@ -462,6 +487,37 @@ class CompareFrameController(QFrame): self.add_protocol(proto_analyzer, group_id=self.proto_tree_model.ngroups - 1) self.refresh() + def add_protocol_label(self, start: int, end: int, messagenr: int, proto_view: int, edit_label_name=True): + # Ensure atleast one Group is active + start, end = self.proto_analyzer.convert_range(start, end, proto_view, 0, decoded=True, message_indx=messagenr) + proto_label = self.proto_analyzer.messages[messagenr].message_type.add_protocol_label(start=start, end=end) + + self.protocol_label_list_model.update() + self.protocol_model.update() + + if edit_label_name: + try: + index = self.protocol_label_list_model.message_type.index(proto_label) + self.ui.listViewLabelNames.edit(self.protocol_label_list_model.createIndex(index, 0)) + except ValueError: + pass + + self.label_value_model.update() + + return True + + def add_message_type(self, selected_messages: list = None): + selected_messages = selected_messages if isinstance(selected_messages, list) else [] + self.proto_analyzer.add_new_message_type(labels=self.proto_analyzer.default_message_type) + self.fill_message_type_combobox() + self.ui.cbMessagetypes.setEditable(True) + self.active_message_type = self.proto_analyzer.message_types[-1] + for msg in selected_messages: + msg.message_type = self.active_message_type + self.ui.cbMessagetypes.setFocus() + self.ui.btnRemoveMessagetype.show() + self.protocol_model.update() + def remove_protocol(self, protocol: ProtocolAnalyzer): self.__protocols = None self.proto_tree_model.remove_protocol(protocol) @@ -525,12 +581,11 @@ class CompareFrameController(QFrame): rows_for_cur_proto = list(range(prev_line, line)) self.rows_for_protocols[proto] = rows_for_cur_proto[:] - prev_line = line if line != 0: first_msg_indices.append(line) - if not self.show_protocol_seperation: + if not self.show_protocol_separation: self.protocol_model.first_messages[:] = [] self.updateUI() return @@ -547,23 +602,660 @@ class CompareFrameController(QFrame): except (KeyError, ValueError): pass - # Hidden Rows berücksichtigen for i in range(self.protocol_model.row_count): if self.ui.tblViewProtocol.isRowHidden(i) and i in first_msg_indices: indx = first_msg_indices.index(i) first_msg_indices[indx] += 1 - if indx < len(first_msg_indices) and first_msg_indices[indx] >= first_msg_indices[indx+1]: + if indx < len(first_msg_indices) and first_msg_indices[indx] >= first_msg_indices[indx + 1]: del first_msg_indices[indx] for line in first_msg_indices: self.ui.tblViewProtocol.setRowHeight(line, constants.SEPARATION_ROW_HEIGHT) self.protocol_model.first_messages = first_msg_indices[:] - #self.set_decoding(self.decodings[self.ui.cbDecoding.currentIndex()]) self.updateUI() - self.on_chkbox_show_differences_changed() + self.show_differences(self.ui.cbShowDiffs.isChecked()) + + def restore_selection(self, old_view: int, sel_cols, sel_rows): + if len(sel_cols) == 0 or len(sel_rows) == 0: + return + + startCol, endCol = numpy.min(sel_cols), numpy.max(sel_cols) + startRow, endRow = numpy.min(sel_rows), numpy.max(sel_rows) + new_view = self.ui.cbProtoView.currentIndex() + + message = self.proto_analyzer.messages[endRow] + startCol = message.convert_index(startCol, old_view, new_view, True)[0] + endCol = message.convert_index(endCol, old_view, new_view, True)[1] + + endCol = endCol if endCol < len(self.protocol_model.display_data[endRow]) else len( + self.protocol_model.display_data[endRow]) - 1 + + startindex = self.protocol_model.index(startRow, startCol) + endindex = self.protocol_model.index(endRow, endCol) + mid_index = self.protocol_model.index(int((startRow + endRow) / 2), int((startCol + endCol) / 2)) + + sel = QItemSelection() + sel.select(startindex, endindex) + + self.ui.tblViewProtocol.selectionModel().select(sel, QItemSelectionModel.ClearAndSelect) + self.ui.tblViewProtocol.scrollTo(mid_index) + + def expand_group_node(self, group_id): + self.ui.treeViewProtocols.expand( + self.proto_tree_model.createIndex(group_id, 0, self.proto_tree_model.rootItem.child(group_id))) + + def updateUI(self, ignore_table_model=False, resize_table=True): + if not ignore_table_model: + self.protocol_model.update() + + self.protocol_label_list_model.update() + self.proto_tree_model.layoutChanged.emit() + self.label_value_model.update() + self.protocol_label_list_model.update() + + if resize_table: + self.ui.tblViewProtocol.resize_columns() + + def refresh(self): + self.__protocols = None + self.set_shown_protocols() + self.updateUI() + + def reset(self): + self.proto_tree_model.rootItem.clearChilds() + self.proto_tree_model.rootItem.addGroup() + for message_type in self.proto_analyzer.message_types: + message_type.clear() + self.refresh() + + def show_protocol_label_dialog(self, preselected_index: int): + view_type = self.ui.cbProtoView.currentIndex() + max_end = max(len(msg) for msg in self.proto_analyzer.messages) if self.proto_analyzer.messages else 10000 + label_controller = ProtocolLabelController(preselected_index=preselected_index, + message_type=self.active_message_type, + max_end=max_end, viewtype=view_type, parent=self) + label_controller.apply_decoding_changed.connect(self.on_apply_decoding_changed) + label_controller.exec_() + + self.protocol_label_list_model.update() + self.update_field_type_combobox() + self.label_value_model.update() + self.show_all_cols() + for lbl in self.proto_analyzer.protocol_labels: + self.set_protocol_label_visibility(lbl) + self.set_show_only_status() + self.protocol_model.update() + self.ui.tblViewProtocol.resize_columns() + + def search(self): + value = self.ui.lineEditSearch.text() + nresults = self.protocol_model.find_protocol_value(value) + + if nresults > 0: + self.ui.btnNextSearch.setEnabled(True) + self.ui.btnPrevSearch.setEnabled(False) + self.ui.lSearchTotal.setText(str(nresults)) + self.ui.lSearchCurrent.setText("0") + self.next_search_result() + else: + self.clear_search() + + def select_all_search_results(self): + self.search() + self.ui.tblViewProtocol.clearSelection() + + for search_result in self.protocol_model.search_results: + startindex = self.protocol_model.index(search_result[0], search_result[1]) + endindex = self.protocol_model.index(search_result[0], + search_result[1] + len(self.protocol_model.search_value) - 1) + + sel = QItemSelection() + sel.select(startindex, endindex) + + self.ui.tblViewProtocol.selectionModel().select(sel, QItemSelectionModel.Select) + self.ui.tblViewProtocol.scrollTo(startindex, QAbstractItemView.PositionAtCenter) + + self.ui.tblViewProtocol.setFocus() + + def filter_search_results(self): + if self.ui.btnSearchSelectFilter.text() != "Filter": + return + + if self.ui.lineEditSearch.text(): + self.search() + self.ui.tblLabelValues.clearSelection() + + matching_rows = set(search_result[0] for search_result in self.protocol_model.search_results) + self.ui.tblViewProtocol.blockSignals(True) + rc = self.protocol_model.row_count + for i in set(range(0, rc)) - matching_rows: + self.ui.tblViewProtocol.hide_row(row=i) + self.ui.tblViewProtocol.blockSignals(False) + self.ui.tblViewProtocol.row_visibility_changed.emit() + + self.ui.lFilterShown.setText(self.tr("shown: {}/{}".format(rc - len(self.protocol_model.hidden_rows), rc))) + + else: + for i in range(0, self.protocol_model.row_count): + self.ui.tblViewProtocol.showRow(i) + + self.ui.lFilterShown.setText("") + self.set_shown_protocols() + + def next_search_result(self): + index = int(self.ui.lSearchCurrent.text()) + self.ui.lSearchTotal.setText((str(len(self.protocol_model.search_results)))) + try: + search_result = self.protocol_model.search_results[index] + startindex = self.protocol_model.index(search_result[0], search_result[1]) + endindex = self.protocol_model.index(search_result[0], + search_result[1] + len(self.protocol_model.search_value) - 1) + + sel = QItemSelection() + sel.select(startindex, endindex) + + self.ui.tblViewProtocol.selectionModel().select(sel, QItemSelectionModel.ClearAndSelect) + self.ui.tblViewProtocol.scrollTo(startindex, QAbstractItemView.PositionAtCenter) + + self.ui.lSearchCurrent.setText(str(index + 1)) + except IndexError: + self.ui.lSearchCurrent.setText("-") + finally: + if index + 1 == len(self.protocol_model.search_results): + self.ui.btnNextSearch.setEnabled(False) + + if index > 0 and len(self.protocol_model.search_results) > 0: + self.ui.btnPrevSearch.setEnabled(True) + + def prev_search_result(self): + index = int(self.ui.lSearchCurrent.text()) - 2 + + try: + search_result = self.protocol_model.search_results[index] + startindex = self.protocol_model.index(search_result[0], search_result[1]) + endindex = self.protocol_model.index(search_result[0], + search_result[1] + len(self.protocol_model.search_value) - 1) + + sel = QItemSelection() + sel.select(startindex, endindex) + + self.ui.tblViewProtocol.selectionModel().select(sel, QItemSelectionModel.ClearAndSelect) + self.ui.tblViewProtocol.scrollTo(startindex, QAbstractItemView.PositionAtCenter) + + self.ui.lSearchCurrent.setText(str(index + 1)) + except IndexError: + self.ui.lSearchCurrent.setText("-") + finally: + if self.ui.lSearchCurrent.text() == "1": + self.ui.btnPrevSearch.setEnabled(False) + + if len(self.protocol_model.search_results) > 0: + self.ui.btnNextSearch.setEnabled(True) + + def clear_search(self): + self.ui.lineEditSearch.clear() + self.ui.btnPrevSearch.setEnabled(False) + self.ui.btnNextSearch.setEnabled(False) + self.ui.lSearchTotal.setText("-") + self.ui.lSearchCurrent.setText("-") + self.protocol_model.search_results[:] = [] + self.protocol_model.search_value = "" + + def set_protocol_label_visibility(self, lbl: ProtocolLabel, message: Message = None): + try: + message = message if message else next( + msg for msg in self.proto_analyzer.messages if lbl in msg.message_type) + start, end = message.get_label_range(lbl, self.ui.cbProtoView.currentIndex(), True) + + for i in range(start, end): + self.ui.tblViewProtocol.setColumnHidden(i, not lbl.show) + except Exception as e: + pass + + def show_all_cols(self): + for i in range(self.protocol_model.col_count): + self.ui.tblViewProtocol.showColumn(i) + + def save_protocol(self): + for msg in self.proto_analyzer.messages: + if not msg.decoder.is_nrz: + reply = QMessageBox.question(self, "Saving of protocol", + "You want to save this protocol with an encoding different from NRZ.\n" + "This may cause loss of information if you load it again.\n\n" + "Save anyway?", QMessageBox.Yes | QMessageBox.No) + if reply != QMessageBox.Yes: + return + else: + break + + text = "protocol" + filename = FileOperator.get_save_file_name("{0}.proto".format(text), parent=self, caption="Save protocol") + + if not filename: + return + + self.proto_analyzer.to_xml_file(filename=filename, decoders=self.decodings, + participants=self.project_manager.participants, write_bits=True) + + def show_differences(self, show_differences: bool): + if show_differences: + if self.protocol_model.refindex == -1: + self.protocol_model.refindex = 0 + else: + self.ui.chkBoxShowOnlyDiffs.setChecked(False) + self.protocol_model.refindex = -1 + + def set_show_only_status(self): + """ + Handles the different combinations of the show only checkboxes, namely: + - Show only labels + - Show only Diffs + """ + if self.ui.chkBoxShowOnlyDiffs.isChecked() and not self.ui.cbShowDiffs.isChecked(): + self.ui.cbShowDiffs.setChecked(True) + self.show_differences(True) + + if self.ui.chkBoxOnlyShowLabelsInProtocol.isChecked() and self.ui.chkBoxShowOnlyDiffs.isChecked(): + self.show_only_diffs_and_labels() + elif self.ui.chkBoxOnlyShowLabelsInProtocol.isChecked() and not self.ui.chkBoxShowOnlyDiffs.isChecked(): + self.show_only_labels() + elif not self.ui.chkBoxOnlyShowLabelsInProtocol.isChecked() and self.ui.chkBoxShowOnlyDiffs.isChecked(): + self.show_only_diffs() + else: + self.restore_visibility() + + self.ui.tblViewProtocol.resize_columns() + + def show_only_labels(self): + visible_columns = set() + for msg in self.proto_analyzer.messages: + for lbl in msg.message_type: + if lbl.show: + start, end = msg.get_label_range(lbl=lbl, view=self.ui.cbProtoView.currentIndex(), + decode=True) + visible_columns |= (set(range(start, end))) + + for i in range(self.protocol_model.col_count): + if i in visible_columns: + self.ui.tblViewProtocol.showColumn(i) + else: + self.ui.tblViewProtocol.hideColumn(i) + + def show_only_diffs(self): + visible_rows = [i for i in range(self.protocol_model.row_count) if not self.ui.tblViewProtocol.isRowHidden(i) + and i != self.protocol_model.refindex] + + visible_diff_columns = [diff_col for i in visible_rows for diff_col in self.protocol_model.diff_columns[i]] + + for j in range(self.protocol_model.col_count): + if j in visible_diff_columns: + self.ui.tblViewProtocol.showColumn(j) + else: + self.ui.tblViewProtocol.hideColumn(j) + + def show_only_diffs_and_labels(self): + visible_label_columns = set() + for lbl in self.proto_analyzer.protocol_labels: + if lbl.show: + start, end = self.proto_analyzer.messages[0].get_label_range(lbl, self.ui.cbProtoView.currentIndex(), + True) + visible_label_columns |= (set(range(start, end))) + + visible_rows = [i for i in range(self.protocol_model.row_count) if not self.ui.tblViewProtocol.isRowHidden(i) + and i != self.protocol_model.refindex] + + visible_diff_columns = set([diff_col for i in visible_rows for diff_col in self.protocol_model.diff_columns[i]]) + + visible_cols = visible_label_columns & visible_diff_columns + for j in range(self.protocol_model.col_count): + if j in visible_cols: + self.ui.tblViewProtocol.showColumn(j) + else: + self.ui.tblViewProtocol.hideColumn(j) + + def restore_visibility(self): + selected = self.ui.tblViewProtocol.selectionModel().selection() + """:type: QtWidgets.QItemSelection """ + + for i in range(self.protocol_model.col_count): + self.ui.tblViewProtocol.showColumn(i) + + for lbl in self.proto_analyzer.protocol_labels: + self.set_protocol_label_visibility(lbl) + + if not selected.isEmpty(): + min_row = numpy.min([rng.top() for rng in selected]) + start = numpy.min([rng.left() for rng in selected]) + self.ui.tblViewProtocol.scrollTo(self.protocol_model.index(min_row, start)) + + def get_labels_from_selection(self, row_start: int, row_end: int, col_start: int, col_end: int): + """ + + :rtype: list of ProtocolLabel + """ + row_end += 1 + col_end += 1 + + view = self.ui.cbProtoView.currentIndex() + result = [] + for i in range(row_start, row_end): + message = self.proto_analyzer.messages[i] + for label in message.message_type: + lbl_start, lbl_end = message.get_label_range(lbl=label, view=view, decode=True) + if any(j in range(lbl_start, lbl_end) for j in range(col_start, col_end)) and not label in result: + result.append(label) + + return result + + def set_search_ui_visibility(self, visible: bool): + self.ui.btnPrevSearch.setVisible(visible) + self.ui.lSearchCurrent.setVisible(visible) + self.ui.lSlash.setVisible(visible) + self.ui.lSearchTotal.setVisible(visible) + self.ui.btnNextSearch.setVisible(visible) + + def __set_default_message_type_ui_status(self): + if self.active_message_type == self.proto_analyzer.default_message_type: + self.ui.cbMessagetypes.setEditable(False) + self.ui.btnRemoveMessagetype.hide() + self.ui.btnMessagetypeSettings.hide() + else: + self.ui.cbMessagetypes.setEditable(True) + self.ui.btnRemoveMessagetype.show() + self.ui.btnMessagetypeSettings.show() + + def update_automatic_assigned_message_types(self): + self.proto_analyzer.update_auto_message_types() + self.protocol_model.update() + + def refresh_assigned_participants_ui(self): + self.protocol_model.refresh_vertical_header() + self.ui.tblViewProtocol.resize_vertical_header() + self.participant_changed.emit() + + 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() + + def mousePressEvent(self, event): + return + + def contextMenuEvent(self, event: QContextMenuEvent): + pass + + @pyqtSlot() + def on_btn_analyze_clicked(self): + self.setCursor(Qt.WaitCursor) + self.ui.stackedWidgetLogicAnalysis.setCurrentIndex(1) + + self.ui.progressBarLogicAnalyzer.setFormat("%p% (Detecting participants)") + self.ui.progressBarLogicAnalyzer.setValue(0) + + if self.assign_participants_action.isChecked(): + t = time.time() + for protocol in self.protocol_list: + protocol.auto_assign_participants(self.protocol_model.participants) + self.refresh_assigned_participants_ui() + logger.debug("Time for auto assigning participants: " + str(time.time() - t)) + + self.ui.progressBarLogicAnalyzer.setFormat("%p% (Assign decodings)") + self.ui.progressBarLogicAnalyzer.setValue(25) + + if self.assign_decodings_action.isChecked(): + t = time.time() + self.proto_analyzer.auto_assign_decodings(self.decodings) + self.protocol_model.update() + self.label_value_model.update() + logger.debug("Time for auto assigning decodings: " + str(time.time() - t)) + + self.ui.progressBarLogicAnalyzer.setFormat("%p% (Assign message type by rules)") + self.ui.progressBarLogicAnalyzer.setValue(50) + + if self.assign_message_type_action.isChecked(): + t = time.time() + self.update_automatic_assigned_message_types() + logger.debug("Time for auto assigning message types: " + str(time.time() - t)) + + self.ui.progressBarLogicAnalyzer.setFormat("%p% (Find new labels/message types)") + self.ui.progressBarLogicAnalyzer.setValue(75) + + if self.assign_labels_action.isChecked(): + t = time.time() + self.proto_analyzer.auto_assign_labels() + self.protocol_model.update() + self.label_value_model.update() + self.protocol_label_list_model.update() + self.ui.listViewLabelNames.clearSelection() + logger.debug("Time for auto assigning labels: " + str(time.time() - t)) + + self.ui.progressBarLogicAnalyzer.setValue(100) + self.unsetCursor() + self.ui.stackedWidgetLogicAnalysis.setCurrentIndex(0) + + self.fill_message_type_combobox() # in case message types were added by logic analyzer + + @pyqtSlot() + def on_btn_save_protocol_clicked(self): + self.save_protocol() + + @pyqtSlot() + def on_btn_next_search_clicked(self): + self.next_search_result() + + @pyqtSlot() + def on_btn_prev_search_clicked(self): + self.prev_search_result() + + @pyqtSlot() + def on_btn_search_clicked(self): + self.search() + + @pyqtSlot() + def on_btn_remove_message_type_clicked(self): + for msg in self.proto_analyzer.messages: + if msg.message_type == self.active_message_type: + msg.message_type = self.proto_analyzer.default_message_type + self.proto_analyzer.message_types.remove(self.active_message_type) + self.fill_message_type_combobox() + self.protocol_model.update() + self.active_message_type = self.proto_analyzer.default_message_type + + @pyqtSlot() + def on_btn_message_type_settings_clicked(self): + dialog = MessageTypeDialogController(self.active_message_type, parent=self) + dialog.show() + dialog.finished.connect(self.on_message_type_dialog_finished) + + @pyqtSlot() + def on_btn_new_message_type_clicked(self): + self.add_message_type() + + @pyqtSlot(list) + def on_table_new_message_type_clicked(self, selected_messages: list): + self.add_message_type(selected_messages) + + @pyqtSlot() + def on_table_selection_changed(self): + self.selection_timer.start(100) + + @pyqtSlot() + def on_combobox_decoding_current_index_changed(self): + new_index = self.ui.cbDecoding.currentIndex() + if new_index == -1: + return + + if new_index == self.ui.cbDecoding.count() - 1: + self.set_decoding(None) + else: + self.set_decoding(self.decodings[new_index], + messages=self.selected_messages if self.selected_messages else None) + + @pyqtSlot() + def on_participant_show_state_changed(self): + for i, msg in enumerate(self.proto_analyzer.messages): + hide = not msg.participant.show if msg.participant is not None else not self.participant_list_model.show_unassigned + self.ui.tblViewProtocol.setRowHidden(i, hide) + + self.set_shown_protocols() + + @pyqtSlot(int, int) + def on_group_deleted(self, deleted_group_id: int, new_group_id_of_childs: int): + try: + self.active_group_ids.remove(deleted_group_id) + except: + pass + + self.updateUI() + + @pyqtSlot() + def on_tbl_view_protocol_row_visibility_changed(self): + self.set_shown_protocols() + self.set_show_only_status() + + @pyqtSlot(int) + def on_check_box_show_only_labels_state_changed(self, new_state: int): + self.set_show_only_status() + + @pyqtSlot(int) + def on_check_box_show_only_diffs_state_changed(self, new_state: int): + self.set_show_only_status() + + @pyqtSlot(int) + def on_proto_to_group_added(self, group_id: int): + self.expand_group_node(group_id) + + @pyqtSlot(ProtocolLabel) + def on_protolabel_visibility_changed(self, proto_label: ProtocolLabel): + self.set_protocol_label_visibility(proto_label) + self.label_value_model.update() + + @pyqtSlot(list) + def on_files_dropped(self, files: list): + self.files_dropped.emit(files) + + @pyqtSlot(bool) + def on_chkbox_show_differences_clicked(self, checked: bool): + self.show_differences(checked) + + @pyqtSlot() + def on_search_action_triggered(self): + self.ui.lFilterShown.hide() + self.ui.btnSearchSelectFilter.setText("Search") + self.set_search_ui_visibility(True) + self.ui.btnSearchSelectFilter.clicked.disconnect() + self.ui.btnSearchSelectFilter.clicked.connect(self.on_btn_search_clicked) + + @pyqtSlot() + def on_select_action_triggered(self): + self.ui.lFilterShown.hide() + self.ui.btnSearchSelectFilter.setText("Select all") + self.set_search_ui_visibility(False) + self.ui.btnSearchSelectFilter.clicked.disconnect() + self.ui.btnSearchSelectFilter.clicked.connect(self.select_all_search_results) + + @pyqtSlot() + def on_filter_action_triggered(self): + if len(self.protocol_model.hidden_rows) == 0: + self.ui.lFilterShown.setText("") + else: + nhidden = len(self.protocol_model.hidden_rows) + rc = self.protocol_model.row_count + self.ui.lFilterShown.setText("shown: {}/{}".format(rc - nhidden, rc)) + + self.ui.lFilterShown.show() + self.ui.btnSearchSelectFilter.setText("Filter") + self.set_search_ui_visibility(False) + self.ui.btnSearchSelectFilter.clicked.disconnect() + self.ui.btnSearchSelectFilter.clicked.connect(self.filter_search_results) + + @pyqtSlot(bool) + def on_writeable_changed(self, writeable_status: bool): + self.protocol_model.is_writeable = writeable_status + self.proto_tree_model.set_copy_mode(writeable_status) + self.refresh() + + @pyqtSlot() + def on_project_updated(self): + self.participant_list_model.participants = self.project_manager.participants + self.participant_list_model.update() + self.protocol_model.participants = self.project_manager.participants + self.protocol_model.refresh_vertical_header() + self.active_message_type = self.proto_analyzer.default_message_type + + @pyqtSlot(ProtocolLabel) + def on_label_removed(self, plabel: ProtocolLabel): + if not plabel.show: + self.show_all_cols() + for lbl in self.proto_analyzer.protocol_labels: + self.set_protocol_label_visibility(lbl) + + self.ui.tblViewProtocol.resize_columns() + + self.protocol_model.update() + self.protocol_label_list_model.update() + self.label_value_model.update() + + @pyqtSlot(ProtocolLabel, MessageType) + def on_apply_decoding_changed(self, lbl: ProtocolLabel, message_type: MessageType): + for msg in self.proto_analyzer.messages: + if msg.message_type == message_type: + msg.clear_decoded_bits() + msg.clear_encoded_bits() + + @pyqtSlot() + def on_label_selection_changed(self): + rows = [index.row() for index in self.ui.listViewLabelNames.selectedIndexes()] + if len(rows) == 0: + return + + maxrow = numpy.max(rows) + + label = self.protocol_label_list_model.message_type[maxrow] + if not label.show: + return + + try: + message = next(msg for msg in self.proto_analyzer.messages if label if msg.message_type) + except StopIteration: + # No messages present + return + start, end = message.get_label_range(label, self.protocol_model.proto_view, True) + indx = self.protocol_model.index(0, int((start + end) / 2)) + + self.ui.tblViewProtocol.scrollTo(indx) + + @pyqtSlot(int) + def on_undo_stack_index_changed(self, index: int): + self.protocol_model.update() + self.protocol_label_list_model.update() + + @pyqtSlot(ProtocolLabel) + def on_edit_label_clicked_in_table(self, proto_label: ProtocolLabel): + + message_type = self.get_message_type_for_label(proto_label) + try: + self.show_protocol_label_dialog(message_type.index(proto_label)) + except AttributeError: + self.show_protocol_label_dialog(0) + + @pyqtSlot(int) + def on_edit_label_action_triggered(self, preselected_index: int): + self.show_protocol_label_dialog(preselected_index) @pyqtSlot() def on_protocol_view_changed(self): @@ -579,125 +1271,61 @@ class CompareFrameController(QFrame): for lbl in self.proto_analyzer.protocol_labels: self.set_protocol_label_visibility(lbl) - self.handle_show_only_checkbox_changed() + self.set_show_only_status() self.restore_selection(old_view, sel_cols, sel_rows) - def restore_selection(self, old_view: int, sel_cols, sel_rows): - if len(sel_cols) == 0 or len(sel_rows) == 0: - return + @pyqtSlot() + def on_item_in_proto_tree_dropped(self): + self.__protocols = None + self.set_shown_protocols() + self.ui.treeViewProtocols.clearSelection() - startCol, endCol = numpy.min(sel_cols), numpy.max(sel_cols) - startRow, endRow = numpy.min(sel_rows), numpy.max(sel_rows) - new_view = self.ui.cbProtoView.currentIndex() + @pyqtSlot() + def on_tree_view_selection_changed(self): + indexes = self.ui.treeViewProtocols.selectedIndexes() - message = self.proto_analyzer.messages[endRow] - startCol = message.convert_index(startCol, old_view, new_view, True)[0] - endCol = message.convert_index(endCol, old_view, new_view, True)[1] - - endCol = endCol if endCol < len(self.protocol_model.display_data[endRow]) else len(self.protocol_model.display_data[endRow]) - 1 - - startindex = self.protocol_model.index(startRow, startCol) - endindex = self.protocol_model.index(endRow, endCol) - mid_index = self.protocol_model.index(int((startRow + endRow) / 2), int((startCol + endCol) / 2)) + selected_items = [self.proto_tree_model.getItem(index) for index in indexes] + self.ui.tblViewProtocol.blockSignals(True) + active_group_ids = set() sel = QItemSelection() - sel.select(startindex, endindex) + + col_count = self.protocol_model.col_count + for item in selected_items: + if item.is_group: + active_group_ids.add(self.proto_tree_model.rootItem.index_of(item)) + elif item.show: + active_group_ids.add(self.proto_tree_model.rootItem.index_of(item.parent())) + + # rows_for_proto = self.rows_for_protocols[item.protocol] + # if len(rows_for_proto) > 0: + # startindex = self.protocol_model.index(rows_for_proto[0], 0) + # endindex = self.protocol_model.index(rows_for_proto[-1], col_count - 1) + # sel.select(startindex, endindex) + + if len(active_group_ids) == 0: + active_group_ids.add(0) + show_decoding = False + else: + show_decoding = True + + if active_group_ids == set(self.active_group_ids): + ignore_table_model_on_update = True + else: + ignore_table_model_on_update = False + self.active_group_ids = list(active_group_ids) + self.active_group_ids.sort() self.ui.tblViewProtocol.selectionModel().select(sel, QItemSelectionModel.ClearAndSelect) - self.ui.tblViewProtocol.scrollTo(mid_index) + self.ui.tblViewProtocol.blockSignals(False) + self.updateUI(ignore_table_model=ignore_table_model_on_update) - def get_group_for_row(self, row: int): - offset = 0 - for group in self.groups: - if row in range(offset, offset + group.num_messages): - return group - offset += group.num_messages + @pyqtSlot(QModelIndex) + def on_group_added(self, index): + self.ui.treeViewProtocols.edit(index) - return None - - @pyqtSlot() - def handle_table_selection_changed(self): - self.selection_timer.start(100) - - @pyqtSlot() - def on_cbDecoding_currentIndexChanged(self): - new_index = self.ui.cbDecoding.currentIndex() - if new_index == -1: - return - - if new_index == self.ui.cbDecoding.count() - 1: - self.set_decoding(None) - else: - self.set_decoding(self.decodings[new_index], messages=self.selected_messages if self.selected_messages else None) - - def set_decoding(self, decoding: Encoder, messages=None): - """ - - :param decoding: - :param messages: None = set for all messages - :return: - """ - if decoding is None: - self.show_decoding_clicked.emit() - else: - if messages is None: - messages = self.proto_analyzer.messages - if len(messages) > 10: - reply = QMessageBox.question(self, "Set decoding", "Do you want to apply the selected decoding to {} messages?".format(len(messages)), QMessageBox.Yes | QMessageBox.No) - if reply != QMessageBox.Yes: - self.ui.cbDecoding.blockSignals(True) - self.ui.cbDecoding.setCurrentText("...") - self.ui.cbDecoding.blockSignals(False) - return - - self.show_all_cols() - - - for msg in messages: - msg.decoder = decoding - - self.clear_search() - - selected = self.ui.tblViewProtocol.selectionModel().selection() - - if not selected.isEmpty() and self.isVisible() and self.proto_analyzer.num_messages > 0: - max_row = numpy.max([rng.bottom() for rng in selected]) - max_row = max_row if max_row < len(self.proto_analyzer.messages) else -1 - try: - msg = self.proto_analyzer.messages[max_row] - except IndexError: - msg = None - self.__set_decoding_error_label(msg) - else: - self.__set_decoding_error_label(None) - - self.protocol_model.update() - self.protocol_label_list_model.update() - self.label_value_model.update() - - for lbl in self.proto_analyzer.protocol_labels: - self.set_protocol_label_visibility(lbl) - - self.ui.tblViewProtocol.resize_columns() - - def __set_decoding_error_label(self, message: Message): - if message: - errors = message.decoding_errors - percent = 100 * (errors / len(message)) - color = "green" if errors == 0 else "red" - self.ui.lDecodingErrorsValue.setStyleSheet("color: "+color) - self.ui.lDecodingErrorsValue.setText(locale.format_string("%d (%.02f%%)", (errors, percent))) - - state = message.decoding_state if message.decoding_state != message.decoder.ErrorState.SUCCESS else "" - self.ui.labelDecodingState.setText(state) - self.ui.labelDecodingState.setStyleSheet("color: red") - else: - self.ui.lDecodingErrorsValue.setText("") - self.ui.labelDecodingState.setText("") - -# self.ui.lSupport.setStyleSheet("color: green") @pyqtSlot() def on_table_selection_timer_timeout(self): selected = self.ui.tblViewProtocol.selectionModel().selection() @@ -775,8 +1403,8 @@ class CompareFrameController(QFrame): for i, tree_item in enumerate(tree_items): proto = tree_item.protocol if proto.show and any(i in self.rows_for_protocols[proto] for i in range(min_row, max_row + 1)): - #index = self.proto_tree_model.createIndex(i, 0, tree_item) - #selection.select(index, index) + # index = self.proto_tree_model.createIndex(i, 0, tree_item) + # selection.select(index, index) active_group_ids.add(group) self.selected_protocols.add(proto) @@ -811,7 +1439,7 @@ class CompareFrameController(QFrame): self.updateUI(ignore_table_model=True, resize_table=False) @pyqtSlot(int) - def handle_ref_index_changed(self, new_ref_index): + def on_ref_index_changed(self, new_ref_index: int): if new_ref_index == -1: self.proto_tree_model.reference_protocol = -1 else: @@ -824,618 +1452,29 @@ class CompareFrameController(QFrame): return self.proto_tree_model.reference_protocol = -1 - def contextMenuEvent(self, event: QContextMenuEvent): - pass - - @pyqtSlot() - def handle_item_in_proto_tree_dropped(self): - self.__protocols = None - self.set_shown_protocols() - self.ui.treeViewProtocols.clearSelection() - - @pyqtSlot() - def handle_tree_view_selection_changed(self): - indexes = self.ui.treeViewProtocols.selectedIndexes() - - selected_items = [self.proto_tree_model.getItem(index) for index in indexes] - - self.ui.tblViewProtocol.blockSignals(True) - active_group_ids = set() - sel = QItemSelection() - - col_count = self.protocol_model.col_count - for item in selected_items: - if item.is_group: - active_group_ids.add(self.proto_tree_model.rootItem.index_of(item)) - elif item.show: - active_group_ids.add(self.proto_tree_model.rootItem.index_of(item.parent())) - - # rows_for_proto = self.rows_for_protocols[item.protocol] - # if len(rows_for_proto) > 0: - # startindex = self.protocol_model.index(rows_for_proto[0], 0) - # endindex = self.protocol_model.index(rows_for_proto[-1], col_count - 1) - # sel.select(startindex, endindex) - - if len(active_group_ids) == 0: - active_group_ids.add(0) - show_decoding = False - else: - show_decoding = True - - if active_group_ids == set(self.active_group_ids): - ignore_table_model_on_update = True - else: - ignore_table_model_on_update = False - self.active_group_ids = list(active_group_ids) - self.active_group_ids.sort() - - self.ui.tblViewProtocol.selectionModel().select(sel, QItemSelectionModel.ClearAndSelect) - self.ui.tblViewProtocol.blockSignals(False) - - self.updateUI(ignore_table_model=ignore_table_model_on_update) - - @pyqtSlot(QModelIndex) - def handle_group_added(self, index): - self.ui.treeViewProtocols.edit(index) - - def handle_group_deleted(self, deleted_group_id, new_group_id_of_childs): - try: - self.active_group_ids.remove(deleted_group_id) - except: - pass - - self.updateUI() - - def expand_group_node(self, group_id): - self.ui.treeViewProtocols.expand( - self.proto_tree_model.createIndex(group_id, 0, self.proto_tree_model.rootItem.child(group_id))) - - def updateUI(self, ignore_table_model=False, resize_table=True): - if not ignore_table_model: - self.protocol_model.update() - - self.protocol_label_list_model.update() - self.proto_tree_model.layoutChanged.emit() - self.label_value_model.update() - self.protocol_label_list_model.update() - - if resize_table: - self.ui.tblViewProtocol.resize_columns() - - def refresh(self): - self.__protocols = None - self.set_shown_protocols() - self.updateUI() - - def reset(self): - self.proto_tree_model.rootItem.clearChilds() - self.proto_tree_model.rootItem.addGroup() - for message_type in self.proto_analyzer.message_types: - message_type.clear() - self.refresh() + self.set_show_only_status() @pyqtSlot(int) - def on_undo_stack_index_changed(self, index: int): - self.protocol_model.update() - self.protocol_label_list_model.update() - - @pyqtSlot(ProtocolLabel) - def on_edit_label_clicked_in_table(self, proto_label: ProtocolLabel): - - message_type = self.get_message_type_for_label(proto_label) - try: - self.show_protocol_labels(message_type.index(proto_label)) - except AttributeError: - self.show_protocol_labels(0) - - @pyqtSlot(int) - def show_protocol_labels(self, preselected_index: int): - view_type = self.ui.cbProtoView.currentIndex() - max_end = max(len(msg) for msg in self.proto_analyzer.messages) if self.proto_analyzer.messages else 10000 - label_controller = ProtocolLabelController(preselected_index=preselected_index, message_type=self.active_message_type, - max_end=max_end, viewtype=view_type, parent=self) - label_controller.apply_decoding_changed.connect(self.on_apply_decoding_changed) - label_controller.exec_() - - self.protocol_label_list_model.update() - self.update_field_type_combobox() - self.label_value_model.update() - self.show_all_cols() - for lbl in self.proto_analyzer.protocol_labels: - self.set_protocol_label_visibility(lbl) - self.handle_show_only_checkbox_changed() - self.protocol_model.update() - self.ui.tblViewProtocol.resize_columns() - - @pyqtSlot(ProtocolLabel, MessageType) - def on_apply_decoding_changed(self, lbl: ProtocolLabel, message_type: MessageType): - for msg in self.proto_analyzer.messages: - if msg.message_type == message_type: - msg.clear_decoded_bits() - msg.clear_encoded_bits() - - @pyqtSlot() - def search(self): - value = self.ui.lineEditSearch.text() - nresults = self.protocol_model.find_protocol_value(value) - - if nresults > 0: - self.ui.btnNextSearch.setEnabled(True) - self.ui.btnPrevSearch.setEnabled(False) - self.ui.lSearchTotal.setText(str(nresults)) - self.ui.lSearchCurrent.setText("0") - self.next_search_result() - else: - self.clear_search() - - def select_all_search_results(self): - self.search() - self.ui.tblViewProtocol.clearSelection() - - for search_result in self.protocol_model.search_results: - startindex = self.protocol_model.index(search_result[0], search_result[1]) - endindex = self.protocol_model.index(search_result[0], - search_result[1] + len(self.protocol_model.search_value) - 1) - - sel = QItemSelection() - sel.select(startindex, endindex) - - self.ui.tblViewProtocol.selectionModel().select(sel, QItemSelectionModel.Select) - self.ui.tblViewProtocol.scrollTo(startindex, QAbstractItemView.PositionAtCenter) - - self.ui.tblViewProtocol.setFocus() - - def filter_search_results(self): - if self.ui.btnSearchSelectFilter.text() != "Filter": - return - - - if self.ui.lineEditSearch.text(): - self.search() - self.ui.tblLabelValues.clearSelection() - - matching_rows = set(search_result[0] for search_result in self.protocol_model.search_results) - self.ui.tblViewProtocol.blockSignals(True) - rc = self.protocol_model.row_count - for i in set(range(0, rc)) - matching_rows: - self.ui.tblViewProtocol.hide_row(row=i) - self.ui.tblViewProtocol.blockSignals(False) - self.ui.tblViewProtocol.row_visibilty_changed.emit() - - self.ui.lFilterShown.setText(self.tr("shown: {}/{}".format(rc-len(self.protocol_model.hidden_rows), rc))) - - else: - for i in range(0, self.protocol_model.row_count): - self.ui.tblViewProtocol.showRow(i) - - self.ui.lFilterShown.setText("") - self.set_shown_protocols() - - @pyqtSlot() - def next_search_result(self): - index = int(self.ui.lSearchCurrent.text()) - self.ui.lSearchTotal.setText((str(len(self.protocol_model.search_results)))) - try: - search_result = self.protocol_model.search_results[index] - startindex = self.protocol_model.index(search_result[0], search_result[1]) - endindex = self.protocol_model.index(search_result[0], - search_result[1] + len(self.protocol_model.search_value) - 1) - - sel = QItemSelection() - sel.select(startindex, endindex) - - self.ui.tblViewProtocol.selectionModel().select(sel, QItemSelectionModel.ClearAndSelect) - self.ui.tblViewProtocol.scrollTo(startindex, QAbstractItemView.PositionAtCenter) - - self.ui.lSearchCurrent.setText(str(index + 1)) - except IndexError: - self.ui.lSearchCurrent.setText("-") - finally: - if index + 1 == len(self.protocol_model.search_results): - self.ui.btnNextSearch.setEnabled(False) - - if index > 0 and len(self.protocol_model.search_results) > 0: - self.ui.btnPrevSearch.setEnabled(True) - - @pyqtSlot() - def prev_search_result(self): - index = int(self.ui.lSearchCurrent.text()) - 2 - - try: - search_result = self.protocol_model.search_results[index] - startindex = self.protocol_model.index(search_result[0], search_result[1]) - endindex = self.protocol_model.index(search_result[0], - search_result[1] + len(self.protocol_model.search_value) - 1) - - sel = QItemSelection() - sel.select(startindex, endindex) - - self.ui.tblViewProtocol.selectionModel().select(sel, QItemSelectionModel.ClearAndSelect) - self.ui.tblViewProtocol.scrollTo(startindex, QAbstractItemView.PositionAtCenter) - - self.ui.lSearchCurrent.setText(str(index + 1)) - except IndexError: - self.ui.lSearchCurrent.setText("-") - finally: - if self.ui.lSearchCurrent.text() == "1": - self.ui.btnPrevSearch.setEnabled(False) - - if len(self.protocol_model.search_results) > 0: - self.ui.btnNextSearch.setEnabled(True) - - def clear_search(self): - self.ui.lineEditSearch.clear() - self.ui.btnPrevSearch.setEnabled(False) - self.ui.btnNextSearch.setEnabled(False) - self.ui.lSearchTotal.setText("-") - self.ui.lSearchCurrent.setText("-") - self.protocol_model.search_results[:] = [] - self.protocol_model.search_value = "" - - def set_protocol_label_visibility(self, lbl: ProtocolLabel, message: Message = None): - try: - message = message if message else next(msg for msg in self.proto_analyzer.messages if lbl in msg.message_type) - start, end = message.get_label_range(lbl, self.ui.cbProtoView.currentIndex(), True) - - for i in range(start, end): - self.ui.tblViewProtocol.setColumnHidden(i, not lbl.show) - except Exception as e: - pass - - def get_message_type_for_label(self, lbl: ProtocolLabel) -> MessageType: - for msg_type in self.proto_analyzer.message_types: - if lbl in msg_type: - return msg_type - return None - - def show_all_cols(self): - for i in range(self.protocol_model.col_count): - self.ui.tblViewProtocol.showColumn(i) - - def save_protocol(self): - for msg in self.proto_analyzer.messages: - if not msg.decoder.is_nrz: - reply = QMessageBox.question(self, "Saving of protocol", - "You want to save this protocol with an encoding different from NRZ.\n" - "This may cause loss of information if you load it again.\n\n" - "Save anyway?", QMessageBox.Yes | QMessageBox.No) - if reply != QMessageBox.Yes: - return - else: - break - - text = "protocol" - filename = FileOperator.get_save_file_name("{0}.proto".format(text), parent=self, caption="Save protocol") - - if not filename: - return - - self.proto_analyzer.to_xml_file(filename=filename, decoders=self.decodings, participants=self.project_manager.participants, write_bits=True) - - def handle_writeable_changed(self, writeable_status: bool): - self.protocol_model.is_writeable = writeable_status - self.proto_tree_model.set_copy_mode(writeable_status) - self.refresh() - - def handle_label_removed(self, plabel: ProtocolLabel): - if not plabel.show: - self.show_all_cols() - for lbl in self.proto_analyzer.protocol_labels: - self.set_protocol_label_visibility(lbl) - - self.ui.tblViewProtocol.resize_columns() - - self.protocol_model.update() - self.protocol_label_list_model.update() - self.label_value_model.update() - - def handle_label_selection_changed(self): - rows = [index.row() for index in self.ui.listViewLabelNames.selectedIndexes()] - if len(rows) == 0: - return - - maxrow = numpy.max(rows) - - label = self.protocol_label_list_model.message_type[maxrow] - if not label.show: - return - - try: - message = next(msg for msg in self.proto_analyzer.messages if label if msg.message_type) - except StopIteration: - # No messages present - return - start, end = message.get_label_range(label, self.protocol_model.proto_view, True) - indx = self.protocol_model.index(0, int((start + end) / 2)) - - self.ui.tblViewProtocol.scrollTo(indx) - - def handle_show_only_checkbox_changed(self): - if self.ui.chkBoxOnlyShowLabelsInProtocol.isChecked() and self.ui.chkBoxShowOnlyDiffs.isChecked(): - self.show_only_diffs_and_labels() - elif self.ui.chkBoxOnlyShowLabelsInProtocol.isChecked() and not self.ui.chkBoxShowOnlyDiffs.isChecked(): - self.show_only_labels() - elif not self.ui.chkBoxOnlyShowLabelsInProtocol.isChecked() and self.ui.chkBoxShowOnlyDiffs.isChecked(): - self.show_only_diffs() - else: - self.restore_visibility() - - self.ui.tblViewProtocol.resize_columns() - - def show_only_labels(self): - visible_columns = set() - for msg in self.proto_analyzer.messages: - for lbl in msg.message_type: - if lbl.show: - start, end = msg.get_label_range(lbl=lbl, view=self.ui.cbProtoView.currentIndex(), - decode=True) - visible_columns |= (set(range(start, end))) - - for i in range(self.protocol_model.col_count): - if i in visible_columns: - self.ui.tblViewProtocol.showColumn(i) - else: - self.ui.tblViewProtocol.hideColumn(i) - - def show_only_diffs(self): - if not self.ui.cbShowDiffs.isChecked(): - self.ui.cbShowDiffs.setChecked(True) - - visible_rows = [i for i in range(self.protocol_model.row_count) if not self.ui.tblViewProtocol.isRowHidden(i) - and i != self.protocol_model.refindex] - - visible_diff_columns = [diff_col for i in visible_rows for diff_col in self.protocol_model.diff_columns[i]] - - for j in range(self.protocol_model.col_count): - if j in visible_diff_columns: - self.ui.tblViewProtocol.showColumn(j) - else: - self.ui.tblViewProtocol.hideColumn(j) - - def show_only_diffs_and_labels(self): - visible_label_columns = set() - for lbl in self.proto_analyzer.protocol_labels: - if lbl.show: - start, end = self.proto_analyzer.messages[0].get_label_range(lbl, self.ui.cbProtoView.currentIndex(), True) - visible_label_columns |= (set(range(start, end))) - - visible_rows = [i for i in range(self.protocol_model.row_count) if not self.ui.tblViewProtocol.isRowHidden(i) - and i != self.protocol_model.refindex] - - visible_diff_columns = set([diff_col for i in visible_rows for diff_col in self.protocol_model.diff_columns[i]]) - - visible_cols = visible_label_columns & visible_diff_columns - for j in range(self.protocol_model.col_count): - if j in visible_cols: - self.ui.tblViewProtocol.showColumn(j) - else: - self.ui.tblViewProtocol.hideColumn(j) - - def restore_visibility(self): - selected = self.ui.tblViewProtocol.selectionModel().selection() - """:type: QtWidgets.QItemSelection """ - - for i in range(self.protocol_model.col_count): - self.ui.tblViewProtocol.showColumn(i) - - for lbl in self.proto_analyzer.protocol_labels: - self.set_protocol_label_visibility(lbl) - - if not selected.isEmpty(): - min_row = numpy.min([rng.top() for rng in selected]) - start = numpy.min([rng.left() for rng in selected]) - self.ui.tblViewProtocol.scrollTo(self.protocol_model.index(min_row, start)) - - def add_protocol_label(self, start: int, end: int, messagenr: int, proto_view: int, edit_label_name=True): - # Ensure atleast one Group is active - start, end = self.proto_analyzer.convert_range(start, end, proto_view, 0, decoded=True, message_indx=messagenr) - proto_label = self.proto_analyzer.messages[messagenr].message_type.add_protocol_label(start=start, end=end) - - self.protocol_label_list_model.update() + def on_combobox_messagetype_index_changed(self, index: int): + self.active_message_type = self.proto_analyzer.message_types[index] + + @pyqtSlot(MessageType, list) + def on_message_type_selected(self, message_type: MessageType, selected_messages: list): + for msg in selected_messages: + msg.message_type = message_type + self.active_message_type = message_type self.protocol_model.update() - if edit_label_name: - try: - index = self.protocol_label_list_model.message_type.index(proto_label) - self.ui.listViewLabelNames.edit(self.protocol_label_list_model.createIndex(index, 0)) - except ValueError: - pass - - self.label_value_model.update() - - return True - - @pyqtSlot() - def on_btn_analyze_clicked(self): - self.setCursor(Qt.WaitCursor) - self.ui.stackedWidgetLogicAnalysis.setCurrentIndex(1) - - - self.ui.progressBarLogicAnalyzer.setFormat("%p% (Detecting participants)") - self.ui.progressBarLogicAnalyzer.setValue(0) - - if self.assign_participants_action.isChecked(): - t = time.time() - for protocol in self.protocol_list: - protocol.auto_assign_participants(self.protocol_model.participants) - self.on_participant_edited() - logger.debug("Time for auto assigning participants: " + str(time.time() - t)) - - self.ui.progressBarLogicAnalyzer.setFormat("%p% (Assign decodings)") - self.ui.progressBarLogicAnalyzer.setValue(25) - - if self.assign_decodings_action.isChecked(): - t = time.time() - self.proto_analyzer.auto_assign_decodings(self.decodings) - self.protocol_model.update() - self.label_value_model.update() - logger.debug("Time for auto assigning decodings: " + str(time.time() - t)) - - self.ui.progressBarLogicAnalyzer.setFormat("%p% (Assign message type by rules)") - self.ui.progressBarLogicAnalyzer.setValue(50) - - if self.assign_message_type_action.isChecked(): - t = time.time() - self.on_message_type_dialog_finished() - logger.debug("Time for auto assigning message types: " + str(time.time() - t)) - - self.ui.progressBarLogicAnalyzer.setFormat("%p% (Find new labels/message types)") - self.ui.progressBarLogicAnalyzer.setValue(75) - - if self.assign_labels_action.isChecked(): - t = time.time() - self.proto_analyzer.auto_assign_labels() - self.protocol_model.update() - self.label_value_model.update() - self.protocol_label_list_model.update() - self.ui.listViewLabelNames.clearSelection() - logger.debug("Time for auto assigning labels: " + str(time.time() - t)) - - self.ui.progressBarLogicAnalyzer.setValue(100) - self.unsetCursor() - self.ui.stackedWidgetLogicAnalysis.setCurrentIndex(0) - - self.fill_message_type_combobox() # in case message types were added by logic analyzer - - def get_labels_from_selection(self, row_start: int, row_end: int, col_start: int, col_end: int): - """ - - :rtype: list of ProtocolLabel - """ - row_end += 1 - col_end += 1 - - view = self.ui.cbProtoView.currentIndex() - result = [] - for i in range(row_start, row_end): - message = self.proto_analyzer.messages[i] - for label in message.message_type: - lbl_start, lbl_end = message.get_label_range(lbl=label, view=view, decode=True) - if any(j in range(lbl_start, lbl_end) for j in range(col_start, col_end)) and not label in result: - result.append(label) - - return result - - def on_project_updated(self): - self.participant_list_model.participants = self.project_manager.participants - self.participant_list_model.update() - self.protocol_model.participants = self.project_manager.participants - self.protocol_model.refresh_vertical_header() - self.active_message_type = self.proto_analyzer.default_message_type - - def set_search_ui_visibility(self, visible: bool): - self.ui.btnPrevSearch.setVisible(visible) - self.ui.lSearchCurrent.setVisible(visible) - self.ui.lSlash.setVisible(visible) - self.ui.lSearchTotal.setVisible(visible) - self.ui.btnNextSearch.setVisible(visible) - - def __set_mode_to_search(self): - self.ui.lFilterShown.hide() - self.ui.btnSearchSelectFilter.setText("Search") - self.set_search_ui_visibility(True) - self.ui.btnSearchSelectFilter.clicked.disconnect() - self.ui.btnSearchSelectFilter.clicked.connect(self.search) - - def __set_mode_to_select_all(self): - self.ui.lFilterShown.hide() - self.ui.btnSearchSelectFilter.setText("Select all") - self.set_search_ui_visibility(False) - self.ui.btnSearchSelectFilter.clicked.disconnect() - self.ui.btnSearchSelectFilter.clicked.connect(self.select_all_search_results) - - def __set_mode_to_filter(self): - if len(self.protocol_model.hidden_rows) == 0: - self.ui.lFilterShown.setText("") - else: - nhidden = len(self.protocol_model.hidden_rows) - rc = self.protocol_model.row_count - self.ui.lFilterShown.setText("shown: {}/{}".format(rc-nhidden, rc)) - - self.ui.lFilterShown.show() - self.ui.btnSearchSelectFilter.setText("Filter") - self.set_search_ui_visibility(False) - self.ui.btnSearchSelectFilter.clicked.disconnect() - self.ui.btnSearchSelectFilter.clicked.connect(self.filter_search_results) - - def on_cbmessagetype_index_changed(self): - self.active_message_type = self.proto_analyzer.message_types[self.ui.cbMessagetypes.currentIndex()] - - def __set_default_message_type_ui_status(self): - if self.active_message_type == self.proto_analyzer.default_message_type: - self.ui.cbMessagetypes.setEditable(False) - self.ui.btnRemoveMessagetype.hide() - self.ui.btnMessagetypeSettings.hide() - else: - self.ui.cbMessagetypes.setEditable(True) - self.ui.btnRemoveMessagetype.show() - self.ui.btnMessagetypeSettings.show() - - def on_messagetype_name_edited(self, edited_str): + @pyqtSlot(str) + def on_message_type_name_edited(self, edited_str: str): if self.active_message_type == self.proto_analyzer.message_types[self.ui.cbMessagetypes.currentIndex()]: self.active_message_type.name = edited_str self.ui.cbMessagetypes.setItemText(self.ui.cbMessagetypes.currentIndex(), edited_str) - def on_new_message_type_clicked(self, selected_messages: list = None): - selected_messages = selected_messages if isinstance(selected_messages, list) else [] - self.proto_analyzer.add_new_message_type(labels=self.proto_analyzer.default_message_type) - self.fill_message_type_combobox() - self.ui.cbMessagetypes.setEditable(True) - self.active_message_type = self.proto_analyzer.message_types[-1] - for msg in selected_messages: - msg.message_type = self.active_message_type - self.ui.cbMessagetypes.setFocus() - self.ui.btnRemoveMessagetype.show() - self.protocol_model.update() - - def on_message_type_selected(self, message_type: MessageType, selected_messages): - for msg in selected_messages: - msg.message_type = message_type - self.active_message_type = message_type - self.protocol_model.update() - - def on_remove_message_type_clicked(self): - for msg in self.proto_analyzer.messages: - if msg.message_type == self.active_message_type: - msg.message_type = self.proto_analyzer.default_message_type - self.proto_analyzer.message_types.remove(self.active_message_type) - self.fill_message_type_combobox() - self.protocol_model.update() - self.active_message_type = self.proto_analyzer.default_message_type - - def on_btn_messagetype_settings_clicked(self): - dialog = MessageTypeDialogController(self.active_message_type, parent=self) - dialog.show() - dialog.finished.connect(self.on_message_type_dialog_finished) - - def on_message_type_dialog_finished(self): - self.proto_analyzer.update_auto_message_types() - self.protocol_model.update() + @pyqtSlot(int) + def on_message_type_dialog_finished(self, status: int): + self.update_automatic_assigned_message_types() + @pyqtSlot() def on_participant_edited(self): - self.protocol_model.refresh_vertical_header() - self.ui.tblViewProtocol.resize_vertical_header() - self.participant_changed.emit() - - def set_participant_visibility(self): - for i, msg in enumerate(self.proto_analyzer.messages): - hide = not msg.participant.show if msg.participant is not None else not self.participant_list_model.show_unassigned - 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() \ No newline at end of file + self.refresh_assigned_participants_ui() diff --git a/src/urh/ui/views/ProtocolTableView.py b/src/urh/ui/views/ProtocolTableView.py index 538d4e62..3f257293 100644 --- a/src/urh/ui/views/ProtocolTableView.py +++ b/src/urh/ui/views/ProtocolTableView.py @@ -13,14 +13,14 @@ class ProtocolTableView(TableView): show_interpretation_clicked = pyqtSignal(int, int, int, int) selection_changed = pyqtSignal() protocol_view_change_clicked = pyqtSignal(int) - row_visibilty_changed = pyqtSignal() + row_visibility_changed = pyqtSignal() writeable_changed = pyqtSignal(bool) crop_sync_clicked = pyqtSignal() revert_sync_cropping_wanted = pyqtSignal() edit_label_clicked = pyqtSignal(ProtocolLabel) files_dropped = pyqtSignal(list) participant_changed = pyqtSignal() - new_messagetype_clicked = pyqtSignal(list) # list of protocol messages + new_messagetype_clicked = pyqtSignal(list) # list of protocol messages messagetype_selected = pyqtSignal(MessageType, list) def __init__(self, parent=None): @@ -90,7 +90,7 @@ class ProtocolTableView(TableView): if refindex < self.model().row_count: self.model().refindex = refindex self.model().update() - self.row_visibilty_changed.emit() + self.row_visibility_changed.emit() def contextMenuEvent(self, event): menu = QMenu() @@ -242,7 +242,7 @@ class ProtocolTableView(TableView): self.showRow(i) self.model().hidden_rows.clear() self.model().update() - self.row_visibilty_changed.emit() + self.row_visibility_changed.emit() elif action == bitAction: self.protocol_view_change_clicked.emit(0) elif action == hexAction: