|
- #include "runtime_monitor_widget.h"
-
- #include "free_monitor_widget.h"
- #include "hmi_editor_widget.h"
- #include "logic_editor_widget.h"
- #include "services/hmi_navigation_service.h"
- #include "services/alarm_service.h"
- #include "services/project_service.h"
- #include "toolbar_icon_factory.h"
- #include "ui_runtime_monitor_widget.h"
-
- #include <QSplitter>
- #include <QComboBox>
- #include <QSignalBlocker>
- #include <QToolButton>
-
- #include <algorithm>
-
- namespace {
-
- QString fromUtf8(const std::string &value)
- {
- return QString::fromUtf8(value.data(), static_cast<int>(value.size()));
- }
-
- std::string toUtf8(const QString &value)
- {
- const QByteArray bytes = value.toUtf8();
- return std::string(bytes.constData(), static_cast<std::size_t>(bytes.size()));
- }
-
- } // namespace
-
- RuntimeMonitorWidget::RuntimeMonitorWidget(
- HmiEditorService &hmi_editor_service,
- HmiRuntimeService &hmi_runtime_service,
- LogicEditorService &logic_editor_service,
- ProjectService &project_service,
- HmiNavigationService &hmi_navigation_service,
- AlarmService &alarm_service,
- RegisterMonitorService ®ister_monitor_service,
- QWidget *parent)
- : QWidget(parent),
- ui_(std::make_unique<Ui::RuntimeMonitorWidget>()),
- project_service_(project_service),
- hmi_navigation_service_(hmi_navigation_service)
- {
- ui_->setupUi(this);
- ui_->exitRuntimeButton->setIcon(makeUiIcon(UiIcon::Exit));
- hmi_view_ = new HmiEditorWidget(
- hmi_editor_service,
- hmi_runtime_service,
- alarm_service,
- ui_->hmiViewContainer);
- hmi_view_->setObjectName(QStringLiteral("runtimeHmiView"));
- hmi_view_->setEditingEnabled(false);
- hmi_view_->setRuntimeActive(true);
- ui_->hmiViewLayout->addWidget(hmi_view_);
-
- logic_view_ = new LogicEditorWidget(logic_editor_service, ui_->logicViewContainer);
- logic_view_->setObjectName(QStringLiteral("runtimeLogicView"));
- logic_view_->setEditingEnabled(false);
- ui_->logicViewLayout->addWidget(logic_view_);
-
- free_monitor_widget_ = new FreeMonitorWidget(
- register_monitor_service, ui_->monitorContainer);
- free_monitor_widget_->setObjectName(QStringLiteral("freeMonitorWidget"));
- ui_->monitorContainerLayout->addWidget(free_monitor_widget_);
- ui_->logicNoticeLabel->setVisible(false);
- ui_->upperSplitter->setSizes({600, 600});
- ui_->verticalSplitter->setSizes({440, 260});
- connect(hmi_view_, &HmiEditorWidget::pageNavigationRequested,
- this,
- [this](const QString &target_page_id)
- {
- const HmiNavigationResult result =
- hmi_navigation_service_.navigateTo(toUtf8(target_page_id));
- if (!result.succeeded)
- {
- emit navigationFailed(fromUtf8(result.message));
- return;
- }
- showRuntimePage(result.pageId);
- });
- connect(ui_->exitRuntimeButton, &QToolButton::clicked,
- this, &RuntimeMonitorWidget::exitRequested);
- connect(ui_->runtimeLogicComboBox,
- QOverload<int>::of(&QComboBox::currentIndexChanged),
- this,
- [this](int index)
- {
- if (index >= 0)
- {
- selectRuntimeLogic(toUtf8(
- ui_->runtimeLogicComboBox->itemData(index).toString()));
- }
- });
- }
-
- RuntimeMonitorWidget::~RuntimeMonitorWidget() = default;
-
- void RuntimeMonitorWidget::setProjectObjects(
- const std::string &page_id, const std::string &logic_id)
- {
- setRuntimePage(page_id);
-
- const QSignalBlocker blocker(ui_->runtimeLogicComboBox);
- ui_->runtimeLogicComboBox->clear();
- for (const ControlLogic &logic : project_service_.project().controlLogics)
- {
- if (logic.enabled)
- {
- ui_->runtimeLogicComboBox->addItem(
- fromUtf8(logic.name), fromUtf8(logic.id));
- }
- }
- int selected_index = ui_->runtimeLogicComboBox->findData(fromUtf8(logic_id));
- if (selected_index < 0 && ui_->runtimeLogicComboBox->count() > 0)
- {
- selected_index = 0;
- }
- ui_->runtimeLogicComboBox->setCurrentIndex(selected_index);
- selectRuntimeLogic(selected_index >= 0
- ? toUtf8(ui_->runtimeLogicComboBox->itemData(selected_index).toString())
- : std::string{});
- }
-
- void RuntimeMonitorWidget::setRuntimePage(const std::string &page_id)
- {
- showRuntimePage(page_id);
- }
-
- void RuntimeMonitorWidget::setMode(
- ApplicationMode mode, PlcConnectionState plc_state)
- {
- const bool offline = mode == ApplicationMode::OfflineRunning;
- const bool online = mode == ApplicationMode::OnlineRunning;
- ui_->logicFrame->setVisible(offline || online);
- hmi_view_->setRuntimeActive(offline || online);
- if (!offline && !online)
- {
- setHmiWriteEnabled(false);
- }
- setFreeMonitorWriteEnabled(offline
- || (online && plc_state == PlcConnectionState::Connected));
- if (!offline && !online)
- {
- logic_view_->clearRuntimeTrace();
- latest_trace_.clear();
- latest_fault_node_id_.clear();
- has_logic_trace_ = false;
- }
- ui_->logicLabel->setText(
- online ? tr("本地推算轨迹") : tr("梯形图运行状态"));
- ui_->logicNoticeLabel->setVisible(online);
- ui_->modeLabel->setText(
- offline ? tr("离线仿真 · 虚拟 M/D")
- : online ? tr("真机运行 · PLC 缓存 · 本地推算轨迹")
- : tr("当前未运行"));
- free_monitor_widget_->refreshValues(mode, plc_state);
- }
-
- void RuntimeMonitorWidget::setHmiWriteEnabled(bool enabled)
- {
- hmi_view_->setRuntimeWriteEnabled(enabled);
- }
-
- void RuntimeMonitorWidget::setFreeMonitorWriteEnabled(bool enabled)
- {
- free_monitor_widget_->setWriteEnabled(enabled);
- }
-
- void RuntimeMonitorWidget::refreshValues(
- ApplicationMode mode, PlcConnectionState plc_state)
- {
- // HMI、报警和自由监控共享同一个活动寄存器仓库
- hmi_view_->refreshRuntimeValues();
- free_monitor_widget_->refreshValues(mode, plc_state);
- }
-
- void RuntimeMonitorWidget::setLogicTrace(
- const LogicTraceSnapshot &trace, const std::string &fault_node_id)
- {
- latest_trace_ = trace;
- latest_fault_node_id_ = fault_node_id;
- has_logic_trace_ = true;
- logic_view_->setRuntimeTrace(
- trace.forLogic(selected_logic_id_), fault_node_id);
- }
-
- FreeMonitorWidget *RuntimeMonitorWidget::freeMonitorWidget() const
- {
- return free_monitor_widget_;
- }
-
- std::string RuntimeMonitorWidget::selectedLogicId() const
- {
- return selected_logic_id_;
- }
-
- void RuntimeMonitorWidget::showRuntimePage(const std::string &page_id)
- {
- hmi_view_->setPageId(page_id);
- hmi_view_->reloadPage();
- const auto page = std::find_if(
- project_service_.project().hmiPages.cbegin(),
- project_service_.project().hmiPages.cend(),
- [&page_id](const HmiPage &candidate) { return candidate.id == page_id; });
- ui_->runtimePageLabel->setText(
- page == project_service_.project().hmiPages.cend()
- ? tr("未选择页面") : fromUtf8(page->name));
- }
-
- void RuntimeMonitorWidget::selectRuntimeLogic(const std::string &logic_id)
- {
- selected_logic_id_ = logic_id;
- logic_view_->setLogicId(logic_id);
- logic_view_->reloadLogic();
- if (has_logic_trace_)
- {
- logic_view_->setRuntimeTrace(
- latest_trace_.forLogic(logic_id), latest_fault_node_id_);
- }
- }
|