|
- #include "main_window.h"
-
- #include "hmi_editor_widget.h"
- #include "services/hmi_editor_service.h"
- #include "services/hmi_runtime_service.h"
- #include "services/project_service.h"
- #include "services/runtime_mode_service.h"
- #include "ui_main_window.h"
-
- #include <QActionGroup>
- #include <QApplication>
- #include <QComboBox>
- #include <QFileDialog>
- #include <QFormLayout>
- #include <QInputDialog>
- #include <QLabel>
- #include <QLineEdit>
- #include <QMessageBox>
- #include <QPushButton>
- #include <QSpinBox>
- #include <QStatusBar>
- #include <QStyle>
- #include <QTimer>
- #include <QToolBar>
- #include <QTreeWidget>
- #include <QTreeWidgetItem>
-
- namespace {
-
- QString modeText(ApplicationMode mode)
- {
- switch (mode)
- {
- case ApplicationMode::Editing:
- {
- return MainWindow::tr("编辑态");
- }
- case ApplicationMode::OfflineRunning:
- {
- return MainWindow::tr("离线运行态");
- }
- case ApplicationMode::OnlineRunning:
- {
- return MainWindow::tr("真机运行态");
- }
- default:
- {
- return MainWindow::tr("未知状态");
- }
- }
- }
-
- QString transitionErrorText(ModeTransitionError error)
- {
- switch (error)
- {
- case ModeTransitionError::MustReturnToEditing:
- {
- return MainWindow::tr("请先返回编辑态,再切换运行模式");
- }
- case ModeTransitionError::InitialPlcReadRequired:
- {
- return MainWindow::tr("真机运行前必须连接 PLC 并完成首次读取");
- }
- case ModeTransitionError::AlreadyInRequestedMode:
- {
- return MainWindow::tr("当前已处于所选模式");
- }
- case ModeTransitionError::None:
- default:
- {
- return MainWindow::tr("模式切换失败");
- }
- }
- }
-
- std::string toUtf8(const QString &value)
- {
- const QByteArray bytes = value.toUtf8();
- return std::string(bytes.constData(), static_cast<std::size_t>(bytes.size()));
- }
-
- QString fromUtf8(const std::string &value)
- {
- return QString::fromUtf8(value.data(), static_cast<int>(value.size()));
- }
-
- QString controlTypeText(HmiControlType type)
- {
- switch (type)
- {
- case HmiControlType::Button:
- {
- return MainWindow::tr("按钮");
- }
- case HmiControlType::Indicator:
- {
- return MainWindow::tr("指示灯");
- }
- case HmiControlType::NumericDisplay:
- {
- return MainWindow::tr("数值显示");
- }
- case HmiControlType::NumericInput:
- {
- return MainWindow::tr("数值输入");
- }
- case HmiControlType::Label:
- default:
- {
- return MainWindow::tr("文本");
- }
- }
- }
-
- bool usesMAddress(HmiControlType type)
- {
- return type == HmiControlType::Button || type == HmiControlType::Indicator;
- }
-
- } // namespace
-
- MainWindow::MainWindow(
- RuntimeModeService &runtime_mode_service,
- ProjectService &project_service,
- HmiEditorService &hmi_editor_service,
- HmiRuntimeService &hmi_runtime_service,
- QWidget *parent)
- : QMainWindow(parent),
- ui_(std::make_unique<Ui::MainWindow>()),
- runtime_mode_service_(runtime_mode_service),
- project_service_(project_service),
- hmi_editor_service_(hmi_editor_service),
- hmi_runtime_service_(hmi_runtime_service)
- {
- ui_->setupUi(this);
- configureAppearance();
- configureActions();
- configurePropertyEditor();
- configureHmiEditor();
- hmi_editor_service_.ensureDefaultPage();
- refreshProjectUi();
- updateModeUi(tr("系统已进入编辑态"));
- }
-
- MainWindow::~MainWindow() = default;
-
- void MainWindow::configureActions()
- {
- mode_action_group_ = new QActionGroup(this);
- mode_action_group_->setExclusive(true);
- mode_action_group_->addAction(ui_->editingModeAction);
- mode_action_group_->addAction(ui_->offlineModeAction);
- mode_action_group_->addAction(ui_->onlineModeAction);
-
- connect(ui_->editingModeAction, &QAction::triggered, this,
- [this] { requestMode(ApplicationMode::Editing); });
- connect(ui_->offlineModeAction, &QAction::triggered, this,
- [this] { requestMode(ApplicationMode::OfflineRunning); });
- connect(ui_->onlineModeAction, &QAction::triggered, this,
- [this] { requestMode(ApplicationMode::OnlineRunning); });
- connect(ui_->exitAction, &QAction::triggered, qApp, &QApplication::closeAllWindows);
-
- new_project_action_ = new QAction(tr("新建工程"), this);
- save_project_action_ = new QAction(tr("保存工程"), this);
- save_as_project_action_ = new QAction(tr("工程另存为"), this);
- load_project_action_ = new QAction(tr("加载工程"), this);
- new_project_action_->setObjectName(QStringLiteral("newProjectAction"));
- save_project_action_->setObjectName(QStringLiteral("saveProjectAction"));
- save_as_project_action_->setObjectName(QStringLiteral("saveAsProjectAction"));
- load_project_action_->setObjectName(QStringLiteral("loadProjectAction"));
- new_project_action_->setIcon(style()->standardIcon(QStyle::SP_FileIcon));
- save_project_action_->setIcon(style()->standardIcon(QStyle::SP_DialogSaveButton));
- load_project_action_->setIcon(style()->standardIcon(QStyle::SP_DialogOpenButton));
- ui_->fileMenu->insertAction(ui_->exitAction, new_project_action_);
- ui_->fileMenu->insertAction(ui_->exitAction, save_project_action_);
- ui_->fileMenu->insertAction(ui_->exitAction, save_as_project_action_);
- ui_->fileMenu->insertAction(ui_->exitAction, load_project_action_);
- ui_->fileMenu->insertSeparator(ui_->exitAction);
- connect(new_project_action_, &QAction::triggered, this, &MainWindow::createNewProject);
- connect(save_project_action_, &QAction::triggered, this, &MainWindow::saveProject);
- connect(save_as_project_action_, &QAction::triggered, this, &MainWindow::saveProjectAs);
- connect(load_project_action_, &QAction::triggered, this, &MainWindow::loadProject);
-
- hmi_tool_bar_ = addToolBar(tr("HMI 控件"));
- hmi_tool_bar_->setObjectName(QStringLiteral("hmiToolBar"));
- hmi_tool_bar_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
- add_button_action_ = hmi_tool_bar_->addAction(
- style()->standardIcon(QStyle::SP_DialogApplyButton), tr("按钮"));
- add_indicator_action_ = hmi_tool_bar_->addAction(
- style()->standardIcon(QStyle::SP_DialogYesButton), tr("指示灯"));
- add_numeric_display_action_ = hmi_tool_bar_->addAction(
- style()->standardIcon(QStyle::SP_FileDialogInfoView), tr("数值显示"));
- add_numeric_input_action_ = hmi_tool_bar_->addAction(
- style()->standardIcon(QStyle::SP_FileDialogContentsView), tr("数值输入"));
- delete_control_action_ = hmi_tool_bar_->addAction(
- style()->standardIcon(QStyle::SP_TrashIcon), tr("删除"));
- add_button_action_->setObjectName(QStringLiteral("addButtonAction"));
- add_indicator_action_->setObjectName(QStringLiteral("addIndicatorAction"));
- add_numeric_display_action_->setObjectName(QStringLiteral("addNumericDisplayAction"));
- add_numeric_input_action_->setObjectName(QStringLiteral("addNumericInputAction"));
- delete_control_action_->setObjectName(QStringLiteral("deleteControlAction"));
- add_button_action_->setToolTip(tr("添加按钮控件"));
- add_indicator_action_->setToolTip(tr("添加指示灯控件"));
- add_numeric_display_action_->setToolTip(tr("添加数值显示控件"));
- add_numeric_input_action_->setToolTip(tr("添加数值输入控件"));
- delete_control_action_->setToolTip(tr("删除当前控件"));
- connect(add_button_action_, &QAction::triggered, this,
- [this] { addHmiControl(HmiControlType::Button); });
- connect(add_indicator_action_, &QAction::triggered, this,
- [this] { addHmiControl(HmiControlType::Indicator); });
- connect(add_numeric_display_action_, &QAction::triggered, this,
- [this] { addHmiControl(HmiControlType::NumericDisplay); });
- connect(add_numeric_input_action_, &QAction::triggered, this,
- [this] { addHmiControl(HmiControlType::NumericInput); });
- connect(delete_control_action_, &QAction::triggered,
- this, &MainWindow::deleteSelectedControl);
-
- ui_->viewMenu->addAction(ui_->projectDock->toggleViewAction());
- ui_->viewMenu->addAction(ui_->propertiesDock->toggleViewAction());
- ui_->viewMenu->addAction(ui_->outputDock->toggleViewAction());
- ui_->viewMenu->addAction(hmi_tool_bar_->toggleViewAction());
- ui_->viewMenu->addSeparator();
- ui_->viewMenu->addAction(ui_->modeToolBar->toggleViewAction());
- }
-
- void MainWindow::configureAppearance()
- {
- setDockNestingEnabled(true);
- setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea);
- setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
-
- ui_->editingModeAction->setIcon(style()->standardIcon(QStyle::SP_FileDialogDetailedView));
- ui_->offlineModeAction->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
- ui_->onlineModeAction->setIcon(style()->standardIcon(QStyle::SP_DriveNetIcon));
- ui_->editorTabWidget->setTabIcon(0, style()->standardIcon(QStyle::SP_DesktopIcon));
- ui_->editorTabWidget->setTabIcon(1, style()->standardIcon(QStyle::SP_FileDialogListView));
- ui_->outputDock->setMaximumHeight(220);
-
- mode_status_label_ = new QLabel(this);
- mode_status_label_->setObjectName(QStringLiteral("modeStatusLabel"));
- mode_status_label_->setMinimumWidth(88);
- mode_status_label_->setAlignment(Qt::AlignCenter);
- register_status_label_ = new QLabel(this);
- register_status_label_->setMinimumWidth(132);
- executor_status_label_ = new QLabel(this);
- executor_status_label_->setMinimumWidth(132);
- statusBar()->addPermanentWidget(mode_status_label_);
- statusBar()->addPermanentWidget(register_status_label_);
- statusBar()->addPermanentWidget(executor_status_label_);
-
- setStyleSheet(QStringLiteral(
- "QMainWindow { background: #f3f5f7; }"
- "QToolBar { background: #ffffff; border: 0; border-bottom: 1px solid #cbd2d9;"
- " padding: 4px; spacing: 3px; }"
- "QToolButton { min-height: 26px; padding: 3px 9px; border: 1px solid transparent; }"
- "QToolButton:hover { background: #edf2f6; border-color: #c5ced6; }"
- "QToolButton:checked { background: #dcece3; border-color: #75a58a; }"
- "QDockWidget { color: #24313b; font-weight: 600; }"
- "QDockWidget::title { background: #e9edf0; padding: 6px; border-bottom: 1px solid #cbd2d9; }"
- "QTreeWidget, QListWidget, QScrollArea { background: #ffffff; border: 1px solid #d5dbe0; }"
- "QTabWidget::pane { border: 0; background: #f3f5f7; }"
- "QTabBar::tab { background: #e5e9ec; padding: 7px 14px; border-right: 1px solid #cbd2d9; }"
- "QTabBar::tab:selected { background: #ffffff; color: #15232d; }"
- "QFrame#hmiCanvasPlaceholder, QFrame#logicCanvasPlaceholder { background: #ffffff;"
- " border: 1px solid #cbd2d9; }"
- "QLabel#hmiEmptyLabel, QLabel#logicEmptyLabel { color: #75838d; }"
- "QLabel#hmiPageTitleLabel { color: #1d2a33; font-weight: 600; }"
- "QLabel#hmiPageSizeLabel { color: #66747e; }"));
- }
-
- void MainWindow::configureHmiEditor()
- {
- QLayout *layout = ui_->hmiCanvasPlaceholder->layout();
- delete ui_->hmiEmptyLabel;
- hmi_editor_widget_ = new HmiEditorWidget(
- hmi_editor_service_, hmi_runtime_service_, ui_->hmiCanvasPlaceholder);
- hmi_editor_widget_->setMinimumHeight(320);
- layout->addWidget(hmi_editor_widget_);
- connect(hmi_editor_widget_, &HmiEditorWidget::controlSelected,
- this,
- [this](const QString &id) { showControlProperties(toUtf8(id)); });
- connect(hmi_editor_widget_, &HmiEditorWidget::controlChanged,
- this,
- [this](const QString &id)
- {
- showControlProperties(toUtf8(id));
- refreshProjectUi();
- });
- connect(hmi_editor_widget_, &HmiEditorWidget::editorError,
- this,
- [this](const QString &message) { statusBar()->showMessage(message, 5000); });
- runtime_refresh_timer_ = new QTimer(this);
- runtime_refresh_timer_->setInterval(150);
- connect(runtime_refresh_timer_, &QTimer::timeout,
- this,
- [this]
- {
- if (runtime_mode_service_.mode() != ApplicationMode::Editing)
- {
- hmi_editor_widget_->refreshRuntimeValues();
- }
- });
- runtime_refresh_timer_->start();
- }
-
- void MainWindow::configurePropertyEditor()
- {
- control_id_edit_ = new QLineEdit(ui_->propertiesPage);
- control_id_edit_->setObjectName(QStringLiteral("controlIdEdit"));
- control_text_edit_ = new QLineEdit(ui_->propertiesPage);
- control_text_edit_->setObjectName(QStringLiteral("controlTextEdit"));
- control_x_spin_box_ = new QSpinBox(ui_->propertiesPage);
- control_y_spin_box_ = new QSpinBox(ui_->propertiesPage);
- control_width_spin_box_ = new QSpinBox(ui_->propertiesPage);
- control_height_spin_box_ = new QSpinBox(ui_->propertiesPage);
- control_x_spin_box_->setObjectName(QStringLiteral("controlXSpinBox"));
- control_y_spin_box_->setObjectName(QStringLiteral("controlYSpinBox"));
- control_width_spin_box_->setObjectName(QStringLiteral("controlWidthSpinBox"));
- control_height_spin_box_->setObjectName(QStringLiteral("controlHeightSpinBox"));
- for (QSpinBox *box : {control_x_spin_box_, control_y_spin_box_})
- {
- box->setRange(0, 4000);
- }
- for (QSpinBox *box : {control_width_spin_box_, control_height_spin_box_})
- {
- box->setRange(1, 4000);
- }
- binding_area_combo_box_ = new QComboBox(ui_->propertiesPage);
- binding_area_combo_box_->setObjectName(QStringLiteral("bindingAreaComboBox"));
- binding_area_combo_box_->addItem(QStringLiteral("M"), QVariant::fromValue(0));
- binding_area_combo_box_->addItem(QStringLiteral("D"), QVariant::fromValue(1));
- binding_index_spin_box_ = new QSpinBox(ui_->propertiesPage);
- binding_index_spin_box_->setObjectName(QStringLiteral("bindingIndexSpinBox"));
- binding_index_spin_box_->setRange(0, RegisterAddress::kMaximumIndex);
- apply_properties_button_ = new QPushButton(tr("应用属性"), ui_->propertiesPage);
- apply_properties_button_->setObjectName(QStringLiteral("applyPropertiesButton"));
- QFormLayout *form = ui_->propertiesForm;
- form->addRow(tr("控件 ID"), control_id_edit_);
- form->addRow(tr("显示文本"), control_text_edit_);
- form->addRow(tr("X"), control_x_spin_box_);
- form->addRow(tr("Y"), control_y_spin_box_);
- form->addRow(tr("宽度"), control_width_spin_box_);
- form->addRow(tr("高度"), control_height_spin_box_);
- form->addRow(tr("绑定区域"), binding_area_combo_box_);
- form->addRow(tr("绑定地址"), binding_index_spin_box_);
- form->addRow(apply_properties_button_);
- connect(apply_properties_button_, &QPushButton::clicked,
- this, &MainWindow::applySelectedControlProperties);
- showControlProperties({});
- }
-
- void MainWindow::refreshProjectUi()
- {
- const std::string current_page_id = hmi_editor_service_.firstPageId();
- if (hmi_editor_widget_ != nullptr)
- {
- hmi_editor_widget_->setPageId(current_page_id);
- }
- const HmiPage *page = hmi_editor_service_.findPage(current_page_id);
- ui_->projectTree->clear();
- auto *hmi_root = new QTreeWidgetItem(ui_->projectTree, {tr("HMI 页面")});
- if (page != nullptr)
- {
- hmi_root->addChild(new QTreeWidgetItem(hmi_root, {fromUtf8(page->name)}));
- ui_->hmiPageTitleLabel->setText(fromUtf8(page->name));
- ui_->hmiPageSizeLabel->setText(
- tr("%1 x %2").arg(page->width).arg(page->height));
- }
- else
- {
- ui_->hmiPageTitleLabel->setText(tr("尚未创建 HMI 页面"));
- ui_->hmiPageSizeLabel->clear();
- }
- new QTreeWidgetItem(ui_->projectTree, {tr("控制逻辑")});
- ui_->projectTree->expandAll();
- }
-
- void MainWindow::showControlProperties(const std::string &control_id)
- {
- selected_control_id_ = control_id;
- const HmiControl *control = hmi_editor_service_.findControl(
- hmi_editor_service_.firstPageId(), control_id);
- const bool has_control = control != nullptr;
- ui_->selectionValueLabel->setText(
- has_control ? fromUtf8(control->id) : tr("未选择"));
- for (QWidget *widget : {static_cast<QWidget *>(control_id_edit_),
- static_cast<QWidget *>(control_text_edit_),
- static_cast<QWidget *>(control_x_spin_box_),
- static_cast<QWidget *>(control_y_spin_box_),
- static_cast<QWidget *>(control_width_spin_box_),
- static_cast<QWidget *>(control_height_spin_box_),
- static_cast<QWidget *>(binding_area_combo_box_),
- static_cast<QWidget *>(binding_index_spin_box_),
- static_cast<QWidget *>(apply_properties_button_)})
- {
- widget->setEnabled(has_control);
- }
- if (!has_control)
- {
- return;
- }
- control_id_edit_->setText(fromUtf8(control->id));
- control_text_edit_->setText(fromUtf8(control->text));
- control_x_spin_box_->setValue(control->bounds.x);
- control_y_spin_box_->setValue(control->bounds.y);
- control_width_spin_box_->setValue(control->bounds.width);
- control_height_spin_box_->setValue(control->bounds.height);
- const RegisterArea default_area = usesMAddress(control->type)
- ? RegisterArea::M : RegisterArea::D;
- const RegisterArea area = control->binding.has_value()
- ? control->binding->area() : default_area;
- binding_area_combo_box_->setCurrentIndex(area == RegisterArea::M ? 0 : 1);
- binding_index_spin_box_->setValue(
- control->binding.has_value() ? control->binding->index() : 0);
- }
-
- void MainWindow::addHmiControl(HmiControlType type)
- {
- const std::string page_id = hmi_editor_service_.firstPageId();
- const HmiEditorResult result = hmi_editor_service_.addControl(page_id, type);
- if (!result.succeeded)
- {
- showProjectResult(tr("添加控件"), fromUtf8(result.message), false);
- return;
- }
- hmi_editor_widget_->reloadPage();
- hmi_editor_widget_->selectControl(result.id);
- showControlProperties(result.id);
- refreshProjectUi();
- statusBar()->showMessage(tr("已添加%1").arg(controlTypeText(type)), 3000);
- }
-
- void MainWindow::deleteSelectedControl()
- {
- if (selected_control_id_.empty())
- {
- return;
- }
- const HmiEditorResult result = hmi_editor_service_.removeControl(
- hmi_editor_service_.firstPageId(), selected_control_id_);
- if (!result.succeeded)
- {
- showProjectResult(tr("删除控件"), fromUtf8(result.message), false);
- return;
- }
- selected_control_id_.clear();
- hmi_editor_widget_->reloadPage();
- showControlProperties({});
- refreshProjectUi();
- }
-
- void MainWindow::applySelectedControlProperties()
- {
- const HmiControl *old_control = hmi_editor_service_.findControl(
- hmi_editor_service_.firstPageId(), selected_control_id_);
- if (old_control == nullptr)
- {
- return;
- }
- HmiControl control = *old_control;
- control.id = toUtf8(control_id_edit_->text());
- control.text = toUtf8(control_text_edit_->text());
- control.bounds.x = control_x_spin_box_->value();
- control.bounds.y = control_y_spin_box_->value();
- control.bounds.width = control_width_spin_box_->value();
- control.bounds.height = control_height_spin_box_->value();
- const RegisterArea area = binding_area_combo_box_->currentIndex() == 0
- ? RegisterArea::M : RegisterArea::D;
- control.binding = RegisterAddress{area, binding_index_spin_box_->value()};
- const HmiEditorResult result = hmi_editor_service_.updateControl(
- hmi_editor_service_.firstPageId(), selected_control_id_, control);
- if (!result.succeeded)
- {
- showProjectResult(tr("应用属性"), fromUtf8(result.message), false);
- return;
- }
- selected_control_id_ = result.id;
- hmi_editor_widget_->reloadPage();
- hmi_editor_widget_->selectControl(selected_control_id_);
- refreshProjectUi();
- statusBar()->showMessage(tr("控件属性已更新"), 3000);
- }
-
- void MainWindow::createNewProject()
- {
- const QString name = QInputDialog::getText(
- this, tr("新建工程"), tr("工程名称"));
- if (name.isEmpty())
- {
- return;
- }
- const ProjectOperationResult result = project_service_.createNewProject(toUtf8(name));
- if (!result.succeeded)
- {
- showProjectResult(tr("新建工程"), fromUtf8(result.message), false);
- return;
- }
- hmi_editor_service_.ensureDefaultPage();
- selected_control_id_.clear();
- refreshProjectUi();
- hmi_editor_widget_->reloadPage();
- showControlProperties({});
- statusBar()->showMessage(tr("已创建新工程"), 3000);
- }
-
- void MainWindow::saveProject()
- {
- const ProjectOperationResult result = project_service_.save();
- if (!result.succeeded)
- {
- saveProjectAs();
- return;
- }
- showProjectResult(tr("保存工程"), tr("工程已保存"), true);
- }
-
- void MainWindow::saveProjectAs()
- {
- const QString path = QFileDialog::getSaveFileName(
- this, tr("工程另存为"), {}, tr("工程文件 (*.json)"));
- if (path.isEmpty())
- {
- return;
- }
- const ProjectOperationResult result = project_service_.saveAs(toUtf8(path));
- showProjectResult(
- tr("保存工程"),
- result.succeeded ? tr("工程已保存") : fromUtf8(result.message),
- result.succeeded);
- }
-
- void MainWindow::loadProject()
- {
- const QString path = QFileDialog::getOpenFileName(
- this, tr("加载工程"), {}, tr("工程文件 (*.json)"));
- if (path.isEmpty())
- {
- return;
- }
- const ProjectOperationResult result = project_service_.load(toUtf8(path));
- if (!result.succeeded)
- {
- showProjectResult(tr("加载工程"), fromUtf8(result.message), false);
- return;
- }
- selected_control_id_.clear();
- refreshProjectUi();
- hmi_editor_widget_->reloadPage();
- showControlProperties({});
- showProjectResult(tr("加载工程"), tr("工程已加载"), true);
- }
-
- void MainWindow::showProjectResult(
- const QString &action, const QString &message, bool succeeded)
- {
- const QString output = action + QStringLiteral(": ") + message;
- statusBar()->showMessage(output, 5000);
- ui_->outputList->addItem(output);
- ui_->outputList->scrollToBottom();
- if (!succeeded)
- {
- QMessageBox::warning(this, action, message);
- }
- }
-
- void MainWindow::requestMode(ApplicationMode requested_mode)
- {
- ModeTransitionResult result;
- switch (requested_mode)
- {
- case ApplicationMode::Editing:
- {
- result = runtime_mode_service_.enterEditing();
- break;
- }
- case ApplicationMode::OfflineRunning:
- {
- result = runtime_mode_service_.enterOfflineRunning();
- break;
- }
- case ApplicationMode::OnlineRunning:
- {
- result = runtime_mode_service_.enterOnlineRunning();
- break;
- }
- default:
- {
- restoreCurrentModeAction();
- statusBar()->showMessage(tr("不支持的运行模式"), 5000);
- return;
- }
- }
- if (!result.succeeded)
- {
- restoreCurrentModeAction();
- statusBar()->showMessage(transitionErrorText(result.error), 5000);
- return;
- }
- updateModeUi(tr("已进入%1").arg(modeText(runtime_mode_service_.mode())));
- }
-
- void MainWindow::updateModeUi(const QString &message)
- {
- const ApplicationMode mode = runtime_mode_service_.mode();
- const ModePolicy policy = runtime_mode_service_.policy();
- restoreCurrentModeAction();
- ui_->projectDock->setEnabled(policy.allowsProjectEditing);
- ui_->propertiesDock->setEnabled(policy.allowsProjectEditing);
- hmi_editor_widget_->setEditingEnabled(policy.allowsProjectEditing);
- hmi_editor_widget_->setRuntimeActive(policy.usesVirtualRegisters);
- hmi_tool_bar_->setEnabled(policy.allowsProjectEditing);
- add_button_action_->setEnabled(policy.allowsProjectEditing);
- add_indicator_action_->setEnabled(policy.allowsProjectEditing);
- add_numeric_display_action_->setEnabled(policy.allowsProjectEditing);
- add_numeric_input_action_->setEnabled(policy.allowsProjectEditing);
- delete_control_action_->setEnabled(policy.allowsProjectEditing);
- new_project_action_->setEnabled(policy.allowsProjectEditing);
- save_project_action_->setEnabled(policy.allowsProjectEditing);
- save_as_project_action_->setEnabled(policy.allowsProjectEditing);
- load_project_action_->setEnabled(policy.allowsProjectEditing);
-
- mode_status_label_->setText(modeText(mode));
- if (mode == ApplicationMode::Editing)
- {
- mode_status_label_->setStyleSheet(QStringLiteral(
- "border: 1px solid #75a58a; background: #e3f0e8; color: #205c3b; padding: 2px 8px;"));
- }
- else if (mode == ApplicationMode::OfflineRunning)
- {
- mode_status_label_->setStyleSheet(QStringLiteral(
- "border: 1px solid #bd8739; background: #fff0d2; color: #744b0e; padding: 2px 8px;"));
- }
- else
- {
- mode_status_label_->setStyleSheet(QStringLiteral(
- "border: 1px solid #4b88a8; background: #deeff7; color: #174f6c; padding: 2px 8px;"));
- }
- register_status_label_->setText(
- policy.usesVirtualRegisters ? tr("数据源:虚拟 M/D")
- : policy.usesPlcRegisters ? tr("数据源:PLC 缓存") : tr("数据源:未启用"));
- executor_status_label_->setText(
- policy.runsLogicExecutor ? tr("逻辑执行器:运行") : tr("逻辑执行器:停止"));
- statusBar()->showMessage(message, 4000);
- ui_->outputList->addItem(message);
- ui_->outputList->scrollToBottom();
- }
-
- void MainWindow::restoreCurrentModeAction()
- {
- ui_->editingModeAction->setChecked(runtime_mode_service_.mode()
- == ApplicationMode::Editing);
- ui_->offlineModeAction->setChecked(runtime_mode_service_.mode()
- == ApplicationMode::OfflineRunning);
- ui_->onlineModeAction->setChecked(runtime_mode_service_.mode()
- == ApplicationMode::OnlineRunning);
- }
|