diff --git a/include/fastdds_monitor/Controller.h b/include/fastdds_monitor/Controller.h index c43f9ee4..a92a6c1e 100644 --- a/include/fastdds_monitor/Controller.h +++ b/include/fastdds_monitor/Controller.h @@ -279,6 +279,15 @@ public slots: QString get_type_idl ( QString entity_id); + QString get_endpoint_topic_id( + QString endpoint_id); + + QString get_domain_id( + QString entity_id); + + QString get_name( + QString entity_id); + QString get_data_type_name( QString entity_id); diff --git a/include/fastdds_monitor/Engine.h b/include/fastdds_monitor/Engine.h index 0185f0fe..8007528e 100644 --- a/include/fastdds_monitor/Engine.h +++ b/include/fastdds_monitor/Engine.h @@ -526,6 +526,10 @@ class Engine : public QQmlApplicationEngine //! Retrive a string list containing the available data kinds. std::vector get_data_kinds(); + //! Retrieve the name associated to a specific entity + std::string get_name( + const backend::EntityId& entity_id); + //! Retrieve the data type name associated to a specific entity std::string get_data_type_name( const backend::EntityId& entity_id); @@ -534,6 +538,14 @@ class Engine : public QQmlApplicationEngine std::string get_type_idl( const backend::EntityId& entity_id); + //! Retrieve the topic id associated to a specific endpoint + models::EntityId get_endpoint_topic_id( + const models::EntityId& endpoint_id); + + //! Retrieve the id of the domain associated to an entity (Domain, DomainParticipant, Topìc or Endpoints) + models::EntityId get_domain_id( + const models::EntityId& entity_id); + //! Returns whether the data kind entered requires a target entity to be defined. bool data_kind_has_target( const QString& data_kind); diff --git a/include/fastdds_monitor/backend/SyncBackendConnection.h b/include/fastdds_monitor/backend/SyncBackendConnection.h index bf7bf2bd..dba01e76 100644 --- a/include/fastdds_monitor/backend/SyncBackendConnection.h +++ b/include/fastdds_monitor/backend/SyncBackendConnection.h @@ -104,6 +104,14 @@ class SyncBackendConnection EntityInfo get_info( EntityId id); + //! Get the id of the topic associated to an endpoint + backend::EntityId get_endpoint_topic_id( + backend::EntityId endpoint_id); + + //! Get the id of the domain associated to an entity (Domain, DomainParticipant, Topìc or Endpoints) + backend::EntityId get_domain_id( + backend::EntityId entity_id); + //! Get the \c EntityKind of a given \c EntityId EntityKind get_type( backend::EntityId id); diff --git a/qml/DomainGraphLayout.qml b/qml/DomainGraphLayout.qml index 8fa3f16c..64f0ff18 100644 --- a/qml/DomainGraphLayout.qml +++ b/qml/DomainGraphLayout.qml @@ -33,7 +33,7 @@ Item // Public signals signal update_tab_name(string new_name, string new_icon, string stack_id) // Update tab name based on selected domain id - signal openEntitiesMenu(string domainEntityId, string entityId, string currentAlias, string entityKind) + signal openEntitiesMenu(string domainEntityId, string entityId, string currentAlias, string entityKind, int caller) signal openTopicMenu(string domainEntityId, string domainId, string entityId, string currentAlias, string entityKind, int caller) signal openLoadingGraphDialog() //l et tab layout know that graph is about to be generated signal initialized() // let tab layout know that graph has been generated @@ -246,7 +246,7 @@ Item onClicked: { if(mouse.button & Qt.RightButton) { - openTopicMenu(domain_entity_id, domain_id, modelData["id"], modelData["alias"], modelData["kind"], panels.openTopicMenuCaller.domainGraph) + openTopicMenu(domain_entity_id, domain_id, modelData["id"], modelData["alias"], modelData["kind"], panels.openMenuCaller.domainGraph) } else { controller.topic_click(modelData["id"]) } @@ -613,7 +613,7 @@ Item onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu(domain_entity_id, modelData["id"], modelData["alias"], modelData["kind"]) + openEntitiesMenu(domain_entity_id, modelData["id"], modelData["alias"], modelData["kind"], openMenuCaller.domainGraph) } else { controller.host_click(modelData["id"]) } @@ -757,7 +757,7 @@ Item onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu(domain_entity_id, modelData["id"], modelData["alias"], modelData["kind"]) + openEntitiesMenu(domain_entity_id, modelData["id"], modelData["alias"], modelData["kind"], openMenuCaller.domainGraph) } else { controller.user_click(modelData["id"]) } @@ -900,7 +900,7 @@ Item onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu(domain_entity_id, modelData["id"], modelData["alias"], modelData["kind"]) + openEntitiesMenu(domain_entity_id, modelData["id"], modelData["alias"], modelData["kind"], openMenuCaller.domainGraph) } else { controller.process_click(modelData["id"]) } @@ -1067,7 +1067,7 @@ Item onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu(domain_entity_id, modelData["id"], modelData["alias"], modelData["kind"]) + openEntitiesMenu(domain_entity_id, modelData["id"], modelData["alias"], modelData["kind"], openMenuCaller.domainGraph) } else { controller.participant_click(modelData["id"]) } @@ -1271,7 +1271,7 @@ Item onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu(domain_entity_id, modelData["id"], modelData["alias"], modelData["kind"]) + openEntitiesMenu(domain_entity_id, modelData["id"], modelData["alias"], modelData["kind"], openMenuCaller.domainGraph) } else { controller.endpoint_click(modelData["id"]) } diff --git a/qml/EntitiesMenu.qml b/qml/EntitiesMenu.qml index 160b699b..dc86f396 100644 --- a/qml/EntitiesMenu.qml +++ b/qml/EntitiesMenu.qml @@ -5,19 +5,101 @@ import Theme 1.0 /* Menu containing the possible actions that can be performed on any DDS, physical and logical entity. */ + + Menu { id: entitiesMenu - property string domainEntityId: "" + property string domainEntityId: "" property string entityId: "" property string currentAlias: "" property string entityKind: "" + property string showGraphButtonName: "" + + signal changeAlias(string domainEntityId, string entityId, string currentAlias, string entityKind) + signal filterEntityStatusLog(string entityId) + signal openTopicView(string domainEntityId, string domainId, string topicId) + + ////////////////// + // Menu options // + ////////////////// + + Component { + id: changeAlias + + MenuItem { + text: "Change alias" + MouseArea { + hoverEnabled: true + anchors.fill: parent + onEntered: parent.highlighted = true + onExited: parent.highlighted = false + onPressed: { + console.log("[EntitiesMenu] domainEntityId: ", entitiesMenu.domainEntityId) + entitiesMenu.changeAlias(entitiesMenu.domainEntityId, entitiesMenu.entityId, entitiesMenu.currentAlias, entitiesMenu.entityKind) + entitiesMenu.close() + } + } + } + } + + Component { + id: viewProblems + + MenuItem { + text: "View Problems" + MouseArea { + hoverEnabled: true + anchors.fill: parent + onEntered: parent.highlighted = true + onExited: parent.highlighted = false + onPressed: { + entitiesMenu.filterEntityStatusLog(entitiesMenu.entityId) + entitiesMenu.close() + } + } + } + } + + Component { + id: endpointsOption + + MenuItem { + text: entitiesMenu.showGraphButtonName + MouseArea { + hoverEnabled: true + anchors.fill: parent + onEntered: parent.highlighted = true + onExited: parent.highlighted = false + onPressed: { + let domain = controller.get_name(entitiesMenu.domainEntityId) + let topicId = controller.get_endpoint_topic_id(entityId) + entitiesMenu.openTopicView(entitiesMenu.domainEntityId, domain, topicId) + entitiesMenu.close() + } + } + } + } - MenuItem { - text: "Change alias" - onTriggered: changeAlias(menu.domainEntityId, menu.entityId, menu.currentAlias, menu.entityKind) + // Print menu options depending on the entity kind + ListModel { + id: entityModel } - MenuItem { - text: "View Problems" - onTriggered: filterEntityStatusLog(menu.entityId) + + Repeater { + model: entityModel + delegate: Loader { + sourceComponent: available ? entity_option : null + } + } + + // Update model if some property change implies graphic changes in UI + onEntityKindChanged: updateEntityModel() + onShowGraphButtonNameChanged: updateEntityModel() + + function updateEntityModel() { + entityModel.clear() + entityModel.append({"available": entitiesMenu.entityKind === "DataWriter" || entitiesMenu.entityKind === "DataReader", "entity_option": endpointsOption}) + entityModel.append({"available": true, "entity_option": changeAlias}) + entityModel.append({"available": true, "entity_option": viewProblems}) } } diff --git a/qml/EntityList.qml b/qml/EntityList.qml index 61c534d2..1a9f7375 100644 --- a/qml/EntityList.qml +++ b/qml/EntityList.qml @@ -90,7 +90,7 @@ Rectangle { } onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu("", id, name, kind) + openEntitiesMenu(controller.get_domain_id(id), id, name, kind, openMenuCaller.leftPanel) } else { controller.participant_click(id) } @@ -173,7 +173,7 @@ Rectangle { } onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu("", id, name, kind) + openEntitiesMenu(controller.get_domain_id(id), id, name, kind, openMenuCaller.leftPanel) } else { controller.endpoint_click(id) } @@ -245,7 +245,7 @@ Rectangle { onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu("", id, name, kind) + openEntitiesMenu(controller.get_domain_id(id), id, name, kind, openMenuCaller.leftPanel) } else { controller.locator_click(id) } diff --git a/qml/LeftPanel.qml b/qml/LeftPanel.qml index 3a0a3efa..295561a8 100644 --- a/qml/LeftPanel.qml +++ b/qml/LeftPanel.qml @@ -32,8 +32,9 @@ RowLayout { Issues } - readonly property var openTopicMenuCaller: ({ - logicalPanel: 0, + // Enum exposed in Panels.qml for Menu items message customization + readonly property var openMenuCaller: ({ + leftPanel: 0, domainGraph: 1 }) @@ -72,7 +73,10 @@ RowLayout { EntitiesMenu { id: entitiesMenu - } + onChangeAlias: leftPanel.changeAlias(domainEntityId, entityId, currentAlias, entityKind) + onFilterEntityStatusLog: leftPanel.filterEntityStatusLog(entityId) + onOpenTopicView: leftPanel.openTopicView(domainEntityId, domainId, topicId) + } TopicMenu { id: topicMenu @@ -92,11 +96,19 @@ RowLayout { aliasDialog.open() } - function openEntitiesMenu(domainEntityId, entityId, currentAlias, entityKind) { + function openEntitiesMenu(domainEntityId, entityId, currentAlias, entityKind, caller) { entitiesMenu.domainEntityId = domainEntityId entitiesMenu.entityId = entityId entitiesMenu.currentAlias = currentAlias entitiesMenu.entityKind = entityKind + + if (caller === openMenuCaller.domainGraph) { + entitiesMenu.showGraphButtonName = "Filter topic graph" + } + else { + entitiesMenu.showGraphButtonName = "Show topic graph" + } + entitiesMenu.popup() } @@ -107,11 +119,11 @@ RowLayout { topicMenu.currentAlias = currentAlias topicMenu.entityKind = entityKind - if (caller === openTopicMenuCaller.logicalPanel) { - topicMenu.showGraphButtonName = "Show topic graph" + if (caller === openMenuCaller.domainGraph) { + topicMenu.showGraphButtonName = "Filter topic graph" } else { - topicMenu.showGraphButtonName = "Filter topic graph" + topicMenu.showGraphButtonName = "Show topic graph" } topicMenu.popup() diff --git a/qml/LogicalView.qml b/qml/LogicalView.qml index c7278729..a4e4b3b4 100644 --- a/qml/LogicalView.qml +++ b/qml/LogicalView.qml @@ -97,7 +97,7 @@ Rectangle { } onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu(domainId, id, name, kind) + openEntitiesMenu(domainId, id, name, kind, openMenuCaller.leftPanel) } else { controller.domain_click(id) } @@ -167,7 +167,7 @@ Rectangle { onClicked: { if(mouse.button & Qt.RightButton) { - openTopicMenu(domainId, domainName, id, name, kind, openTopicMenuCaller.logicalPanel) + openTopicMenu(domainId, domainName, id, name, kind, openMenuCaller.leftPanel) } else { controller.topic_click(id) } diff --git a/qml/Panels.qml b/qml/Panels.qml index 1ba118b3..cf8c0e6a 100644 --- a/qml/Panels.qml +++ b/qml/Panels.qml @@ -133,7 +133,7 @@ RowLayout { } } onOpenEntitiesMenu: { - panels.openEntitiesMenu(domainEntityId, entityId, currentAlias, entityKind) + panels.openEntitiesMenu(domainEntityId, entityId, currentAlias, entityKind, caller) } onOpenTopicMenu: { panels.openTopicMenu(domainEntityId, domainId, entityId, currentAlias, entityKind, caller) @@ -164,8 +164,8 @@ RowLayout { } } - // Expose LeftPanel openTopicMenuCaller enum to be used in other children components (e.g: DomainGraphView.qml) - property alias openTopicMenuCaller: leftPanel.openTopicMenuCaller + // Expose LeftPanel openMenuCaller enum to be used in other children components (e.g: DomainGraphView.qml) + property alias openMenuCaller: leftPanel.openMenuCaller function createHistoricChart(dataKind){ tabs.chartsLayout_createHistoricChart(dataKind) @@ -199,8 +199,8 @@ RowLayout { leftPanel.changeExplorerEntityInfo(status) } - function openEntitiesMenu(domainEntityId, entityId, currentAlias, entityKind) { - leftPanel.openEntitiesMenu(domainEntityId, entityId, currentAlias, entityKind) + function openEntitiesMenu(domainEntityId, entityId, currentAlias, entityKind, caller) { + leftPanel.openEntitiesMenu(domainEntityId, entityId, currentAlias, entityKind, caller) } function openTopicMenu(domainEntityId, domainId, entityId, currentAlias, entityKind, caller) { diff --git a/qml/PhysicalView.qml b/qml/PhysicalView.qml index e698b445..dbd553bc 100644 --- a/qml/PhysicalView.qml +++ b/qml/PhysicalView.qml @@ -90,7 +90,7 @@ Rectangle { } onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu("", id, name, kind) + openEntitiesMenu("", id, name, kind, openMenuCaller.leftPanel) } else { controller.host_click(id) } @@ -174,7 +174,7 @@ Rectangle { } onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu("", id, name, kind) + openEntitiesMenu("", id, name, kind, openMenuCaller.leftPanel) } else { controller.user_click(id) } @@ -246,7 +246,7 @@ Rectangle { onClicked: { if(mouse.button & Qt.RightButton) { - openEntitiesMenu("", id, name, kind) + openEntitiesMenu("", id, name, kind, openMenuCaller.leftPanel) } else { controller.process_click(id) } diff --git a/qml/TabLayout.qml b/qml/TabLayout.qml index d536a870..791e89a1 100644 --- a/qml/TabLayout.qml +++ b/qml/TabLayout.qml @@ -28,7 +28,7 @@ Item { property bool fullScreen: false // ChartsLayout inherited var // Public signals - signal openEntitiesMenu(string domainEntityId, string entityId, string currentAlias, string entityKind) + signal openEntitiesMenu(string domainEntityId, string entityId, string currentAlias, string entityKind, int caller) signal openTopicMenu(string domainEntityId, string domainId, string entityId, string currentAlias, string entityKind, int caller) // Private properties @@ -253,7 +253,7 @@ Item { } onOpenEntitiesMenu: { - tabLayout.openEntitiesMenu(domainEntityId, entityId, currentAlias, entityKind) + tabLayout.openEntitiesMenu(domainEntityId, entityId, currentAlias, entityKind, caller) } onOpenTopicMenu: { tabLayout.openTopicMenu(domainEntityId, domainId, entityId, currentAlias, entityKind, caller) diff --git a/src/Controller.cpp b/src/Controller.cpp index 276e4e64..69e71fae 100644 --- a/src/Controller.cpp +++ b/src/Controller.cpp @@ -329,6 +329,24 @@ QString Controller::get_type_idl( return utils::to_QString(engine_->get_type_idl(backend::models_id_to_backend_id(entity_id))); } +QString Controller::get_endpoint_topic_id( + QString endpoint_id) +{ + return engine_->get_endpoint_topic_id(endpoint_id); +} + +QString Controller::get_domain_id( + QString entity_id) +{ + return engine_->get_domain_id(entity_id); +} + +QString Controller::get_name( + QString entity_id) +{ + return utils::to_QString(engine_->get_name(backend::models_id_to_backend_id(entity_id))); +} + QString Controller::get_data_type_name( QString entity_id) { diff --git a/src/Engine.cpp b/src/Engine.cpp index 972fab7f..77190028 100644 --- a/src/Engine.cpp +++ b/src/Engine.cpp @@ -1709,6 +1709,12 @@ std::vector Engine::get_data_kinds() return backend_connection_.get_data_kinds(); } +std::string Engine::get_name( + const backend::EntityId& entity_id) +{ + return backend_connection_.get_name(entity_id); +} + std::string Engine::get_data_type_name( const backend::EntityId& entity_id) { @@ -1721,6 +1727,20 @@ std::string Engine::get_type_idl( return backend_connection_.get_type_idl(entity_id); } +models::EntityId Engine::get_endpoint_topic_id( + const models::EntityId& endpoint_id) +{ + backend::EntityId topic_id = backend_connection_.get_endpoint_topic_id(backend::models_id_to_backend_id(endpoint_id)); + return backend::backend_id_to_models_id(topic_id); +} + +models::EntityId Engine::get_domain_id( + const models::EntityId& entity_id) +{ + backend::EntityId domain_id = backend_connection_.get_domain_id(backend::models_id_to_backend_id(entity_id)); + return backend::backend_id_to_models_id(domain_id); +} + bool Engine::data_kind_has_target( const QString& data_kind) { diff --git a/src/backend/SyncBackendConnection.cpp b/src/backend/SyncBackendConnection.cpp index d7ec5a76..01fd373e 100644 --- a/src/backend/SyncBackendConnection.cpp +++ b/src/backend/SyncBackendConnection.cpp @@ -495,6 +495,18 @@ EntityInfo SyncBackendConnection::get_info( } } +backend::EntityId SyncBackendConnection::get_endpoint_topic_id( + backend::EntityId endpoint_id) +{ + return StatisticsBackend::get_endpoint_topic_id(endpoint_id); +} + +backend::EntityId SyncBackendConnection::get_domain_id( + backend::EntityId entity_id) +{ + return StatisticsBackend::get_domain_id(entity_id); +} + bool SyncBackendConnection::get_alive( EntityId id) {