综合平台编程器项目的远程存储
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

201 lines
6.5 KiB

  1. #include "runtime_monitor_widget.h"
  2. #include "free_monitor_widget.h"
  3. #include "hmi_editor_widget.h"
  4. #include "logic_editor_widget.h"
  5. #include "services/hmi_navigation_service.h"
  6. #include "services/alarm_service.h"
  7. #include "services/project_service.h"
  8. #include "ui_runtime_monitor_widget.h"
  9. #include <QSplitter>
  10. #include <QComboBox>
  11. #include <QSignalBlocker>
  12. #include <algorithm>
  13. namespace {
  14. QString fromUtf8(const std::string &value)
  15. {
  16. return QString::fromUtf8(value.data(), static_cast<int>(value.size()));
  17. }
  18. std::string toUtf8(const QString &value)
  19. {
  20. const QByteArray bytes = value.toUtf8();
  21. return std::string(bytes.constData(), static_cast<std::size_t>(bytes.size()));
  22. }
  23. } // namespace
  24. RuntimeMonitorWidget::RuntimeMonitorWidget(
  25. HmiEditorService &hmi_editor_service,
  26. HmiRuntimeService &hmi_runtime_service,
  27. LogicEditorService &logic_editor_service,
  28. ProjectService &project_service,
  29. HmiNavigationService &hmi_navigation_service,
  30. AlarmService &alarm_service,
  31. RegisterMonitorService &register_monitor_service,
  32. QWidget *parent)
  33. : QWidget(parent),
  34. ui_(std::make_unique<Ui::RuntimeMonitorWidget>()),
  35. project_service_(project_service),
  36. hmi_navigation_service_(hmi_navigation_service)
  37. {
  38. ui_->setupUi(this);
  39. hmi_view_ = new HmiEditorWidget(
  40. hmi_editor_service,
  41. hmi_runtime_service,
  42. alarm_service,
  43. ui_->hmiViewContainer);
  44. hmi_view_->setObjectName(QStringLiteral("runtimeHmiView"));
  45. hmi_view_->setEditingEnabled(false);
  46. hmi_view_->setRuntimeActive(true);
  47. ui_->hmiViewLayout->addWidget(hmi_view_);
  48. logic_view_ = new LogicEditorWidget(logic_editor_service, ui_->logicViewContainer);
  49. logic_view_->setObjectName(QStringLiteral("runtimeLogicView"));
  50. logic_view_->setEditingEnabled(false);
  51. ui_->logicViewLayout->addWidget(logic_view_);
  52. free_monitor_widget_ = new FreeMonitorWidget(
  53. register_monitor_service, ui_->monitorContainer);
  54. free_monitor_widget_->setObjectName(QStringLiteral("freeMonitorWidget"));
  55. ui_->monitorContainerLayout->addWidget(free_monitor_widget_);
  56. ui_->upperSplitter->setSizes({600, 600});
  57. ui_->verticalSplitter->setSizes({440, 260});
  58. connect(hmi_view_, &HmiEditorWidget::pageNavigationRequested,
  59. this,
  60. [this](const QString &target_page_id)
  61. {
  62. const HmiNavigationResult result =
  63. hmi_navigation_service_.navigateTo(toUtf8(target_page_id));
  64. if (!result.succeeded)
  65. {
  66. emit navigationFailed(fromUtf8(result.message));
  67. return;
  68. }
  69. showRuntimePage(result.pageId);
  70. emit runtimePageChanged(fromUtf8(result.pageId));
  71. });
  72. connect(ui_->runtimeLogicComboBox,
  73. QOverload<int>::of(&QComboBox::currentIndexChanged),
  74. this,
  75. [this](int index)
  76. {
  77. if (index >= 0)
  78. {
  79. selectRuntimeLogic(toUtf8(
  80. ui_->runtimeLogicComboBox->itemData(index).toString()));
  81. }
  82. });
  83. }
  84. RuntimeMonitorWidget::~RuntimeMonitorWidget() = default;
  85. void RuntimeMonitorWidget::setProjectObjects(
  86. const std::string &page_id, const std::string &logic_id)
  87. {
  88. showRuntimePage(page_id);
  89. const QSignalBlocker blocker(ui_->runtimeLogicComboBox);
  90. ui_->runtimeLogicComboBox->clear();
  91. for (const ControlLogic &logic : project_service_.project().controlLogics)
  92. {
  93. if (logic.enabled)
  94. {
  95. ui_->runtimeLogicComboBox->addItem(
  96. fromUtf8(logic.name), fromUtf8(logic.id));
  97. }
  98. }
  99. int selected_index = ui_->runtimeLogicComboBox->findData(fromUtf8(logic_id));
  100. if (selected_index < 0 && ui_->runtimeLogicComboBox->count() > 0)
  101. {
  102. selected_index = 0;
  103. }
  104. ui_->runtimeLogicComboBox->setCurrentIndex(selected_index);
  105. selectRuntimeLogic(selected_index >= 0
  106. ? toUtf8(ui_->runtimeLogicComboBox->itemData(selected_index).toString())
  107. : std::string{});
  108. }
  109. void RuntimeMonitorWidget::setMode(
  110. ApplicationMode mode, PlcConnectionState plc_state)
  111. {
  112. const bool offline = mode == ApplicationMode::OfflineRunning;
  113. const bool online = mode == ApplicationMode::OnlineRunning;
  114. ui_->logicFrame->setVisible(offline);
  115. hmi_view_->setRuntimeActive(offline || online);
  116. hmi_view_->setRuntimeWriteEnabled(
  117. offline || (online && plc_state == PlcConnectionState::Connected));
  118. if (!offline)
  119. {
  120. logic_view_->clearRuntimeTrace();
  121. latest_trace_.clear();
  122. latest_fault_node_id_.clear();
  123. has_logic_trace_ = false;
  124. }
  125. ui_->modeLabel->setText(
  126. offline ? tr("离线仿真 · 虚拟 M/D")
  127. : online ? tr("真机运行 · PLC 缓存") : tr("当前未运行"));
  128. free_monitor_widget_->refreshValues(mode, plc_state);
  129. }
  130. void RuntimeMonitorWidget::setHmiWriteEnabled(bool enabled)
  131. {
  132. hmi_view_->setRuntimeWriteEnabled(enabled);
  133. }
  134. void RuntimeMonitorWidget::refreshValues(
  135. ApplicationMode mode, PlcConnectionState plc_state)
  136. {
  137. hmi_view_->refreshRuntimeValues();
  138. free_monitor_widget_->refreshValues(mode, plc_state);
  139. }
  140. void RuntimeMonitorWidget::setLogicTrace(
  141. const LogicTraceSnapshot &trace, const std::string &fault_node_id)
  142. {
  143. latest_trace_ = trace;
  144. latest_fault_node_id_ = fault_node_id;
  145. has_logic_trace_ = true;
  146. logic_view_->setRuntimeTrace(
  147. trace.forLogic(selected_logic_id_), fault_node_id);
  148. }
  149. FreeMonitorWidget *RuntimeMonitorWidget::freeMonitorWidget() const
  150. {
  151. return free_monitor_widget_;
  152. }
  153. std::string RuntimeMonitorWidget::selectedLogicId() const
  154. {
  155. return selected_logic_id_;
  156. }
  157. void RuntimeMonitorWidget::showRuntimePage(const std::string &page_id)
  158. {
  159. hmi_view_->setPageId(page_id);
  160. hmi_view_->reloadPage();
  161. const auto page = std::find_if(
  162. project_service_.project().hmiPages.cbegin(),
  163. project_service_.project().hmiPages.cend(),
  164. [&page_id](const HmiPage &candidate) { return candidate.id == page_id; });
  165. ui_->runtimePageLabel->setText(
  166. page == project_service_.project().hmiPages.cend()
  167. ? tr("未选择页面") : fromUtf8(page->name));
  168. }
  169. void RuntimeMonitorWidget::selectRuntimeLogic(const std::string &logic_id)
  170. {
  171. selected_logic_id_ = logic_id;
  172. logic_view_->setLogicId(logic_id);
  173. logic_view_->reloadLogic();
  174. if (has_logic_trace_)
  175. {
  176. logic_view_->setRuntimeTrace(
  177. latest_trace_.forLogic(logic_id), latest_fault_node_id_);
  178. }
  179. }