| @@ -17,6 +17,7 @@ INCLUDEPATH += src | |||
| SOURCES += \ | |||
| src/main.cpp \ | |||
| src/ui/main_window.cpp \ | |||
| src/ui/plc_connection_dialog.cpp \ | |||
| src/domain/register_address.cpp \ | |||
| src/domain/register_repository.cpp \ | |||
| src/domain/active_register_repository.cpp \ | |||
| @@ -41,9 +42,10 @@ SOURCES += \ | |||
| HEADERS += \ | |||
| src/ui/main_window.h \ | |||
| src/ui/plc_connection_dialog.h \ | |||
| src/domain/register_address.h \ | |||
| src/domain/active_register_repository.h \ | |||
| src/domain/register_repository.h \ | |||
| src/domain/active_register_repository.h \ | |||
| src/domain/data_point_model.h \ | |||
| src/domain/hmi_model.h \ | |||
| src/domain/control_logic_model.h \ | |||
| @@ -57,13 +59,14 @@ HEADERS += \ | |||
| src/services/hmi_runtime_service.h \ | |||
| src/services/software_logic_executor.h \ | |||
| src/services/offline_simulation_service.h \ | |||
| src/services/runtime_mode_service.h \ | |||
| src/services/plc_communication_gateway.h \ | |||
| src/infrastructure/plc_register_repository.h \ | |||
| src/infrastructure/plc_communication_service.h \ | |||
| src/services/runtime_mode_service.h \ | |||
| src/infrastructure/json_project_storage.h \ | |||
| src/ui/hmi_editor_widget.h \ | |||
| src/ui/logic_editor_widget.h | |||
| FORMS += \ | |||
| src/ui/main_window.ui | |||
| src/ui/main_window.ui \ | |||
| src/ui/plc_connection_dialog.ui | |||
| @@ -9,7 +9,11 @@ | |||
| #include <QApplication> | |||
| #include "infrastructure/json_project_storage.h" | |||
| #include "infrastructure/plc_communication_service.h" | |||
| #include "infrastructure/plc_register_repository.h" | |||
| #include "domain/active_register_repository.h" | |||
| #include "services/hmi_editor_service.h" | |||
| #include "services/data_point_service.h" | |||
| #include "services/hmi_runtime_service.h" | |||
| #include "services/logic_editor_service.h" | |||
| #include "services/offline_simulation_service.h" | |||
| @@ -27,17 +31,27 @@ int main(int argc, char *argv[]) | |||
| JsonProjectStorage project_storage; | |||
| ProjectService project_service(project_storage); | |||
| HmiEditorService hmi_editor_service(project_service); | |||
| DataPointService data_point_service(project_service); | |||
| LogicEditorService logic_editor_service(project_service); | |||
| // 当前离线模式使用内存仓库,后续真机模式替换为 PLC 缓存实现 | |||
| VirtualRegisterRepository virtual_register_repository; | |||
| HmiRuntimeService hmi_runtime_service(virtual_register_repository); | |||
| PlcRegisterRepository plc_register_repository; | |||
| ActiveRegisterRepository active_register_repository(virtual_register_repository); | |||
| PlcCommunicationService plc_communication_service(plc_register_repository); | |||
| HmiRuntimeService hmi_runtime_service(active_register_repository); | |||
| OfflineSimulationService offline_simulation_service(virtual_register_repository); | |||
| RuntimeModeService runtime_mode_service( | |||
| project_service, offline_simulation_service); | |||
| runtime_mode_service.configurePlc( | |||
| plc_communication_service, | |||
| active_register_repository, | |||
| virtual_register_repository, | |||
| plc_register_repository); | |||
| MainWindow main_window( | |||
| runtime_mode_service, | |||
| project_service, | |||
| hmi_editor_service, | |||
| data_point_service, | |||
| logic_editor_service, | |||
| hmi_runtime_service); | |||
| main_window.show(); | |||
| @@ -107,6 +107,16 @@ HmiRuntimeWriteResult HmiRuntimeService::writeNumericInput( | |||
| : writeFailure(repositoryError(result.error)); | |||
| } | |||
| BitReadResult HmiRuntimeService::readBit(const RegisterAddress &address) const | |||
| { | |||
| return repository_.readBit(address); | |||
| } | |||
| WordReadResult HmiRuntimeService::readWord(const RegisterAddress &address) const | |||
| { | |||
| return repository_.readWord(address); | |||
| } | |||
| HmiRuntimeError HmiRuntimeService::repositoryError(RegisterError error) | |||
| { | |||
| // 领域仓库错误被收敛为 HMI 可理解的运行错误 | |||
| @@ -78,6 +78,8 @@ public: | |||
| */ | |||
| HmiRuntimeWriteResult writeNumericInput( | |||
| const HmiControl &control, std::int16_t value); | |||
| BitReadResult readBit(const RegisterAddress &address) const; | |||
| WordReadResult readWord(const RegisterAddress &address) const; | |||
| private: | |||
| static HmiRuntimeError repositoryError(RegisterError error); | |||
| @@ -11,6 +11,7 @@ | |||
| #include "domain/hmi_model.h" | |||
| #include "domain/control_logic_model.h" | |||
| #include "domain/runtime_state.h" | |||
| #include "services/plc_communication_gateway.h" | |||
| #include <QMainWindow> | |||
| @@ -18,15 +19,8 @@ | |||
| QT_BEGIN_NAMESPACE | |||
| class QActionGroup; | |||
| class QAction; | |||
| class QComboBox; | |||
| class QLabel; | |||
| class QLineEdit; | |||
| class QPushButton; | |||
| class QSpinBox; | |||
| class QStackedWidget; | |||
| class QTimer; | |||
| class QToolBar; | |||
| namespace Ui { | |||
| class MainWindow; | |||
| @@ -37,6 +31,7 @@ class RuntimeModeService; | |||
| class ProjectService; | |||
| class HmiEditorService; | |||
| class HmiRuntimeService; | |||
| class DataPointService; | |||
| class HmiEditorWidget; | |||
| class LogicEditorService; | |||
| class LogicEditorWidget; | |||
| @@ -63,6 +58,7 @@ public: | |||
| RuntimeModeService &runtime_mode_service, | |||
| ProjectService &project_service, | |||
| HmiEditorService &hmi_editor_service, | |||
| DataPointService &data_point_service, | |||
| LogicEditorService &logic_editor_service, | |||
| HmiRuntimeService &hmi_runtime_service, | |||
| QWidget *parent = nullptr); | |||
| @@ -80,6 +76,8 @@ private: | |||
| void configureLogicEditor(); | |||
| // 创建并连接控件属性编辑表单 | |||
| void configurePropertyEditor(); | |||
| void configureDataPointEditor(); | |||
| void configurePlcConnection(); | |||
| // 刷新工程树和当前 HMI 页面信息 | |||
| void refreshProjectUi(); | |||
| // 显示指定 HMI 控件的可编辑属性 | |||
| @@ -102,6 +100,12 @@ private: | |||
| void deleteSelectedLogicObject(); | |||
| // 将逻辑属性表单内容应用到当前选中节点 | |||
| void applySelectedLogicNodeProperties(); | |||
| void refreshDataPointUi(); | |||
| void addDataPoint(); | |||
| void updateSelectedDataPoint(); | |||
| void deleteSelectedDataPoint(); | |||
| void connectPlc(); | |||
| void disconnectPlc(); | |||
| // 创建新的工程并刷新编辑界面 | |||
| void createNewProject(); | |||
| // 保存当前工程到已关联的路径 | |||
| @@ -144,55 +148,18 @@ private: | |||
| */ | |||
| ProjectService &project_service_; | |||
| HmiEditorService &hmi_editor_service_; | |||
| DataPointService &data_point_service_; | |||
| LogicEditorService &logic_editor_service_; | |||
| HmiRuntimeService &hmi_runtime_service_; | |||
| QActionGroup *mode_action_group_ = nullptr; | |||
| QAction *new_project_action_ = nullptr; | |||
| QAction *save_project_action_ = nullptr; | |||
| QAction *save_as_project_action_ = nullptr; | |||
| QAction *load_project_action_ = nullptr; | |||
| QAction *add_button_action_ = nullptr; | |||
| QAction *add_indicator_action_ = nullptr; | |||
| QAction *add_numeric_display_action_ = nullptr; | |||
| QAction *add_numeric_input_action_ = nullptr; | |||
| QAction *delete_control_action_ = nullptr; | |||
| QAction *add_rung_action_ = nullptr; | |||
| QAction *parallel_insert_action_ = nullptr; | |||
| QAction *add_normally_open_action_ = nullptr; | |||
| QAction *add_normally_closed_action_ = nullptr; | |||
| QAction *add_normal_coil_action_ = nullptr; | |||
| QAction *add_set_coil_action_ = nullptr; | |||
| QAction *add_reset_coil_action_ = nullptr; | |||
| QAction *add_compare_action_ = nullptr; | |||
| QAction *delete_logic_action_ = nullptr; | |||
| QToolBar *hmi_tool_bar_ = nullptr; | |||
| QToolBar *logic_tool_bar_ = nullptr; | |||
| QActionGroup *logic_insert_action_group_ = nullptr; | |||
| HmiEditorWidget *hmi_editor_widget_ = nullptr; | |||
| LogicEditorWidget *logic_editor_widget_ = nullptr; | |||
| QTimer *runtime_refresh_timer_ = nullptr; | |||
| QLabel *mode_status_label_ = nullptr; | |||
| QLabel *register_status_label_ = nullptr; | |||
| QLabel *executor_status_label_ = nullptr; | |||
| QLineEdit *control_id_edit_ = nullptr; | |||
| QLineEdit *control_text_edit_ = nullptr; | |||
| QSpinBox *control_x_spin_box_ = nullptr; | |||
| QSpinBox *control_y_spin_box_ = nullptr; | |||
| QSpinBox *control_width_spin_box_ = nullptr; | |||
| QSpinBox *control_height_spin_box_ = nullptr; | |||
| QComboBox *binding_area_combo_box_ = nullptr; | |||
| QSpinBox *binding_index_spin_box_ = nullptr; | |||
| QPushButton *apply_properties_button_ = nullptr; | |||
| QStackedWidget *property_stack_ = nullptr; | |||
| QWidget *hmi_properties_page_ = nullptr; | |||
| QWidget *logic_properties_page_ = nullptr; | |||
| QLineEdit *logic_node_id_edit_ = nullptr; | |||
| QLabel *logic_node_type_label_ = nullptr; | |||
| QLabel *logic_address_area_label_ = nullptr; | |||
| QSpinBox *logic_address_spin_box_ = nullptr; | |||
| QComboBox *logic_mode_combo_box_ = nullptr; | |||
| QComboBox *logic_comparison_combo_box_ = nullptr; | |||
| QSpinBox *logic_value_spin_box_ = nullptr; | |||
| QPushButton *apply_logic_properties_button_ = nullptr; | |||
| PlcSerialConfiguration plc_configuration_; | |||
| std::string selected_control_id_; | |||
| std::string selected_logic_node_id_; | |||
| }; | |||
| @@ -221,7 +221,12 @@ | |||
| <property name="title"> | |||
| <string>文件(&F)</string> | |||
| </property> | |||
| <addaction name="exitAction"/> | |||
| <addaction name="newProjectAction"/> | |||
| <addaction name="saveProjectAction"/> | |||
| <addaction name="saveAsProjectAction"/> | |||
| <addaction name="loadProjectAction"/> | |||
| <addaction name="separator"/> | |||
| <addaction name="exitAction"/> | |||
| </widget> | |||
| <widget class="QMenu" name="runMenu"> | |||
| <property name="title"> | |||
| @@ -229,7 +234,10 @@ | |||
| </property> | |||
| <addaction name="editingModeAction"/> | |||
| <addaction name="offlineModeAction"/> | |||
| <addaction name="onlineModeAction"/> | |||
| <addaction name="onlineModeAction"/> | |||
| <addaction name="separator"/> | |||
| <addaction name="configurePlcAction"/> | |||
| <addaction name="disconnectPlcAction"/> | |||
| </widget> | |||
| <widget class="QMenu" name="viewMenu"> | |||
| <property name="title"> | |||
| @@ -260,7 +268,39 @@ | |||
| <addaction name="editingModeAction"/> | |||
| <addaction name="offlineModeAction"/> | |||
| <addaction name="onlineModeAction"/> | |||
| </widget> | |||
| <addaction name="configurePlcAction"/> | |||
| <addaction name="disconnectPlcAction"/> | |||
| </widget> | |||
| <widget class="QToolBar" name="hmiToolBar"> | |||
| <property name="windowTitle"><string>HMI 控件</string></property> | |||
| <property name="toolButtonStyle"><enum>Qt::ToolButtonTextBesideIcon</enum></property> | |||
| <attribute name="toolBarArea"><enum>TopToolBarArea</enum></attribute> | |||
| <attribute name="toolBarBreak"><bool>false</bool></attribute> | |||
| <addaction name="addButtonAction"/> | |||
| <addaction name="addIndicatorAction"/> | |||
| <addaction name="addNumericDisplayAction"/> | |||
| <addaction name="addNumericInputAction"/> | |||
| <addaction name="deleteControlAction"/> | |||
| </widget> | |||
| <widget class="QToolBar" name="logicToolBar"> | |||
| <property name="windowTitle"><string>控制逻辑节点</string></property> | |||
| <property name="toolButtonStyle"><enum>Qt::ToolButtonTextBesideIcon</enum></property> | |||
| <attribute name="toolBarArea"><enum>TopToolBarArea</enum></attribute> | |||
| <attribute name="toolBarBreak"><bool>false</bool></attribute> | |||
| <addaction name="addRungAction"/> | |||
| <addaction name="appendInsertAction"/> | |||
| <addaction name="beforeInsertAction"/> | |||
| <addaction name="afterInsertAction"/> | |||
| <addaction name="parallelInsertAction"/> | |||
| <addaction name="separator"/> | |||
| <addaction name="addNormallyOpenAction"/> | |||
| <addaction name="addNormallyClosedAction"/> | |||
| <addaction name="addNormalCoilAction"/> | |||
| <addaction name="addSetCoilAction"/> | |||
| <addaction name="addResetCoilAction"/> | |||
| <addaction name="addCompareAction"/> | |||
| <addaction name="deleteLogicAction"/> | |||
| </widget> | |||
| <widget class="QDockWidget" name="projectDock"> | |||
| <property name="minimumSize"> | |||
| <size> | |||
| @@ -360,32 +400,82 @@ | |||
| <height>164</height> | |||
| </rect> | |||
| </property> | |||
| <layout class="QFormLayout" name="propertiesForm"> | |||
| <property name="fieldGrowthPolicy"> | |||
| <enum>QFormLayout::AllNonFixedFieldsGrow</enum> | |||
| </property> | |||
| <item row="0" column="0"> | |||
| <widget class="QLabel" name="selectionCaptionLabel"> | |||
| <property name="text"> | |||
| <string>当前对象</string> | |||
| </property> | |||
| </widget> | |||
| </item> | |||
| <item row="0" column="1"> | |||
| <widget class="QLabel" name="selectionValueLabel"> | |||
| <property name="text"> | |||
| <string>未选择</string> | |||
| </property> | |||
| </widget> | |||
| </item> | |||
| </layout> | |||
| <layout class="QVBoxLayout" name="propertiesPageLayout"> | |||
| <item> | |||
| <layout class="QFormLayout" name="selectionForm"> | |||
| <item row="0" column="0"><widget class="QLabel" name="selectionCaptionLabel"><property name="text"><string>当前对象</string></property></widget></item> | |||
| <item row="0" column="1"><widget class="QLabel" name="selectionValueLabel"><property name="text"><string>未选择</string></property></widget></item> | |||
| </layout> | |||
| </item> | |||
| <item> | |||
| <widget class="QStackedWidget" name="propertyStack"> | |||
| <widget class="QWidget" name="hmiPropertiesPage"> | |||
| <layout class="QFormLayout" name="hmiPropertiesForm"> | |||
| <property name="fieldGrowthPolicy"><enum>QFormLayout::AllNonFixedFieldsGrow</enum></property> | |||
| <item row="0" column="0"><widget class="QLabel" name="controlIdLabel"><property name="text"><string>控件 ID</string></property></widget></item> | |||
| <item row="0" column="1"><widget class="QLineEdit" name="controlIdEdit"/></item> | |||
| <item row="1" column="0"><widget class="QLabel" name="controlTextLabel"><property name="text"><string>显示文本</string></property></widget></item> | |||
| <item row="1" column="1"><widget class="QLineEdit" name="controlTextEdit"/></item> | |||
| <item row="2" column="0"><widget class="QLabel" name="controlXLabel"><property name="text"><string>X</string></property></widget></item> | |||
| <item row="2" column="1"><widget class="QSpinBox" name="controlXSpinBox"><property name="maximum"><number>4000</number></property></widget></item> | |||
| <item row="3" column="0"><widget class="QLabel" name="controlYLabel"><property name="text"><string>Y</string></property></widget></item> | |||
| <item row="3" column="1"><widget class="QSpinBox" name="controlYSpinBox"><property name="maximum"><number>4000</number></property></widget></item> | |||
| <item row="4" column="0"><widget class="QLabel" name="controlWidthLabel"><property name="text"><string>宽度</string></property></widget></item> | |||
| <item row="4" column="1"><widget class="QSpinBox" name="controlWidthSpinBox"><property name="minimum"><number>1</number></property><property name="maximum"><number>4000</number></property></widget></item> | |||
| <item row="5" column="0"><widget class="QLabel" name="controlHeightLabel"><property name="text"><string>高度</string></property></widget></item> | |||
| <item row="5" column="1"><widget class="QSpinBox" name="controlHeightSpinBox"><property name="minimum"><number>1</number></property><property name="maximum"><number>4000</number></property></widget></item> | |||
| <item row="6" column="0"><widget class="QLabel" name="bindingAreaLabel"><property name="text"><string>绑定区域</string></property></widget></item> | |||
| <item row="6" column="1"><widget class="QComboBox" name="bindingAreaComboBox"> | |||
| <item><property name="text"><string>未绑定</string></property><property name="userData"><string notr="true">-1</string></property></item> | |||
| <item><property name="text"><string>M</string></property><property name="userData"><string notr="true">0</string></property></item> | |||
| <item><property name="text"><string>D</string></property><property name="userData"><string notr="true">1</string></property></item> | |||
| </widget></item> | |||
| <item row="7" column="0"><widget class="QLabel" name="bindingIndexLabel"><property name="text"><string>绑定地址</string></property></widget></item> | |||
| <item row="7" column="1"><widget class="QSpinBox" name="bindingIndexSpinBox"><property name="maximum"><number>4000</number></property></widget></item> | |||
| <item row="8" column="0"><widget class="QLabel" name="hmiDataPointLabel"><property name="text"><string>选择数据点</string></property></widget></item> | |||
| <item row="8" column="1"><widget class="QComboBox" name="hmiDataPointComboBox"/></item> | |||
| <item row="9" column="0" colspan="2"><widget class="QPushButton" name="applyPropertiesButton"><property name="text"><string>应用属性</string></property></widget></item> | |||
| </layout> | |||
| </widget> | |||
| <widget class="QWidget" name="logicPropertiesPage"> | |||
| <layout class="QFormLayout" name="logicPropertiesForm"> | |||
| <property name="fieldGrowthPolicy"><enum>QFormLayout::AllNonFixedFieldsGrow</enum></property> | |||
| <item row="0" column="0"><widget class="QLabel" name="logicNodeIdLabel"><property name="text"><string>节点 ID</string></property></widget></item> | |||
| <item row="0" column="1"><widget class="QLineEdit" name="logicNodeIdEdit"><property name="readOnly"><bool>true</bool></property></widget></item> | |||
| <item row="1" column="0"><widget class="QLabel" name="logicNodeTypeCaption"><property name="text"><string>节点类型</string></property></widget></item> | |||
| <item row="1" column="1"><widget class="QLabel" name="logicNodeTypeLabel"><property name="text"><string/></property></widget></item> | |||
| <item row="2" column="0"><widget class="QLabel" name="logicAddressAreaCaption"><property name="text"><string>地址区域</string></property></widget></item> | |||
| <item row="2" column="1"><widget class="QLabel" name="logicAddressAreaLabel"><property name="text"><string/></property></widget></item> | |||
| <item row="3" column="0"><widget class="QLabel" name="logicAddressLabel"><property name="text"><string>地址</string></property></widget></item> | |||
| <item row="3" column="1"><widget class="QSpinBox" name="logicAddressSpinBox"><property name="maximum"><number>4000</number></property></widget></item> | |||
| <item row="4" column="0"><widget class="QLabel" name="logicDataPointLabel"><property name="text"><string>选择数据点</string></property></widget></item> | |||
| <item row="4" column="1"><widget class="QComboBox" name="logicDataPointComboBox"/></item> | |||
| <item row="5" column="0"><widget class="QLabel" name="logicModeLabel"><property name="text"><string>工作方式</string></property></widget></item> | |||
| <item row="5" column="1"><widget class="QComboBox" name="logicModeComboBox"/></item> | |||
| <item row="6" column="0"><widget class="QLabel" name="logicComparisonLabel"><property name="text"><string>比较运算</string></property></widget></item> | |||
| <item row="6" column="1"><widget class="QComboBox" name="logicComparisonComboBox"> | |||
| <item><property name="text"><string>等于</string></property><property name="userData"><string notr="true">0</string></property></item> | |||
| <item><property name="text"><string>不等于</string></property><property name="userData"><string notr="true">1</string></property></item> | |||
| <item><property name="text"><string>小于</string></property><property name="userData"><string notr="true">2</string></property></item> | |||
| <item><property name="text"><string>小于等于</string></property><property name="userData"><string notr="true">3</string></property></item> | |||
| <item><property name="text"><string>大于</string></property><property name="userData"><string notr="true">4</string></property></item> | |||
| <item><property name="text"><string>大于等于</string></property><property name="userData"><string notr="true">5</string></property></item> | |||
| </widget></item> | |||
| <item row="7" column="0"><widget class="QLabel" name="logicValueLabel"><property name="text"><string>比较常量</string></property></widget></item> | |||
| <item row="7" column="1"><widget class="QSpinBox" name="logicValueSpinBox"><property name="minimum"><number>-32768</number></property><property name="maximum"><number>32767</number></property></widget></item> | |||
| <item row="8" column="0" colspan="2"><widget class="QPushButton" name="applyLogicPropertiesButton"><property name="text"><string>应用属性</string></property></widget></item> | |||
| </layout> | |||
| </widget> | |||
| </widget> | |||
| </item> | |||
| </layout> | |||
| </widget> | |||
| </widget> | |||
| </item> | |||
| </layout> | |||
| </widget> | |||
| </widget> | |||
| <widget class="QDockWidget" name="outputDock"> | |||
| <widget class="QDockWidget" name="outputDock"> | |||
| <property name="minimumSize"> | |||
| <size> | |||
| <width>300</width> | |||
| @@ -422,13 +512,77 @@ | |||
| </widget> | |||
| </item> | |||
| </layout> | |||
| </widget> | |||
| </widget> | |||
| </widget> | |||
| <action name="exitAction"> | |||
| <widget class="QDockWidget" name="dataPointDock"> | |||
| <property name="minimumSize"><size><width>420</width><height>170</height></size></property> | |||
| <property name="windowTitle"><string>数据点</string></property> | |||
| <attribute name="dockWidgetArea"><number>8</number></attribute> | |||
| <widget class="QWidget" name="dataPointDockContents"> | |||
| <layout class="QVBoxLayout" name="dataPointDockLayout"> | |||
| <property name="leftMargin"><number>6</number></property> | |||
| <property name="topMargin"><number>6</number></property> | |||
| <property name="rightMargin"><number>6</number></property> | |||
| <property name="bottomMargin"><number>6</number></property> | |||
| <item> | |||
| <widget class="QTableWidget" name="dataPointTable"> | |||
| <property name="selectionMode"><enum>QAbstractItemView::SingleSelection</enum></property> | |||
| <property name="selectionBehavior"><enum>QAbstractItemView::SelectRows</enum></property> | |||
| <property name="editTriggers"><set>QAbstractItemView::NoEditTriggers</set></property> | |||
| <column><property name="text"><string>地址</string></property></column> | |||
| <column><property name="text"><string>类型</string></property></column> | |||
| <column><property name="text"><string>名称</string></property></column> | |||
| <column><property name="text"><string>注释</string></property></column> | |||
| <column><property name="text"><string>当前值</string></property></column> | |||
| <column><property name="text"><string>引用位置</string></property></column> | |||
| </widget> | |||
| </item> | |||
| <item> | |||
| <layout class="QHBoxLayout" name="dataPointEditorLayout"> | |||
| <item><widget class="QLabel" name="dataPointAreaLabel"><property name="text"><string>区域</string></property></widget></item> | |||
| <item><widget class="QComboBox" name="dataPointAreaComboBox"><item><property name="text"><string>M</string></property><property name="userData"><string notr="true">0</string></property></item><item><property name="text"><string>D</string></property><property name="userData"><string notr="true">1</string></property></item></widget></item> | |||
| <item><widget class="QLabel" name="dataPointAddressLabel"><property name="text"><string>地址</string></property></widget></item> | |||
| <item><widget class="QSpinBox" name="dataPointAddressSpinBox"><property name="maximum"><number>4000</number></property></widget></item> | |||
| <item><widget class="QLabel" name="dataPointNameLabel"><property name="text"><string>名称</string></property></widget></item> | |||
| <item><widget class="QLineEdit" name="dataPointNameEdit"/></item> | |||
| <item><widget class="QLabel" name="dataPointCommentLabel"><property name="text"><string>注释</string></property></widget></item> | |||
| <item><widget class="QLineEdit" name="dataPointCommentEdit"/></item> | |||
| <item><widget class="QPushButton" name="addDataPointButton"><property name="text"><string>新增</string></property></widget></item> | |||
| <item><widget class="QPushButton" name="updateDataPointButton"><property name="text"><string>更新</string></property></widget></item> | |||
| <item><widget class="QPushButton" name="deleteDataPointButton"><property name="text"><string>删除</string></property></widget></item> | |||
| </layout> | |||
| </item> | |||
| </layout> | |||
| </widget> | |||
| </widget> | |||
| <action name="exitAction"> | |||
| <property name="text"> | |||
| <string>退出(&X)</string> | |||
| </property> | |||
| </action> | |||
| </action> | |||
| <action name="newProjectAction"><property name="text"><string>新建工程</string></property></action> | |||
| <action name="saveProjectAction"><property name="text"><string>保存工程</string></property></action> | |||
| <action name="saveAsProjectAction"><property name="text"><string>工程另存为</string></property></action> | |||
| <action name="loadProjectAction"><property name="text"><string>加载工程</string></property></action> | |||
| <action name="configurePlcAction"><property name="text"><string>PLC 配置</string></property><property name="toolTip"><string>配置参数并连接真实 PLC</string></property></action> | |||
| <action name="disconnectPlcAction"><property name="text"><string>断开 PLC</string></property><property name="toolTip"><string>断开当前 PLC 连接</string></property></action> | |||
| <action name="addButtonAction"><property name="text"><string>按钮</string></property><property name="toolTip"><string>添加按钮控件</string></property></action> | |||
| <action name="addIndicatorAction"><property name="text"><string>指示灯</string></property><property name="toolTip"><string>添加指示灯控件</string></property></action> | |||
| <action name="addNumericDisplayAction"><property name="text"><string>数值显示</string></property><property name="toolTip"><string>添加数值显示控件</string></property></action> | |||
| <action name="addNumericInputAction"><property name="text"><string>数值输入</string></property><property name="toolTip"><string>添加数值输入控件</string></property></action> | |||
| <action name="deleteControlAction"><property name="text"><string>删除</string></property><property name="toolTip"><string>删除当前控件</string></property></action> | |||
| <action name="addRungAction"><property name="text"><string>新建网络</string></property><property name="toolTip"><string>在梯形图末尾新增网络</string></property></action> | |||
| <action name="appendInsertAction"><property name="checkable"><bool>true</bool></property><property name="checked"><bool>true</bool></property><property name="text"><string>末尾追加</string></property><property name="toolTip"><string>将下一个条件追加到当前网络末尾</string></property></action> | |||
| <action name="beforeInsertAction"><property name="checkable"><bool>true</bool></property><property name="text"><string>前插</string></property><property name="toolTip"><string>将下一个条件串联到选中节点或支路之前</string></property></action> | |||
| <action name="afterInsertAction"><property name="checkable"><bool>true</bool></property><property name="text"><string>后插</string></property><property name="toolTip"><string>将下一个条件串联到选中节点或支路之后</string></property></action> | |||
| <action name="parallelInsertAction"><property name="checkable"><bool>true</bool></property><property name="text"><string>并联插入</string></property><property name="toolTip"><string>将下一个条件并联到选中节点或整条支路</string></property></action> | |||
| <action name="addNormallyOpenAction"><property name="text"><string>常开</string></property><property name="toolTip"><string>向当前网络添加常开触点</string></property></action> | |||
| <action name="addNormallyClosedAction"><property name="text"><string>常闭</string></property><property name="toolTip"><string>向当前网络添加常闭触点</string></property></action> | |||
| <action name="addNormalCoilAction"><property name="text"><string>线圈</string></property><property name="toolTip"><string>设置当前网络的普通线圈</string></property></action> | |||
| <action name="addSetCoilAction"><property name="text"><string>置位</string></property><property name="toolTip"><string>设置当前网络的置位线圈</string></property></action> | |||
| <action name="addResetCoilAction"><property name="text"><string>复位</string></property><property name="toolTip"><string>设置当前网络的复位线圈</string></property></action> | |||
| <action name="addCompareAction"><property name="text"><string>D 比较</string></property><property name="toolTip"><string>向当前网络添加 D 值与常量比较</string></property></action> | |||
| <action name="deleteLogicAction"><property name="text"><string>删除</string></property><property name="toolTip"><string>删除选中的逻辑节点或网络</string></property></action> | |||
| <action name="editingModeAction"> | |||
| <property name="checkable"> | |||
| <bool>true</bool> | |||
| @@ -468,4 +622,4 @@ | |||
| </widget> | |||
| <resources/> | |||
| <connections/> | |||
| </ui> | |||
| </ui> | |||
| @@ -0,0 +1,88 @@ | |||
| #include "plc_connection_dialog.h" | |||
| #include "ui_plc_connection_dialog.h" | |||
| #include <QComboBox> | |||
| #include <QSerialPortInfo> | |||
| #include <initializer_list> | |||
| namespace { | |||
| void setItemData(QComboBox *combo_box, const std::initializer_list<int> &values) | |||
| { | |||
| int index = 0; | |||
| for (int value : values) | |||
| { | |||
| combo_box->setItemData(index, value); | |||
| ++index; | |||
| } | |||
| } | |||
| void selectData(QComboBox *combo_box, int value) | |||
| { | |||
| const int index = combo_box->findData(value); | |||
| if (index >= 0) | |||
| { | |||
| combo_box->setCurrentIndex(index); | |||
| } | |||
| } | |||
| } // namespace | |||
| PlcConnectionDialog::PlcConnectionDialog( | |||
| const PlcSerialConfiguration &configuration, | |||
| QWidget *parent) | |||
| : QDialog(parent), | |||
| ui_(std::make_unique<Ui::PlcConnectionDialog>()) | |||
| { | |||
| ui_->setupUi(this); | |||
| setItemData(ui_->baudRateComboBox, {9600, 19200, 38400, 57600, 115200}); | |||
| setItemData(ui_->dataBitsComboBox, {7, 8}); | |||
| setItemData(ui_->parityComboBox, {0, 3, 2}); | |||
| setItemData(ui_->stopBitsComboBox, {1, 2}); | |||
| for (const QSerialPortInfo &port : QSerialPortInfo::availablePorts()) | |||
| { | |||
| ui_->serialPortComboBox->addItem( | |||
| port.portName(), | |||
| port.description().isEmpty() ? port.portName() : port.description()); | |||
| } | |||
| const QString port_name = QString::fromUtf8(configuration.portName.c_str()); | |||
| if (!port_name.isEmpty()) | |||
| { | |||
| const int port_index = ui_->serialPortComboBox->findText(port_name); | |||
| if (port_index < 0) | |||
| { | |||
| ui_->serialPortComboBox->addItem(port_name); | |||
| } | |||
| ui_->serialPortComboBox->setCurrentText(port_name); | |||
| } | |||
| ui_->serverAddressSpinBox->setValue(configuration.serverAddress); | |||
| selectData(ui_->baudRateComboBox, configuration.baudRate); | |||
| selectData(ui_->dataBitsComboBox, configuration.dataBits); | |||
| selectData(ui_->parityComboBox, configuration.parity); | |||
| selectData(ui_->stopBitsComboBox, configuration.stopBits); | |||
| ui_->responseTimeoutSpinBox->setValue(configuration.responseTimeoutMs); | |||
| ui_->retriesSpinBox->setValue(configuration.retries); | |||
| ui_->pollIntervalSpinBox->setValue(configuration.pollIntervalMs); | |||
| } | |||
| PlcConnectionDialog::~PlcConnectionDialog() = default; | |||
| PlcSerialConfiguration PlcConnectionDialog::configuration() const | |||
| { | |||
| PlcSerialConfiguration result; | |||
| const QByteArray port_name = ui_->serialPortComboBox->currentText().trimmed().toUtf8(); | |||
| result.portName.assign(port_name.constData(), static_cast<std::size_t>(port_name.size())); | |||
| result.serverAddress = ui_->serverAddressSpinBox->value(); | |||
| result.baudRate = ui_->baudRateComboBox->currentData().toInt(); | |||
| result.dataBits = ui_->dataBitsComboBox->currentData().toInt(); | |||
| result.parity = ui_->parityComboBox->currentData().toInt(); | |||
| result.stopBits = ui_->stopBitsComboBox->currentData().toInt(); | |||
| result.responseTimeoutMs = ui_->responseTimeoutSpinBox->value(); | |||
| result.retries = ui_->retriesSpinBox->value(); | |||
| result.pollIntervalMs = ui_->pollIntervalSpinBox->value(); | |||
| return result; | |||
| } | |||
| @@ -0,0 +1,27 @@ | |||
| #pragma once | |||
| #include "services/plc_communication_gateway.h" | |||
| #include <QDialog> | |||
| #include <memory> | |||
| namespace Ui { | |||
| class PlcConnectionDialog; | |||
| } | |||
| class PlcConnectionDialog final : public QDialog | |||
| { | |||
| Q_OBJECT | |||
| public: | |||
| explicit PlcConnectionDialog( | |||
| const PlcSerialConfiguration &configuration, | |||
| QWidget *parent = nullptr); | |||
| ~PlcConnectionDialog() override; | |||
| PlcSerialConfiguration configuration() const; | |||
| private: | |||
| std::unique_ptr<Ui::PlcConnectionDialog> ui_; | |||
| }; | |||
| @@ -0,0 +1,85 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <ui version="4.0"> | |||
| <class>PlcConnectionDialog</class> | |||
| <widget class="QDialog" name="PlcConnectionDialog"> | |||
| <property name="windowTitle"> | |||
| <string>PLC 通信配置</string> | |||
| </property> | |||
| <property name="minimumSize"> | |||
| <size><width>420</width><height>0</height></size> | |||
| </property> | |||
| <layout class="QVBoxLayout" name="dialogLayout"> | |||
| <item> | |||
| <widget class="QGroupBox" name="serialGroupBox"> | |||
| <property name="title"><string>Modbus RTU 串口</string></property> | |||
| <layout class="QFormLayout" name="serialFormLayout"> | |||
| <property name="fieldGrowthPolicy"><enum>QFormLayout::AllNonFixedFieldsGrow</enum></property> | |||
| <item row="0" column="0"><widget class="QLabel" name="serialPortLabel"><property name="text"><string>端口</string></property></widget></item> | |||
| <item row="0" column="1"> | |||
| <widget class="QComboBox" name="serialPortComboBox"> | |||
| <property name="editable"><bool>true</bool></property> | |||
| <property name="placeholderText"><string>选择或输入 COM 端口</string></property> | |||
| </widget> | |||
| </item> | |||
| <item row="1" column="0"><widget class="QLabel" name="serverAddressLabel"><property name="text"><string>PLC 站号</string></property></widget></item> | |||
| <item row="1" column="1"><widget class="QSpinBox" name="serverAddressSpinBox"><property name="minimum"><number>1</number></property><property name="maximum"><number>247</number></property></widget></item> | |||
| <item row="2" column="0"><widget class="QLabel" name="baudRateLabel"><property name="text"><string>波特率</string></property></widget></item> | |||
| <item row="2" column="1"> | |||
| <widget class="QComboBox" name="baudRateComboBox"> | |||
| <item><property name="text"><string>9600</string></property><property name="userData"><string notr="true">9600</string></property></item> | |||
| <item><property name="text"><string>19200</string></property><property name="userData"><string notr="true">19200</string></property></item> | |||
| <item><property name="text"><string>38400</string></property><property name="userData"><string notr="true">38400</string></property></item> | |||
| <item><property name="text"><string>57600</string></property><property name="userData"><string notr="true">57600</string></property></item> | |||
| <item><property name="text"><string>115200</string></property><property name="userData"><string notr="true">115200</string></property></item> | |||
| </widget> | |||
| </item> | |||
| <item row="3" column="0"><widget class="QLabel" name="dataBitsLabel"><property name="text"><string>数据位</string></property></widget></item> | |||
| <item row="3" column="1"> | |||
| <widget class="QComboBox" name="dataBitsComboBox"> | |||
| <item><property name="text"><string>7</string></property><property name="userData"><string notr="true">7</string></property></item> | |||
| <item><property name="text"><string>8</string></property><property name="userData"><string notr="true">8</string></property></item> | |||
| </widget> | |||
| </item> | |||
| <item row="4" column="0"><widget class="QLabel" name="parityLabel"><property name="text"><string>校验方式</string></property></widget></item> | |||
| <item row="4" column="1"> | |||
| <widget class="QComboBox" name="parityComboBox"> | |||
| <item><property name="text"><string>无校验</string></property><property name="userData"><string notr="true">0</string></property></item> | |||
| <item><property name="text"><string>奇校验</string></property><property name="userData"><string notr="true">3</string></property></item> | |||
| <item><property name="text"><string>偶校验</string></property><property name="userData"><string notr="true">2</string></property></item> | |||
| </widget> | |||
| </item> | |||
| <item row="5" column="0"><widget class="QLabel" name="stopBitsLabel"><property name="text"><string>停止位</string></property></widget></item> | |||
| <item row="5" column="1"> | |||
| <widget class="QComboBox" name="stopBitsComboBox"> | |||
| <item><property name="text"><string>1</string></property><property name="userData"><string notr="true">1</string></property></item> | |||
| <item><property name="text"><string>2</string></property><property name="userData"><string notr="true">2</string></property></item> | |||
| </widget> | |||
| </item> | |||
| </layout> | |||
| </widget> | |||
| </item> | |||
| <item> | |||
| <widget class="QGroupBox" name="timingGroupBox"> | |||
| <property name="title"><string>通信时序</string></property> | |||
| <layout class="QFormLayout" name="timingFormLayout"> | |||
| <item row="0" column="0"><widget class="QLabel" name="responseTimeoutLabel"><property name="text"><string>响应超时</string></property></widget></item> | |||
| <item row="0" column="1"><widget class="QSpinBox" name="responseTimeoutSpinBox"><property name="suffix"><string> ms</string></property><property name="minimum"><number>100</number></property><property name="maximum"><number>30000</number></property><property name="singleStep"><number>100</number></property><property name="value"><number>1000</number></property></widget></item> | |||
| <item row="1" column="0"><widget class="QLabel" name="retriesLabel"><property name="text"><string>失败重试</string></property></widget></item> | |||
| <item row="1" column="1"><widget class="QSpinBox" name="retriesSpinBox"><property name="suffix"><string> 次</string></property><property name="maximum"><number>10</number></property><property name="value"><number>2</number></property></widget></item> | |||
| <item row="2" column="0"><widget class="QLabel" name="pollIntervalLabel"><property name="text"><string>轮询周期</string></property></widget></item> | |||
| <item row="2" column="1"><widget class="QSpinBox" name="pollIntervalSpinBox"><property name="suffix"><string> ms</string></property><property name="minimum"><number>50</number></property><property name="maximum"><number>10000</number></property><property name="singleStep"><number>50</number></property><property name="value"><number>200</number></property></widget></item> | |||
| </layout> | |||
| </widget> | |||
| </item> | |||
| <item> | |||
| <widget class="QDialogButtonBox" name="buttonBox"> | |||
| <property name="standardButtons"><set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set></property> | |||
| </widget> | |||
| </item> | |||
| </layout> | |||
| </widget> | |||
| <connections> | |||
| <connection><sender>buttonBox</sender><signal>accepted()</signal><receiver>PlcConnectionDialog</receiver><slot>accept()</slot><hints><hint type="sourcelabel"><x>320</x><y>360</y></hint><hint type="destinationlabel"><x>210</x><y>180</y></hint></hints></connection> | |||
| <connection><sender>buttonBox</sender><signal>rejected()</signal><receiver>PlcConnectionDialog</receiver><slot>reject()</slot><hints><hint type="sourcelabel"><x>320</x><y>360</y></hint><hint type="destinationlabel"><x>210</x><y>180</y></hint></hints></connection> | |||
| </connections> | |||
| </ui> | |||
| @@ -2,6 +2,7 @@ | |||
| #include "domain/register_repository.h" | |||
| #include "services/hmi_editor_service.h" | |||
| #include "services/hmi_runtime_service.h" | |||
| #include "services/data_point_service.h" | |||
| #include "services/logic_editor_service.h" | |||
| #include "services/offline_simulation_service.h" | |||
| #include "services/project_service.h" | |||
| @@ -9,12 +10,17 @@ | |||
| #include "ui/hmi_editor_widget.h" | |||
| #include "ui/logic_editor_widget.h" | |||
| #include "ui/main_window.h" | |||
| #include "ui/plc_connection_dialog.h" | |||
| #include <QAction> | |||
| #include <QApplication> | |||
| #include <QComboBox> | |||
| #include <QDialog> | |||
| #include <QDockWidget> | |||
| #include <QLabel> | |||
| #include <QLineEdit> | |||
| #include <QSpinBox> | |||
| #include <QTimer> | |||
| #include <iostream> | |||
| #include <stdexcept> | |||
| @@ -60,6 +66,7 @@ void testModeActionsControlEditingAvailability() | |||
| TestProjectStorage storage; | |||
| ProjectService project_service(storage); | |||
| HmiEditorService editor_service(project_service); | |||
| DataPointService data_point_service(project_service); | |||
| LogicEditorService logic_editor_service(project_service); | |||
| VirtualRegisterRepository repository; | |||
| HmiRuntimeService runtime_service(repository); | |||
| @@ -69,6 +76,7 @@ void testModeActionsControlEditingAvailability() | |||
| mode_service, | |||
| project_service, | |||
| editor_service, | |||
| data_point_service, | |||
| logic_editor_service, | |||
| runtime_service); | |||
| window.resize(1000, 640); | |||
| @@ -124,9 +132,11 @@ void testModeActionsControlEditingAvailability() | |||
| logic_editor_service.firstLogicId()); | |||
| require(logic != nullptr && logic->rungs.size() == 1, | |||
| "logic actions must edit the default ladder rung"); | |||
| require(logic->rungs.front().stages.size() == 1 | |||
| && logic->rungs.front().stages.front().branches.size() == 2, | |||
| "parallel insert mode must add a branch to the selected stage"); | |||
| require(logic->rungs.front().condition.has_value() | |||
| && logic->rungs.front().condition->kind | |||
| == ConditionExpressionKind::Parallel | |||
| && logic->rungs.front().condition->children.size() == 2U, | |||
| "parallel insert mode must create a parallel expression"); | |||
| require(logic->rungs.front().output.has_value(), | |||
| "coil action must set the fixed ladder output"); | |||
| @@ -134,11 +144,13 @@ void testModeActionsControlEditingAvailability() | |||
| require(mode_service.mode() == ApplicationMode::Editing, | |||
| "unconfigured ladder nodes must block offline running"); | |||
| const LadderRung &rung = logic->rungs.front(); | |||
| for (const LogicNode &node : rung.stages.front().branches) | |||
| std::vector<const LogicNode *> condition_nodes; | |||
| collectConditionNodes(*rung.condition, &condition_nodes); | |||
| for (const LogicNode *node : condition_nodes) | |||
| { | |||
| require(logic_editor_service.updateNodeConfig( | |||
| logic_editor_service.firstLogicId(), | |||
| node.id, | |||
| node->id, | |||
| ContactNodeConfig{ | |||
| RegisterAddress{RegisterArea::M, 0}, | |||
| ContactMode::NormallyOpen}) | |||
| @@ -198,6 +210,70 @@ void testModeActionsControlEditingAvailability() | |||
| "rejected online running must restore the editing action"); | |||
| } | |||
| void testPlcConfigurationUsesDialog() | |||
| { | |||
| PlcSerialConfiguration initial; | |||
| initial.portName = "COM17"; | |||
| initial.serverAddress = 12; | |||
| initial.baudRate = 38400; | |||
| initial.dataBits = 7; | |||
| initial.parity = 3; | |||
| initial.stopBits = 2; | |||
| initial.responseTimeoutMs = 2500; | |||
| initial.retries = 4; | |||
| initial.pollIntervalMs = 350; | |||
| PlcConnectionDialog configuration_dialog(initial); | |||
| const PlcSerialConfiguration actual = configuration_dialog.configuration(); | |||
| require(actual.portName == initial.portName, | |||
| "PLC dialog must preserve a manually entered serial port"); | |||
| require(actual.serverAddress == initial.serverAddress | |||
| && actual.baudRate == initial.baudRate | |||
| && actual.dataBits == initial.dataBits | |||
| && actual.parity == initial.parity | |||
| && actual.stopBits == initial.stopBits, | |||
| "PLC dialog must preserve Modbus RTU serial parameters"); | |||
| require(actual.responseTimeoutMs == initial.responseTimeoutMs | |||
| && actual.retries == initial.retries | |||
| && actual.pollIntervalMs == initial.pollIntervalMs, | |||
| "PLC dialog must preserve communication timing parameters"); | |||
| TestProjectStorage storage; | |||
| ProjectService project_service(storage); | |||
| HmiEditorService editor_service(project_service); | |||
| DataPointService data_point_service(project_service); | |||
| LogicEditorService logic_editor_service(project_service); | |||
| VirtualRegisterRepository repository; | |||
| HmiRuntimeService runtime_service(repository); | |||
| OfflineSimulationService simulation_service(repository); | |||
| RuntimeModeService mode_service(project_service, simulation_service); | |||
| MainWindow window( | |||
| mode_service, | |||
| project_service, | |||
| editor_service, | |||
| data_point_service, | |||
| logic_editor_service, | |||
| runtime_service); | |||
| require(window.findChild<QComboBox *>(QStringLiteral("serialPortComboBox")) == nullptr, | |||
| "serial configuration controls must not be embedded in the main window"); | |||
| QAction *configure_action = requiredChild<QAction>(window, "configurePlcAction"); | |||
| bool dialog_opened = false; | |||
| QTimer::singleShot( | |||
| 0, | |||
| [&dialog_opened] | |||
| { | |||
| auto *dialog = qobject_cast<PlcConnectionDialog *>( | |||
| QApplication::activeModalWidget()); | |||
| dialog_opened = dialog != nullptr; | |||
| if (dialog != nullptr) | |||
| { | |||
| dialog->reject(); | |||
| } | |||
| }); | |||
| configure_action->trigger(); | |||
| require(dialog_opened, | |||
| "PLC configuration action must open the dedicated configuration dialog"); | |||
| } | |||
| } // namespace | |||
| int main(int argc, char *argv[]) | |||
| @@ -209,6 +285,7 @@ int main(int argc, char *argv[]) | |||
| try | |||
| { | |||
| testModeActionsControlEditingAvailability(); | |||
| testPlcConfigurationUsesDialog(); | |||
| } | |||
| catch (const std::exception &error) | |||
| { | |||
| @@ -1,4 +1,4 @@ | |||
| QT += widgets | |||
| QT += widgets serialport | |||
| TEMPLATE = app | |||
| TARGET = main_window_tests | |||
| @@ -11,15 +11,19 @@ INCLUDEPATH += ../src | |||
| SOURCES += \ | |||
| main_window_tests.cpp \ | |||
| ../src/ui/main_window.cpp \ | |||
| ../src/ui/plc_connection_dialog.cpp \ | |||
| ../src/ui/hmi_editor_widget.cpp \ | |||
| ../src/ui/logic_editor_widget.cpp \ | |||
| ../src/domain/register_address.cpp \ | |||
| ../src/domain/register_repository.cpp \ | |||
| ../src/domain/active_register_repository.cpp \ | |||
| ../src/domain/data_point_model.cpp \ | |||
| ../src/domain/hmi_model.cpp \ | |||
| ../src/domain/control_logic_model.cpp \ | |||
| ../src/domain/project_model.cpp \ | |||
| ../src/domain/runtime_state.cpp \ | |||
| ../src/services/project_service.cpp \ | |||
| ../src/services/data_point_service.cpp \ | |||
| ../src/services/hmi_editor_service.cpp \ | |||
| ../src/services/logic_editor_service.cpp \ | |||
| ../src/services/hmi_runtime_service.cpp \ | |||
| @@ -29,16 +33,20 @@ SOURCES += \ | |||
| HEADERS += \ | |||
| ../src/ui/main_window.h \ | |||
| ../src/ui/plc_connection_dialog.h \ | |||
| ../src/ui/hmi_editor_widget.h \ | |||
| ../src/ui/logic_editor_widget.h \ | |||
| ../src/domain/register_address.h \ | |||
| ../src/domain/register_repository.h \ | |||
| ../src/domain/active_register_repository.h \ | |||
| ../src/domain/data_point_model.h \ | |||
| ../src/domain/hmi_model.h \ | |||
| ../src/domain/control_logic_model.h \ | |||
| ../src/domain/project_model.h \ | |||
| ../src/domain/project_storage.h \ | |||
| ../src/domain/runtime_state.h \ | |||
| ../src/services/project_service.h \ | |||
| ../src/services/data_point_service.h \ | |||
| ../src/services/hmi_editor_service.h \ | |||
| ../src/services/logic_editor_service.h \ | |||
| ../src/services/hmi_runtime_service.h \ | |||
| @@ -46,5 +54,9 @@ HEADERS += \ | |||
| ../src/services/offline_simulation_service.h \ | |||
| ../src/services/runtime_mode_service.h | |||
| HEADERS += \ | |||
| ../src/services/plc_communication_gateway.h | |||
| FORMS += \ | |||
| ../src/ui/main_window.ui | |||
| ../src/ui/main_window.ui \ | |||
| ../src/ui/plc_connection_dialog.ui | |||