综合平台编程器项目的远程存储
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.
 
 
 
 

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