From 2fda1036bdc0919651017117a4cbe59546cb0a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A8?= =?UTF-8?q?=D1=82=D0=B5=D0=B9=D0=B1=D0=B5=D0=B7=D0=B0=D0=BD=D0=B4=D1=82?= <vyacheslavshteibezandt@gmail.com> Date: Tue, 11 Mar 2025 14:41:08 +0300 Subject: [PATCH] 1.0 Dev --- ProjectSettings.h | 72 + UnionCom.pro | 81 + UnionCom_global.h | 12 + canidcalc.cpp | 137 ++ canidcalc.h | 65 + canidcalc.ui | 323 ++++ canusb.cpp | 153 ++ canusb.h | 67 + canusb.ui | 258 +++ crc16.cpp | 134 ++ crc16.h | 30 + crc16.ui | 549 ++++++ macrossetting.cpp | 453 +++++ macrossetting.h | 211 +++ macrossetting.ui | 4019 ++++++++++++++++++++++++++++++++++++++++ main.cpp | 23 + mainmenu.cpp | 37 + mainmenu.h | 28 + mainmenu.ui | 74 + slcan.h | 510 +++++ slcan.lib | Bin 0 -> 12884 bytes union_modbus.cpp | 445 +++++ union_modbus.h | 80 + union_modbus.ui | 675 +++++++ union_modbus_slave.cpp | 335 ++++ union_modbus_slave.h | 77 + union_modbus_slave.ui | 798 ++++++++ unioncom.cpp | 3280 ++++++++++++++++++++++++++++++++ unioncom.h | 316 ++++ unioncom.ui | 3197 ++++++++++++++++++++++++++++++++ usettingsrs.cpp | 188 ++ usettingsrs.h | 58 + usettingsrs.ui | 175 ++ writeregistermodel.cpp | 167 ++ writeregistermodel.h | 88 + 35 files changed, 17115 insertions(+) create mode 100644 ProjectSettings.h create mode 100644 UnionCom.pro create mode 100644 UnionCom_global.h create mode 100644 canidcalc.cpp create mode 100644 canidcalc.h create mode 100644 canidcalc.ui create mode 100644 canusb.cpp create mode 100644 canusb.h create mode 100644 canusb.ui create mode 100644 crc16.cpp create mode 100644 crc16.h create mode 100644 crc16.ui create mode 100644 macrossetting.cpp create mode 100644 macrossetting.h create mode 100644 macrossetting.ui create mode 100644 main.cpp create mode 100644 mainmenu.cpp create mode 100644 mainmenu.h create mode 100644 mainmenu.ui create mode 100644 slcan.h create mode 100644 slcan.lib create mode 100644 union_modbus.cpp create mode 100644 union_modbus.h create mode 100644 union_modbus.ui create mode 100644 union_modbus_slave.cpp create mode 100644 union_modbus_slave.h create mode 100644 union_modbus_slave.ui create mode 100644 unioncom.cpp create mode 100644 unioncom.h create mode 100644 unioncom.ui create mode 100644 usettingsrs.cpp create mode 100644 usettingsrs.h create mode 100644 usettingsrs.ui create mode 100644 writeregistermodel.cpp create mode 100644 writeregistermodel.h diff --git a/ProjectSettings.h b/ProjectSettings.h new file mode 100644 index 0000000..06338b5 --- /dev/null +++ b/ProjectSettings.h @@ -0,0 +1,72 @@ +#ifndef PROJECTSETTINGS_H +#define PROJECTSETTINGS_H + +#define CMD_TO_LOAD_FILE "SENDFILE" +#define FRAMES 512 // размер буфера для чтения, кол-во кадров +#define READDELAY 5000 + +#define MAX_DLC_SIZE 1 +#define MAX_MACROS_RTR_SIZE 1 +#define MAX_MACROS_EID_SIZE 1 +#define MAX_MACROS_ID_SIZE 8 +#define MAX_MACROS_HEX_SIZE 1 +#define MAX_MACROS_NAME_SIZE 8 +#define MAX_MACROS_SIZE 256 + +#define NORMAL_MSG_TO_LOGGER 0 +#define WARNING_TO_LOGGER 1 +#define GHOST_TO_LOGGER 2 +#define TX_ERROR_EVENT 3 +#define RX_ERROR_EVENT 4 + +#define RX_CAN_GROUP_TABLE_COUNT_COLUMN 0 +#define RX_CAN_GROUP_TABLE_TIME_COLUMN 1 +#define RX_CAN_GROUP_TABLE_PERIOD_COLUMN 2 +#define RX_CAN_GROUP_TABLE_ID_COLUMN 3 +#define RX_CAN_GROUP_TABLE_E_COLUMN 4 +#define RX_CAN_GROUP_TABLE_R_COLUMN 5 +#define RX_CAN_GROUP_TABLE_DLC_COLUMN 6 +#define RX_CAN_GROUP_TABLE_DATA_COLUMN 7 +#define RX_CAN_GROUP_TABLE_TMPS 8 + +#define RX_CAN_REQUESTER_GROUP_TABLE_COUNT_COLUMN 0 +#define RX_CAN_REQUESTER_GROUP_TABLE_TIME_COLUMN 1 +#define RX_CAN_REQUESTER_GROUP_TABLE_PERIOD_COLUMN 2 +#define RX_CAN_REQUESTER_GROUP_TABLE_ID_COLUMN 3 +#define RX_CAN_REQUESTER_GROUP_TABLE_ROUTE 4 +#define RX_CAN_REQUESTER_GROUP_TABLE_DATATYPE 5 +#define RX_CAN_REQUESTER_GROUP_TABLE_SENSORTYPE 6 +#define RX_CAN_REQUESTER_GROUP_TABLE_SENSORID 7 +#define RX_CAN_REQUESTER_GROUP_TABLE_DEVICE 8 +#define RX_CAN_REQUESTER_GROUP_TABLE_E_COLUMN 9 +#define RX_CAN_REQUESTER_GROUP_TABLE_R_COLUMN 10 +#define RX_CAN_REQUESTER_GROUP_TABLE_DLC_COLUMN 11 +#define RX_CAN_REQUESTER_GROUP_TABLE_DATA_COLUMN 12 +#define RX_CAN_REQUESTER_GROUP_TABLE_TMPS 13 + +#include "chrono" +#include "QDebug" +#include "QTime" +#include "QMessageBox" +#include <QFileDialog> +#include "QTimer" +#include "QLineEdit" +#include "QCheckBox" +#include "QThread" +#include "QtConcurrent/QtConcurrent" + + +//#include "QTextCodec" + +#include <QSerialPort> + +#include "crc16.h" +#include "writeregistermodel.h" +#include "canusb.h" +#include "mainmenu.h" +#include "unioncom.h" +#include "usettingsrs.h" +#include "macrossetting.h" +#include "union_modbus.h" +#include "union_modbus_slave.h" +#endif // PROJECTSETTINGS_H diff --git a/UnionCom.pro b/UnionCom.pro new file mode 100644 index 0000000..e00e1e7 --- /dev/null +++ b/UnionCom.pro @@ -0,0 +1,81 @@ +QT -= gui + +QT += core gui +QT += widgets serialport +QT += serialbus widgets + +requires(qtConfig(combobox)) + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +QT += serialport + +TEMPLATE = lib +DEFINES += UNIONCOM_LIBRARY + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + canidcalc.cpp \ + canusb.cpp \ + crc16.cpp \ + macrossetting.cpp \ + main.cpp \ + mainmenu.cpp \ + union_modbus.cpp \ + union_modbus_slave.cpp \ + unioncom.cpp \ + usettingsrs.cpp \ + writeregistermodel.cpp + +HEADERS += \ + ProjectSettings.h \ + canidcalc.h \ + canusb.h \ + crc16.h \ + macrossetting.h \ + mainmenu.h \ + slcan.h \ + union_modbus.h \ + union_modbus_slave.h \ + unioncom.h \ + usettingsrs.h \ + writeregistermodel.h + +FORMS += \ + canidcalc.ui \ + canusb.ui \ + crc16.ui \ + macrossetting.ui \ + mainmenu.ui \ + union_modbus.ui \ + union_modbus_slave.ui \ + unioncom.ui \ + usettingsrs.ui + + +# Default rules for deployment. +unix { + target.path = /usr/lib +} +!isEmpty(target.path): INSTALLS += target + +win32: LIBS += -L$$PWD/./ -lslcan + +#win32:CONFIG(release, debug|release): LIBS += -L$$PWD/./ -lslcan +#else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/./ -lslcand +#else:unix: LIBS += -L$$PWD/./ -lslcan + +#INCLUDEPATH += $$PWD/. +#DEPENDPATH += $$PWD/. diff --git a/UnionCom_global.h b/UnionCom_global.h new file mode 100644 index 0000000..1426575 --- /dev/null +++ b/UnionCom_global.h @@ -0,0 +1,12 @@ +#ifndef UNIONCOM_GLOBAL_H +#define UNIONCOM_GLOBAL_H + +#include <QtCore/qglobal.h> + +#if defined(UNIONCOM_LIBRARY) +# define UNIONCOM_EXPORT Q_DECL_EXPORT +#else +# define UNIONCOM_EXPORT Q_DECL_IMPORT +#endif + +#endif // UNIONCOM_GLOBAL_H diff --git a/canidcalc.cpp b/canidcalc.cpp new file mode 100644 index 0000000..deed730 --- /dev/null +++ b/canidcalc.cpp @@ -0,0 +1,137 @@ +#include "canidcalc.h" +#include "ui_canidcalc.h" + +CanIdCalc::CanIdCalc(QWidget *parent) : + QWidget(parent), + ui(new Ui::CanIdCalc) +{ + ui->setupUi(this); + CanId.ID_All = 0; + CanIdModbus.ID_All = 0; + ui->StrAdrBox->setValue(0); + on_DataTypeBox_currentIndexChanged(0); +} + +CanIdCalc::~CanIdCalc() +{ + delete ui; +} + +void CanIdCalc::on_DataTypeBox_currentIndexChanged(int index) +{ + isModbus = false; + ui->SensorTypeBox->clear(); + ui->SensorTypeBox->setEnabled(true); + ui->SensorIdBox->setEnabled(true); + ui->SensorTypeLabel->show(); + ui->SensorTypeBox->show(); + ui->StrAdrLabel->hide(); + ui->StrAdrBox->hide(); + ui->SensorTypeLabel->setText("Sensor Type"); + ui->SensorIdLabel->setText("Sensor ID"); + ui->SensorIdBox->setMaximum(2047); + ui->SensorIdBox->setValue(CanId.Fields.SensorID); + CanId.Fields.DataType = index; + CanIdModbus.Fields.DataType = index; + switch (index) { + case 0: + ui->SensorTypeBox->addItem("Статус"); + ui->SensorTypeBox->addItem("Запрос на вкл/выкл"); + ui->SensorTypeBox->addItem("Рестарт устройств"); + ui->SensorTypeBox->addItem("Установка времени"); + break; + case 1: + ui->SensorTypeBox->addItem("Аварии"); + ui->SensorTypeBox->addItem("Предупреждения"); + ui->SensorTypeBox->addItem("Управляющие сигналы"); + ui->SensorTypeBox->addItem("Флаги"); + ui->SensorTypeBox->addItem("Рестарт устройства"); + ui->SensorTypeBox->addItem("Изменение режима работы устройства"); + ui->SensorTypeBox->addItem("Перечень параметров"); + break; + case 2: + ui->SensorTypeBox->addItem("Универсальный запрос"); + ui->SensorTypeBox->addItem("Уставки"); + ui->SensorTypeBox->addItem("Напряжение"); + ui->SensorTypeBox->addItem("Ток"); + ui->SensorTypeBox->addItem("Температура"); + break; + case 3: + case 4: + case 5: + case 6: + isModbus = true; + ui->SensorTypeLabel->hide(); + ui->SensorTypeBox->hide(); + ui->StrAdrLabel->show(); + ui->StrAdrBox->show(); + ui->SensorIdLabel->setText("Кол-во регистров"); + ui->SensorIdBox->setMaximum(255); + ui->SensorIdBox->setValue(CanIdModbus.Fields.CountReg); + on_StrAdrBox_valueChanged(ui->StrAdrBox->value()); + break; + case 7: + CanId.Fields.DataType = 0xF; + ui->SensorTypeBox->addItem("Пульс"); + ui->SensorTypeBox->setEnabled(false); + ui->SensorIdBox->setEnabled(false); + ui->SensorIdBox->setValue(0); + break; + } + id_Calc(); +} + +void CanIdCalc::on_SensorTypeBox_currentIndexChanged(int index) +{ + CanId.Fields.SensorType = index; + id_Calc(); +} + +void CanIdCalc::on_SensorIdBox_valueChanged(int arg1) +{ + CanId.Fields.SensorID = arg1; + CanIdModbus.Fields.CountReg = arg1; + id_Calc(); +} + +void CanIdCalc::on_DeviceIdBox_valueChanged(int arg1) +{ + CanId.Fields.Device = arg1; + CanIdModbus.Fields.Device = arg1; + id_Calc(); +} + +void CanIdCalc::id_Calc() +{ + if(isModbus) + { + ui->ResultLine->setText(QStringLiteral("%1").arg(CanIdModbus.ID_All, 8, 16, QLatin1Char('0')).toUpper()); + } + else + { + ui->ResultLine->setText(QStringLiteral("%1").arg(CanId.ID_All, 8, 16, QLatin1Char('0')).toUpper()); + } +} + +void CanIdCalc::on_StrAdrBox_valueChanged(int arg1) +{ + CanIdModbus.Fields.StrAdr = arg1; + id_Calc(); +} + +void CanIdCalc::on_routeBox_stateChanged(int arg1) +{ + switch (arg1) { + case Qt::Unchecked: + ui->routeBox->setText("Master"); + CanId.Fields.Route = 0; + CanIdModbus.Fields.Route = 0; + break; + case Qt::Checked: + ui->routeBox->setText("Slave"); + CanId.Fields.Route = 1; + CanIdModbus.Fields.Route = 1; + break; + } + id_Calc(); +} diff --git a/canidcalc.h b/canidcalc.h new file mode 100644 index 0000000..130b23d --- /dev/null +++ b/canidcalc.h @@ -0,0 +1,65 @@ +#ifndef CANIDCALC_H +#define CANIDCALC_H + +#include <QWidget> + +namespace Ui { +class CanIdCalc; +} + +class CanIdCalc : public QWidget +{ + Q_OBJECT + +public: + explicit CanIdCalc(QWidget *parent = nullptr); + ~CanIdCalc(); + +private slots: + + void on_DataTypeBox_currentIndexChanged(int index); + + void on_SensorTypeBox_currentIndexChanged(int index); + + void on_SensorIdBox_valueChanged(int arg1); + + void on_DeviceIdBox_valueChanged(int arg1); + + void on_StrAdrBox_valueChanged(int arg1); + + void on_routeBox_stateChanged(int arg1); + +private: + void id_Calc(); + + bool isModbus = false; + union Can_ID{ + struct Can_ID_Fields + { + uint Device:8; + uint SensorID:11; + uint SensorType:5; + uint DataType:4; + uint Route:1; + + }Fields; + uint ID_All:29; + }CanId; + + union Can_ID_Modbus{ + struct Can_ID_Fields + { + uint Device:8; + uint CountReg:8; + uint StrAdr:8; + uint DataType:4; + uint Route:1; + }Fields; + uint ID_All:29; + }CanIdModbus; + + + Ui::CanIdCalc *ui; +}; + +#endif // CANIDCALC_H diff --git a/canidcalc.ui b/canidcalc.ui new file mode 100644 index 0000000..d7ca270 --- /dev/null +++ b/canidcalc.ui @@ -0,0 +1,323 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CanIdCalc</class> + <widget class="QWidget" name="CanIdCalc"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>994</width> + <height>67</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="6"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="7"> + <widget class="QSpinBox" name="SensorIdBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="maximum"> + <number>2047</number> + </property> + </widget> + </item> + <item row="0" column="5"> + <widget class="QLabel" name="StrAdrLabel"> + <property name="text"> + <string>Стартовый адрес</string> + </property> + </widget> + </item> + <item row="0" column="11"> + <widget class="QLabel" name="ResultLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Result</string> + </property> + </widget> + </item> + <item row="0" column="7"> + <widget class="QLabel" name="SensorIdLabel"> + <property name="text"> + <string>Sensor ID</string> + </property> + </widget> + </item> + <item row="1" column="11"> + <widget class="QLineEdit" name="ResultLine"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>60</width> + <height>16777215</height> + </size> + </property> + <property name="maxLength"> + <number>8</number> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QLabel" name="SensorTypeLabel"> + <property name="text"> + <string>Sensor Type</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="routeBox"> + <property name="text"> + <string>Master</string> + </property> + </widget> + </item> + <item row="1" column="9"> + <widget class="QSpinBox" name="DeviceIdBox"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="maximum"> + <number>255</number> + </property> + </widget> + </item> + <item row="0" column="9"> + <widget class="QLabel" name="DeviceIdLabel"> + <property name="text"> + <string>Device ID</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QComboBox" name="DataTypeBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <item> + <property name="text"> + <string>Широковещательные</string> + </property> + </item> + <item> + <property name="text"> + <string>Дискретные</string> + </property> + </item> + <item> + <property name="text"> + <string>Аналог</string> + </property> + </item> + <item> + <property name="text"> + <string>Modbus Coil</string> + </property> + </item> + <item> + <property name="text"> + <string>Modbus Discrete</string> + </property> + </item> + <item> + <property name="text"> + <string>Modbus Holding</string> + </property> + </item> + <item> + <property name="text"> + <string>Modbus Input</string> + </property> + </item> + <item> + <property name="text"> + <string>Пульс</string> + </property> + </item> + </widget> + </item> + <item row="1" column="10"> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="4"> + <widget class="QComboBox" name="SensorTypeBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="editable"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="DataTypeLabel"> + <property name="text"> + <string>Data Type</string> + </property> + </widget> + </item> + <item row="1" column="8"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="5"> + <widget class="QSpinBox" name="StrAdrBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="maximum"> + <number>255</number> + </property> + </widget> + </item> + <item row="1" column="3"> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Route</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/canusb.cpp b/canusb.cpp new file mode 100644 index 0000000..a679e75 --- /dev/null +++ b/canusb.cpp @@ -0,0 +1,153 @@ +#include "canusb.h" +#include "ui_canusb.h" +#include <QFileDialog> +#include <QLineEdit> +#include <QDebug> +#include <QTime> +#include "ui_send_cmd.h" +#include "ProjectSettings.h" + +CanUsb *target; + +CB_FLAGS cb_flags; +CanUsb::CanUsb(QWidget *parent) + : QWidget(parent) + , ui(new Ui::CanUsb) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose); + init(); +} + +CanUsb::~CanUsb() +{ + delete ui; +} + +void CanUsb::init() +{ + target=this; + Refresh(); + ui->dataBitsBox->setEditText("1CE0E1"); +} + +unsigned CanUsb::div_up(unsigned x, unsigned y) +{ + return (x - 1) / y + 1; +} + +void CanUsb::Refresh() +{ + ui->serialPortInfoListBox->setDisabled(TRUE); + int count = SlCan_GetDeviceCount(); + QString currPort = ui->serialPortInfoListBox->currentText(); + ui->serialPortInfoListBox->clear(); + for (int i = 0; i < count; ++i) + { + HSLCAN device = SlCan_GetDevice(i); + char* buff = new char[30]; + SlCan_DeviceGetProperty(device, 0x0000000D, buff, 30); + QString str(buff); + ui->serialPortInfoListBox->addItem(str); + delete[] buff; + } + ui->serialPortInfoListBox->setCurrentText(currPort); + ui->serialPortInfoListBox->setDisabled(FALSE); +} + +static QString DeviceGetPropety(HSLCAN hDevice, DWORD dwIndex) +{ + char pBuf[256]; + SlCan_DeviceGetProperty(hDevice, dwIndex, pBuf, 256); + return QString(pBuf); +} +void CanUsb::on_serialPortInfoListBox_currentIndexChanged(int index) +{ + device = SlCan_GetDevice(ui->serialPortInfoListBox->currentIndex()); + ui->descriptionLabel->setText(tr("Description: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_DEVICEDESC))); + ui->descriptionLabel->setToolTip(QString("Description: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_DEVICEDESC))); + + ui->manufacturerLabel->setText(tr("Manufacturer: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_MFG))); + ui->manufacturerLabel->setToolTip((QString("Manufacturer: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_MFG)))); + + ui->serialNumberLabel->setText(tr("Serial number: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_SERIAL))); + ui->serialNumberLabel->setToolTip(QString("Serial number: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_SERIAL))); + + ui->locationLabel->setText(tr("Location: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_PORTNAME))); + ui->locationLabel->setToolTip(QString("Location: %1").arg(DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_PORTNAME))); + + QString VBuf = DeviceGetPropety(device, SLCAN_PROPERTY_INDEX_INSTANCEID); + QString VID; + QString PID; + bool FirstFlag = FALSE; + bool SecondFlag = FALSE; + for(int i = 0; i < VBuf.size(); i++) + { + if(VBuf[i]=='_') + { + FirstFlag=TRUE; + i++; + } + if(FirstFlag) + { + if(VBuf[i]=='&') + { + FirstFlag=FALSE; + SecondFlag=TRUE; + } + else if(SecondFlag!=TRUE) + { + VID+=VBuf[i]; + } + else + { + if(VBuf[i]==0x5C) + { + break; + } + else + { + PID+=VBuf[i]; + } + } + } + } + ui->vidLabel->setText(tr("Vendor Identifier: %1").arg(VID.toLower())); + ui->vidLabel->setToolTip(QString("Vendor Identifier: %1").arg(VID.toLower())); + + ui->pidLabel->setText(tr("Product Identifier: %1").arg(PID.toLower())); + ui->pidLabel->setToolTip(QString("Product Identifier: %1").arg(PID.toLower())); +} + +int CanUsb::GetID() +{ + return ui->dataBitsBox->currentText().toInt(nullptr, 16); +} +int CanUsb::GetBR() +{ + return ui->baudRateBox->currentIndex(); +} +HSLCAN CanUsb::G_Device() +{ + return device; +} +int CanUsb::GetMode() +{ + return ui->modeBox->currentIndex()+1; +} +void CanUsb::AfterConnection() +{ + ui->parametersBox->setEnabled(FALSE); + ui->selectBox->setEnabled(FALSE); +} + +void CanUsb::AfterDisconnection() +{ + ui->parametersBox->setEnabled(TRUE); + ui->selectBox->setEnabled(TRUE); +} + +int CanUsb::GetCount() +{ + return ui->serialPortInfoListBox->count(); +} diff --git a/canusb.h b/canusb.h new file mode 100644 index 0000000..3641be8 --- /dev/null +++ b/canusb.h @@ -0,0 +1,67 @@ +#ifndef USBCAN_H +#define USBCAN_H + +#include <QWidget> +#include <slcan.h> +#include "ProjectSettings.h" +class Send_CMD; + +static void __stdcall Device_Callback(HSLCAN cbDevice, DWORD dwIndex, DWORD dwOperation, PVOID pContext, DWORD dwContextSize); +static void __stdcall DeviceList_Callback(HSLCAN cbDevice, DWORD dwIndex, PVOID pContext, DWORD dwContextSize); + +QT_BEGIN_NAMESPACE +namespace Ui { class CanUsb; } +QT_END_NAMESPACE + +struct CB_FLAGS{ + unsigned AvailableDevicesListHasBeenChanged:1; +}; + +class CanUsb : public QWidget +{ + Q_OBJECT + + +private: + + DWORD ID; //идентификатор устройства + SLCAN_MESSAGE outMsg; //буфер для отправки сообщения + SLCAN_MESSAGE inputMsg[FRAMES]; //буфер для приёма сообщения + HSLCAN device; + SLCAN_BITRATE br; + DWORD cntrInput; + unsigned int Counter_of_suc_transmit=0; + unsigned int TX_error_counter=0; + unsigned div_up(unsigned x, unsigned y); + + Send_CMD* send_cmd = nullptr; + SLCAN_STATE DeviceState; + + int timerRefreshID = 0; + + + +public: + + int GetCount(); + void AfterDisconnection(); + void AfterConnection(); + int GetMode(); + int GetID(); + int GetBR(); + void device_connect(); + HSLCAN G_Device(); + HSLCAN GetDevice(){return device;} + CanUsb(QWidget *parent = nullptr); + ~CanUsb(); + void init(); + void Refresh(); + +private slots: + + void on_serialPortInfoListBox_currentIndexChanged(int index); + +private: + Ui::CanUsb *ui; +}; +#endif // USBCAN_H diff --git a/canusb.ui b/canusb.ui new file mode 100644 index 0000000..293dc78 --- /dev/null +++ b/canusb.ui @@ -0,0 +1,258 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CanUsb</class> + <widget class="QWidget" name="CanUsb"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>200</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>200</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>400</width> + <height>200</height> + </size> + </property> + <property name="windowTitle"> + <string>CanUsb</string> + </property> + <property name="animated" stdset="0"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="1"> + <layout class="QVBoxLayout" name="SelectParameters"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <widget class="QGroupBox" name="parametersBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Select Parameters</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="1" column="0"> + <widget class="QLabel" name="dataBitsLabel"> + <property name="text"> + <string>ID</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="dataBitsBox"> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="baudRateLabel"> + <property name="text"> + <string>BaudRate:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="baudRateBox"> + <property name="currentIndex"> + <number>3</number> + </property> + <item> + <property name="text"> + <string>1000K</string> + </property> + </item> + <item> + <property name="text"> + <string>800K</string> + </property> + </item> + <item> + <property name="text"> + <string>500K</string> + </property> + </item> + <item> + <property name="text"> + <string>250K</string> + </property> + </item> + <item> + <property name="text"> + <string>125K</string> + </property> + </item> + <item> + <property name="text"> + <string>50K</string> + </property> + </item> + <item> + <property name="text"> + <string>20K</string> + </property> + </item> + <item> + <property name="text"> + <string>10K</string> + </property> + </item> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="modeLabel"> + <property name="text"> + <string>Mode</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="modeBox"> + <item> + <property name="text"> + <string>Normal</string> + </property> + </item> + <item> + <property name="text"> + <string>Listen Only</string> + </property> + </item> + <item> + <property name="text"> + <string>Loop Back</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item row="0" column="0"> + <widget class="QGroupBox" name="selectBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="title"> + <string>Select Serial Port</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QComboBox" name="serialPortInfoListBox"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="descriptionLabel"> + <property name="text"> + <string>Description:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="manufacturerLabel"> + <property name="text"> + <string>Manufacturer:</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="serialNumberLabel"> + <property name="text"> + <string>Serial number:</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="locationLabel"> + <property name="text"> + <string>Location:</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="vidLabel"> + <property name="text"> + <string>Vendor ID:</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="pidLabel"> + <property name="text"> + <string>Product ID:</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + <action name="action"> + <property name="text"> + <string>Main menu</string> + </property> + </action> + <action name="actionBluetooth"> + <property name="text"> + <string>Bluetooth</string> + </property> + </action> + <action name="actionMain_menu"> + <property name="text"> + <string>Main menu</string> + </property> + </action> + </widget> + <resources/> + <connections/> +</ui> diff --git a/crc16.cpp b/crc16.cpp new file mode 100644 index 0000000..2df2ddb --- /dev/null +++ b/crc16.cpp @@ -0,0 +1,134 @@ +#include "crc16.h" +#include "ui_crc16.h" + +CRC16::CRC16(QWidget *parent) : + QWidget(parent), + ui(new Ui::CRC16) +{ + ui->setupUi(this); + arr[0] = ui->lineByte_0; + arr[1] = ui->lineByte_1; + arr[2] = ui->lineByte_2; + arr[3] = ui->lineByte_3; + arr[4] = ui->lineByte_4; + arr[5] = ui->lineByte_5; + arr[6] = ui->lineByte_6; + arr[7] = ui->lineByte_7; +} + +CRC16::~CRC16() +{ + delete ui; +} + +static uint16_t getCRC_MODBUS(QByteArray buf, uint16_t len) +{ + static const uint16_t table[256] = { + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 }; + uint8_t x_or = 0; + uint16_t crc = 0xFFFF; + int i = 0; + while( len-- ) + { + x_or = (buf.at(i++)) ^ crc; + crc >>= 8; + crc ^= table[x_or]; + } + return crc; +} + +uint16_t getCRC_ARC(QByteArray data, uint16_t size) +{ + uint16_t out = 0; + int bits_read = 0, bit_flag; + if(data.size() == NULL) + return 0; + int data_i = 0; + while(size > 0) + { + bit_flag = out >> 15; + out <<= 1; + out |= (data.at(data_i) >> bits_read) & 1; + bits_read++; + if(bits_read > 7) + { + bits_read = 0; + data.at(data_i++); + size--; + } + if(bit_flag) + out ^= 0x8005; + } + int i; + for (i = 0; i < 16; ++i) { + bit_flag = out >> 15; + out <<= 1; + if(bit_flag) + out ^= 0x8005; + } + uint16_t crc = 0; + i = 0x8000; + int j = 0x0001; + for (; i != 0; i >>=1, j <<= 1) { + if (i & out) crc |= j; + } + return crc; +} + +void CRC16::on_buttonShowCRC_clicked() +{ + QByteArray crc; + for(int i = 0; i < ui->comboCountDLC->currentIndex()+1; i++) + { + crc += (BYTE)arr[i]->text().toInt(nullptr, 16); + } + ui->lineX25->setText("0x"+QString::number(qChecksum(crc, crc.size()), 16).toUpper()); + ui->lineModbus->setText("0x"+QString::number(getCRC_MODBUS(crc, ui->comboCountDLC->currentIndex()+1), 16).toUpper()); + ui->lineARC->setText("0x"+QString::number(getCRC_ARC(crc, crc.size()), 16).toUpper()); +} + +void CRC16::on_comboCountDLC_currentIndexChanged(int index) +{ + for(int i = 0; i < 8; i++) + { + if(i > (index)) + { + arr[i]->setEnabled(FALSE); + } + else + { + arr[i]->setEnabled(TRUE); + } + } +} diff --git a/crc16.h b/crc16.h new file mode 100644 index 0000000..dda68a6 --- /dev/null +++ b/crc16.h @@ -0,0 +1,30 @@ +#ifndef CRC16_H +#define CRC16_H + +#include <QWidget> +#include "ProjectSettings.h" + +namespace Ui { +class CRC16; +} + +class CRC16 : public QWidget +{ + Q_OBJECT + +public: + explicit CRC16(QWidget *parent = nullptr); + ~CRC16(); + +private slots: + + void on_buttonShowCRC_clicked(); + + void on_comboCountDLC_currentIndexChanged(int index); + +private: + QLineEdit *arr [8]; + Ui::CRC16 *ui; +}; + +#endif // CRC16_H diff --git a/crc16.ui b/crc16.ui new file mode 100644 index 0000000..332d026 --- /dev/null +++ b/crc16.ui @@ -0,0 +1,549 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CRC16</class> + <widget class="QWidget" name="CRC16"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>90</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>90</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>400</width> + <height>90</height> + </size> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <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> + <property name="spacing"> + <number>3</number> + </property> + <item row="1" column="0"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>Count</string> + </property> + <property name="alignment"> + <set>Qt::AlignHCenter|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>3</string> + </property> + <property name="alignment"> + <set>Qt::AlignHCenter|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="1" column="6"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>6</string> + </property> + <property name="alignment"> + <set>Qt::AlignHCenter|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>2</string> + </property> + <property name="alignment"> + <set>Qt::AlignHCenter|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLineEdit" name="lineByte_2"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineByte_0"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="text"> + <string/> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="1" column="7"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>7</string> + </property> + <property name="alignment"> + <set>Qt::AlignHCenter|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="0" column="8"> + <widget class="QLineEdit" name="lineByte_7"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="10"> + <widget class="QPushButton" name="buttonShowCRC"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Рассчитать</string> + </property> + </widget> + </item> + <item row="0" column="5"> + <widget class="QLineEdit" name="lineByte_4"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="6"> + <widget class="QLineEdit" name="lineByte_5"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="7"> + <widget class="QLineEdit" name="lineByte_6"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLineEdit" name="lineByte_1"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="1" column="8"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>8</string> + </property> + <property name="alignment"> + <set>Qt::AlignHCenter|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>1</string> + </property> + <property name="alignment"> + <set>Qt::AlignHCenter|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>4</string> + </property> + <property name="alignment"> + <set>Qt::AlignHCenter|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QLineEdit" name="lineByte_3"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="1" column="5"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>5</string> + </property> + <property name="alignment"> + <set>Qt::AlignHCenter|Qt::AlignTop</set> + </property> + </widget> + </item> + <item row="2" column="1" colspan="10"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="2"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>Modbus:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QLabel" name="label_12"> + <property name="text"> + <string>ARC:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineX25"> + <property name="minimumSize"> + <size> + <width>50</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>50</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>9Ahhhh</string> + </property> + <property name="maxLength"> + <number>6</number> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLineEdit" name="lineModbus"> + <property name="minimumSize"> + <size> + <width>50</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>50</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>6</number> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>CCITT (X-25):</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="5"> + <widget class="QLineEdit" name="lineARC"> + <property name="minimumSize"> + <size> + <width>50</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>50</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>6</number> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="0"> + <widget class="QComboBox" name="comboCountDLC"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>7</number> + </property> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/macrossetting.cpp b/macrossetting.cpp new file mode 100644 index 0000000..5160a18 --- /dev/null +++ b/macrossetting.cpp @@ -0,0 +1,453 @@ +#include "macrossetting.h" +#include "ui_macrossetting.h" + +MacrosSetting::MacrosSetting(QWidget *parent) : + QDialog(parent), + ui(new Ui::MacrosSetting) +{ + ui->setupUi(this); + Init(); +} + +MacrosSetting::~MacrosSetting() +{ + delete ui; +} + +void MacrosSetting::Init() +{ + //EID + { + MacrosSettingKit[0].EID = ui->checkEID_01; + MacrosSettingKit[1].EID = ui->checkEID_02; + MacrosSettingKit[2].EID = ui->checkEID_03; + MacrosSettingKit[3].EID = ui->checkEID_04; + MacrosSettingKit[4].EID = ui->checkEID_05; + MacrosSettingKit[5].EID = ui->checkEID_06; + MacrosSettingKit[6].EID = ui->checkEID_07; + MacrosSettingKit[7].EID = ui->checkEID_08; + MacrosSettingKit[8].EID = ui->checkEID_09; + MacrosSettingKit[9].EID = ui->checkEID_10; + MacrosSettingKit[10].EID = ui->checkEID_11; + MacrosSettingKit[11].EID = ui->checkEID_12; + MacrosSettingKit[12].EID = ui->checkEID_13; + MacrosSettingKit[13].EID = ui->checkEID_14; + MacrosSettingKit[14].EID = ui->checkEID_15; + } + //ID + { + MacrosSettingKit[0].ID = ui->lineID_01; + MacrosSettingKit[1].ID = ui->lineID_02; + MacrosSettingKit[2].ID = ui->lineID_03; + MacrosSettingKit[3].ID = ui->lineID_04; + MacrosSettingKit[4].ID = ui->lineID_05; + MacrosSettingKit[5].ID = ui->lineID_06; + MacrosSettingKit[6].ID = ui->lineID_07; + MacrosSettingKit[7].ID = ui->lineID_08; + MacrosSettingKit[8].ID = ui->lineID_09; + MacrosSettingKit[9].ID = ui->lineID_10; + MacrosSettingKit[10].ID = ui->lineID_11; + MacrosSettingKit[11].ID = ui->lineID_12; + MacrosSettingKit[12].ID = ui->lineID_13; + MacrosSettingKit[13].ID = ui->lineID_14; + MacrosSettingKit[14].ID = ui->lineID_15; + } + //IsHEX + { + MacrosSettingKit[0].IsHEX = ui->checkHEX_01; + MacrosSettingKit[1].IsHEX = ui->checkHEX_02; + MacrosSettingKit[2].IsHEX = ui->checkHEX_03; + MacrosSettingKit[3].IsHEX = ui->checkHEX_04; + MacrosSettingKit[4].IsHEX = ui->checkHEX_05; + MacrosSettingKit[5].IsHEX = ui->checkHEX_06; + MacrosSettingKit[6].IsHEX = ui->checkHEX_07; + MacrosSettingKit[7].IsHEX = ui->checkHEX_08; + MacrosSettingKit[8].IsHEX = ui->checkHEX_09; + MacrosSettingKit[9].IsHEX = ui->checkHEX_10; + MacrosSettingKit[10].IsHEX = ui->checkHEX_11; + MacrosSettingKit[11].IsHEX = ui->checkHEX_12; + MacrosSettingKit[12].IsHEX = ui->checkHEX_13; + MacrosSettingKit[13].IsHEX = ui->checkHEX_14; + MacrosSettingKit[14].IsHEX = ui->checkHEX_15; + } + //Name + { + MacrosSettingKit[0].Name = ui->lineMcrsName_01; + MacrosSettingKit[1].Name = ui->lineMcrsName_02; + MacrosSettingKit[2].Name = ui->lineMcrsName_03; + MacrosSettingKit[3].Name = ui->lineMcrsName_04; + MacrosSettingKit[4].Name = ui->lineMcrsName_05; + MacrosSettingKit[5].Name = ui->lineMcrsName_06; + MacrosSettingKit[6].Name = ui->lineMcrsName_07; + MacrosSettingKit[7].Name = ui->lineMcrsName_08; + MacrosSettingKit[8].Name = ui->lineMcrsName_09; + MacrosSettingKit[9].Name = ui->lineMcrsName_10; + MacrosSettingKit[10].Name = ui->lineMcrsName_11; + MacrosSettingKit[11].Name = ui->lineMcrsName_12; + MacrosSettingKit[12].Name = ui->lineMcrsName_13; + MacrosSettingKit[13].Name = ui->lineMcrsName_14; + MacrosSettingKit[14].Name = ui->lineMcrsName_15; + } + //Mcrs + { + MacrosSettingKit[0].Mcrs = ui->lineMcrs_01; + MacrosSettingKit[1].Mcrs = ui->lineMcrs_02; + MacrosSettingKit[2].Mcrs = ui->lineMcrs_03; + MacrosSettingKit[3].Mcrs = ui->lineMcrs_04; + MacrosSettingKit[4].Mcrs = ui->lineMcrs_05; + MacrosSettingKit[5].Mcrs = ui->lineMcrs_06; + MacrosSettingKit[6].Mcrs = ui->lineMcrs_07; + MacrosSettingKit[7].Mcrs = ui->lineMcrs_08; + MacrosSettingKit[8].Mcrs = ui->lineMcrs_09; + MacrosSettingKit[9].Mcrs = ui->lineMcrs_10; + MacrosSettingKit[10].Mcrs = ui->lineMcrs_11; + MacrosSettingKit[11].Mcrs = ui->lineMcrs_12; + MacrosSettingKit[12].Mcrs = ui->lineMcrs_13; + MacrosSettingKit[13].Mcrs = ui->lineMcrs_14; + MacrosSettingKit[14].Mcrs = ui->lineMcrs_15; + } + //Count + { + MacrosSettingKit[0].Count = ui->spinCount_01; + MacrosSettingKit[1].Count = ui->spinCount_02; + MacrosSettingKit[2].Count = ui->spinCount_03; + MacrosSettingKit[3].Count = ui->spinCount_04; + MacrosSettingKit[4].Count = ui->spinCount_05; + MacrosSettingKit[5].Count = ui->spinCount_06; + MacrosSettingKit[6].Count = ui->spinCount_07; + MacrosSettingKit[7].Count = ui->spinCount_08; + MacrosSettingKit[8].Count = ui->spinCount_09; + MacrosSettingKit[9].Count = ui->spinCount_10; + MacrosSettingKit[10].Count = ui->spinCount_11; + MacrosSettingKit[11].Count = ui->spinCount_12; + MacrosSettingKit[12].Count = ui->spinCount_13; + MacrosSettingKit[13].Count = ui->spinCount_14; + MacrosSettingKit[14].Count = ui->spinCount_15; + } + //IsPeriod + { + MacrosSettingKit[0].IsPeriod = ui->checkPeriod_01; + MacrosSettingKit[1].IsPeriod = ui->checkPeriod_02; + MacrosSettingKit[2].IsPeriod = ui->checkPeriod_03; + MacrosSettingKit[3].IsPeriod = ui->checkPeriod_04; + MacrosSettingKit[4].IsPeriod = ui->checkPeriod_05; + MacrosSettingKit[5].IsPeriod = ui->checkPeriod_06; + MacrosSettingKit[6].IsPeriod = ui->checkPeriod_07; + MacrosSettingKit[7].IsPeriod = ui->checkPeriod_08; + MacrosSettingKit[8].IsPeriod = ui->checkPeriod_09; + MacrosSettingKit[9].IsPeriod = ui->checkPeriod_10; + MacrosSettingKit[10].IsPeriod = ui->checkPeriod_11; + MacrosSettingKit[11].IsPeriod = ui->checkPeriod_12; + MacrosSettingKit[12].IsPeriod = ui->checkPeriod_13; + MacrosSettingKit[13].IsPeriod = ui->checkPeriod_14; + MacrosSettingKit[14].IsPeriod = ui->checkPeriod_15; + } + //Period + { + MacrosSettingKit[0].Period = ui->spinPeriod_01; + MacrosSettingKit[1].Period = ui->spinPeriod_02; + MacrosSettingKit[2].Period = ui->spinPeriod_03; + MacrosSettingKit[3].Period = ui->spinPeriod_04; + MacrosSettingKit[4].Period = ui->spinPeriod_05; + MacrosSettingKit[5].Period = ui->spinPeriod_06; + MacrosSettingKit[6].Period = ui->spinPeriod_07; + MacrosSettingKit[7].Period = ui->spinPeriod_08; + MacrosSettingKit[8].Period = ui->spinPeriod_09; + MacrosSettingKit[9].Period = ui->spinPeriod_10; + MacrosSettingKit[10].Period = ui->spinPeriod_11; + MacrosSettingKit[11].Period = ui->spinPeriod_12; + MacrosSettingKit[12].Period = ui->spinPeriod_13; + MacrosSettingKit[13].Period = ui->spinPeriod_14; + MacrosSettingKit[14].Period = ui->spinPeriod_15; + } + //RTR + { + MacrosSettingKit[0].RTR = ui->checkRTR_01; + MacrosSettingKit[1].RTR = ui->checkRTR_02; + MacrosSettingKit[2].RTR = ui->checkRTR_03; + MacrosSettingKit[3].RTR = ui->checkRTR_04; + MacrosSettingKit[4].RTR = ui->checkRTR_05; + MacrosSettingKit[5].RTR = ui->checkRTR_06; + MacrosSettingKit[6].RTR = ui->checkRTR_07; + MacrosSettingKit[7].RTR = ui->checkRTR_08; + MacrosSettingKit[8].RTR = ui->checkRTR_09; + MacrosSettingKit[9].RTR = ui->checkRTR_10; + MacrosSettingKit[10].RTR = ui->checkRTR_11; + MacrosSettingKit[11].RTR = ui->checkRTR_12; + MacrosSettingKit[12].RTR = ui->checkRTR_13; + MacrosSettingKit[13].RTR = ui->checkRTR_14; + MacrosSettingKit[14].RTR = ui->checkRTR_15; + } + //DLC + { + MacrosSettingKit[0].DLC = ui->comboDLC_01; + MacrosSettingKit[1].DLC = ui->comboDLC_02; + MacrosSettingKit[2].DLC = ui->comboDLC_03; + MacrosSettingKit[3].DLC = ui->comboDLC_04; + MacrosSettingKit[4].DLC = ui->comboDLC_05; + MacrosSettingKit[5].DLC = ui->comboDLC_06; + MacrosSettingKit[6].DLC = ui->comboDLC_07; + MacrosSettingKit[7].DLC = ui->comboDLC_08; + MacrosSettingKit[8].DLC = ui->comboDLC_09; + MacrosSettingKit[9].DLC = ui->comboDLC_10; + MacrosSettingKit[10].DLC = ui->comboDLC_11; + MacrosSettingKit[11].DLC = ui->comboDLC_12; + MacrosSettingKit[12].DLC = ui->comboDLC_13; + MacrosSettingKit[13].DLC = ui->comboDLC_14; + MacrosSettingKit[14].DLC = ui->comboDLC_15; + } + for(int i = 0; i < 15; i++) + { + MacrosSettingKit[i].Period->setEnabled(false); + MacrosSettingKit[i].DLC->setEnabled(false); + EnterErrors.ID[i] = EnterErrors.Mcrs[i] = 0; + } +} + +void MacrosSetting::GetMcrs() +{ +// for (int i = 0; i < 15; i++) +// { +// MacrosKit[i].IsHEX = MacrosSettingKit[i].IsHEX->checkState(); +// MacrosKit[i].Name = MacrosSettingKit[i].Name->text(); +// MacrosKit[i].Mcrs = MacrosSettingKit[i].Mcrs->text(); +// } +// IsOK = TRUE; +} + +void MacrosSetting::SetStart(Qt::CheckState *ptrEID, DWORD *ptrID, Qt::CheckState *ptrRTR, + Qt::CheckState *ptrHEX, int *ptrDLC, QString *ptrName, QString *ptrMcrs, + int *ptrCount, Qt::CheckState *ptrIsPeriod, int *ptrPeriod) +{ + McrsReturn.EID = ptrEID; + McrsReturn.ID = ptrID; + McrsReturn.RTR = ptrRTR; + McrsReturn.IsHEX = ptrHEX; + McrsReturn.DLC = ptrDLC; + McrsReturn.Name = ptrName; + McrsReturn.Mcrs = ptrMcrs; + McrsReturn.Count = ptrCount; + McrsReturn.IsPeriod = ptrIsPeriod; + McrsReturn.Period = ptrPeriod; + for(int i = 0; i < 15; i++) + { + MacrosSettingKit[i].EID->setCheckState(ptrEID[i]); + if(ptrEID[i]==Qt::Checked) + { + MacrosSettingKit[i].ID->setText(QStringLiteral("%1").arg(ptrID[i], 8, 16, QLatin1Char('0')).toUpper()); + } + else + { + MacrosSettingKit[i].ID->setText(QStringLiteral("%1").arg(ptrID[i], 3, 16, QLatin1Char('0')).toUpper()); + } + + MacrosSettingKit[i].RTR->setCheckState(ptrRTR[i]); + MacrosSettingKit[i].IsHEX->setCheckState(ptrHEX[i]); + MacrosSettingKit[i].DLC->setCurrentIndex(ptrDLC[i]); + comboDLC_stateChanged(i+1); + MacrosSettingKit[i].Name->setText(ptrName[i]); + MacrosSettingKit[i].Mcrs->setText(ptrMcrs[i]); + MacrosSettingKit[i].Count->setValue(ptrCount[i]); + MacrosSettingKit[i].IsPeriod->setCheckState(ptrIsPeriod[i]); + MacrosSettingKit[i].Period->setValue(ptrPeriod[i]); + } +} + +void MacrosSetting::on_buttonBox_accepted() +{ + for (int i = 0; i < 15; i++) + { + McrsReturn.EID[i] = MacrosSettingKit[i].EID->checkState(); + McrsReturn.ID[i] = MacrosSettingKit[i].ID->text().toInt(nullptr, 16); + McrsReturn.RTR[i] = MacrosSettingKit[i].RTR->checkState(); + McrsReturn.IsHEX[i] = MacrosSettingKit[i].IsHEX->checkState(); + McrsReturn.DLC[i] = MacrosSettingKit[i].DLC->currentIndex(); + McrsReturn.Name[i] = MacrosSettingKit[i].Name->text(); +// if (!ValidationMcrs(i+1)) +// { +// QDialog *McrsError = new QDialog; +// McrsError->setWindowTitle(QString("Ошибка заполнения")); +// McrsError->setMinimumSize(260, 70); +// McrsError->setMaximumSize(260, 70); +// QVBoxLayout *layoutCTX = new QVBoxLayout(McrsError); +// McrsError->setLayout(layoutCTX); +// QLabel *ErrorMSG = new QLabel; +// ErrorMSG->setText(QString("Некорректное значение поля макроса %1.").arg(MacrosSettingKit[i].Name->text())); +// layoutCTX->addWidget(ErrorMSG); +// QDialogButtonBox *yesOrNo = new QDialogButtonBox(McrsError); +// yesOrNo->addButton("Продолжить без HEX", QDialogButtonBox::AcceptRole); +// yesOrNo->addButton("Очистить макрос", QDialogButtonBox::RejectRole); +// layoutCTX->addWidget(yesOrNo); +// connect(yesOrNo, &QDialogButtonBox::accepted, McrsError, &QDialog::accept); +// connect(yesOrNo, &QDialogButtonBox::rejected, McrsError, &QDialog::reject); +// McrsError->exec(); +// if(McrsError->result()==QDialog::Accepted) +// { +// MacrosSettingKit[i].IsHEX->setCheckState(Qt::Unchecked); +// McrsReturn.IsHEX[i] = Qt::Unchecked; +// McrsReturn.Mcrs[i] = MacrosSettingKit[i].Mcrs->text(); +// } +// else +// { +// MacrosSettingKit[i].Mcrs->clear(); +// McrsReturn.Mcrs[i] = MacrosSettingKit[i].Mcrs->text(); +// } +// } +// else +// { +// +// } + McrsReturn.Mcrs[i] = MacrosSettingKit[i].Mcrs->text(); + McrsReturn.Count[i] = MacrosSettingKit[i].Count->value(); + McrsReturn.IsPeriod[i] = MacrosSettingKit[i].IsPeriod->checkState(); + McrsReturn.Period[i] = MacrosSettingKit[i].Period->value(); + } + IsOK = TRUE; +} + +void MacrosSetting::on_buttonBox_rejected() +{ + IsOK = FALSE; +} + +void MacrosSetting::checkPeriod_stateChanged(int index, int arg1) +{ + index--; + MacrosSettingKit[index].Period->setEnabled(arg1); +} + +void MacrosSetting::ValidationID(unsigned int numID) +{ + numID--; + QString buffer = QString::number(MacrosSettingKit[numID].ID->text().toUInt(nullptr, 16), 10); + int pos = 0; + unsigned long long maxRange; + if(MacrosSettingKit[numID].EID->checkState()==Qt::Checked) + { + maxRange = 0x1FFFFFFF; + } + else + { + maxRange = 0x7FF; + } + if((unsigned long long)buffer.toUInt(nullptr, 10) > (unsigned long long) maxRange) + { + MacrosSettingKit[numID].ID->setStyleSheet("border: 1px solid red"); + MacrosSettingKit[numID].ID->setToolTip(QString("Valid ID: 0 - 0x%1").arg(QString::number(maxRange, 16).toUpper())); + EnterErrors.ID[numID] = true; + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + } + else + { + MacrosSettingKit[numID].ID->setStyleSheet(""); + MacrosSettingKit[numID].ID->setToolTip(QString()); + EnterErrors.ID[numID] = false; + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(checkErrors()); + } +} + +bool MacrosSetting::ValidationMcrs(unsigned int numID) +{ + numID--; + if(MacrosSettingKit[numID].IsHEX->checkState()==Qt::Checked) + { + QString buffer = MacrosSettingKit[numID].Mcrs->text(); + for(int i = 0; i < buffer.size(); i++) + { + if(buffer.at(i) < '0' || (buffer.at(i) > '9' && buffer.at(i) < 'A') || (buffer.at(i) > 'F' && buffer.at(i) < 'a') || buffer.at(i) > 'f') + { + MacrosSettingKit[numID].Mcrs->setStyleSheet("border: 1px solid red"); + MacrosSettingKit[numID].Mcrs->setToolTip(QString("Hexadecimal character required. A-F, 0-9.")); + EnterErrors.Mcrs[numID] = true; + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); + return false; + } + } + MacrosSettingKit[numID].Mcrs->setStyleSheet(""); + MacrosSettingKit[numID].Mcrs->setToolTip(QString()); + MacrosSettingKit[numID].Mcrs->setText(buffer.toUpper()); + } + EnterErrors.Mcrs[numID] = false; + ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(checkErrors()); + return true; +} + +void MacrosSetting::checkEID_stateChanged(int index) +{ + index--; + if(MacrosSettingKit[index].EID->checkState()==Qt::Checked) + { + MacrosSettingKit[index].ID->setInputMask(">HHHHHHHH"); + } + else + { + MacrosSettingKit[index].ID->setInputMask(">HHH"); + } +} + +void MacrosSetting::checkRTR_stateChanged(int index) +{ + index--; + if(MacrosSettingKit[index].RTR->checkState()==Qt::Checked) + { + MacrosSettingKit[index].IsHEX->setEnabled(false); + MacrosSettingKit[index].Mcrs->setEnabled(false); + MacrosSettingKit[index].DLC->setEnabled(true); + } + else + { + MacrosSettingKit[index].IsHEX->setEnabled(true); + MacrosSettingKit[index].Mcrs->setEnabled(true); + if(MacrosSettingKit[index].IsHEX->checkState()!=Qt::Checked) + { + MacrosSettingKit[index].DLC->setEnabled(false); + } + } +} + +void MacrosSetting::checkHEX_stateChanged(int index) +{ + index--; + if(MacrosSettingKit[index].IsHEX->checkState()==Qt::Checked) + { + MacrosSettingKit[index].DLC->setEnabled(true); + comboDLC_stateChanged(index+1); + ValidationMcrs(index+1); + //MacrosSettingKit[index].Mcrs->setInputMask(">"); + } + else + { + MacrosSettingKit[index].DLC->setEnabled(false); + MacrosSettingKit[index].Mcrs->setInputMask(""); + MacrosSettingKit[index].Mcrs->setMaxLength(32767); + //MacrosSettingKit[index].Mcrs->setInputMask(""); + } +} + +void MacrosSetting::comboDLC_stateChanged(int index) +{ + index--; + if(MacrosSettingKit[index].IsHEX->checkState()==Qt::Checked) + { + int currentDLC = MacrosSettingKit[index].DLC->currentIndex(); + //QString buffer = ">"; +// for (int i = 1; i < currentDLC; i++) +// { +// buffer += "HH"; +// } + //MacrosSettingKit[index].Mcrs->setInputMask(buffer); + MacrosSettingKit[index].Mcrs->setMaxLength((MacrosSettingKit[index].DLC->currentIndex())*2); + } +} + +bool MacrosSetting::checkErrors() +{ + for(int i = 0; i < 15; i++) + { + if (EnterErrors.ID[i] || EnterErrors.Mcrs[i]) + { + return false; + } + } + return true; +} diff --git a/macrossetting.h b/macrossetting.h new file mode 100644 index 0000000..0bdcee6 --- /dev/null +++ b/macrossetting.h @@ -0,0 +1,211 @@ +#ifndef MACROSSETTING_H +#define MACROSSETTING_H + +#include <QDialog> +#include "unioncom.h" +#include "QLineEdit" +#include "QCheckBox" +#include "QSpinBox" +#include "QComboBox" + +namespace Ui { +class MacrosSetting; +} + +class MacrosSetting : public QDialog +{ + Q_OBJECT + +public: +// struct mcrs_stgs_kit{ +// Qt::CheckState IsHEX; +// QString Name; +// QString Mcrs; +// } MacrosWindow[15]; + struct MacrosSrting{ + QCheckBox *EID; + QLineEdit *ID; + QCheckBox *RTR; + QCheckBox *IsHEX; + QComboBox *DLC; + QLineEdit *Name; + QLineEdit *Mcrs; + QSpinBox *Count; + QCheckBox *IsPeriod; + QSpinBox *Period; + } MacrosSettingKit[15]; + struct mcrs_return{ + Qt::CheckState *EID; + DWORD *ID; + Qt::CheckState *RTR; + Qt::CheckState *IsHEX; + int *DLC; + QString *Name; + QString *Mcrs; + int *Count; + Qt::CheckState *IsPeriod; + int *Period; + } McrsReturn; + struct error_enter{ + bool ID[15]; + bool Mcrs[15]; + }EnterErrors; + + explicit MacrosSetting(QWidget *parent = nullptr); + ~MacrosSetting(); + + bool IsOK = false; + void SetStart(Qt::CheckState *ptrEID, DWORD *ptrID, Qt::CheckState *ptrRTR, Qt::CheckState *ptrHEX, int *ptrDLC, + QString *ptrName, QString *ptrMcrs, int *ptrCount, Qt::CheckState *ptrIsPeriod, int *ptrPeriod); + +private slots: + + + void on_buttonBox_accepted(); + + void on_buttonBox_rejected(); + + void on_checkPeriod_01_stateChanged(int arg1) {checkPeriod_stateChanged(1, arg1);}; + void on_checkPeriod_02_stateChanged(int arg1) {checkPeriod_stateChanged(2, arg1);}; + void on_checkPeriod_03_stateChanged(int arg1) {checkPeriod_stateChanged(3, arg1);}; + void on_checkPeriod_04_stateChanged(int arg1) {checkPeriod_stateChanged(4, arg1);}; + void on_checkPeriod_05_stateChanged(int arg1) {checkPeriod_stateChanged(5, arg1);}; + void on_checkPeriod_06_stateChanged(int arg1) {checkPeriod_stateChanged(6, arg1);}; + void on_checkPeriod_07_stateChanged(int arg1) {checkPeriod_stateChanged(7, arg1);}; + void on_checkPeriod_08_stateChanged(int arg1) {checkPeriod_stateChanged(8, arg1);}; + void on_checkPeriod_09_stateChanged(int arg1) {checkPeriod_stateChanged(9, arg1);}; + void on_checkPeriod_10_stateChanged(int arg1) {checkPeriod_stateChanged(10, arg1);}; + void on_checkPeriod_11_stateChanged(int arg1) {checkPeriod_stateChanged(11, arg1);}; + void on_checkPeriod_12_stateChanged(int arg1) {checkPeriod_stateChanged(12, arg1);}; + void on_checkPeriod_13_stateChanged(int arg1) {checkPeriod_stateChanged(13, arg1);}; + void on_checkPeriod_14_stateChanged(int arg1) {checkPeriod_stateChanged(14, arg1);}; + void on_checkPeriod_15_stateChanged(int arg1) {checkPeriod_stateChanged(15, arg1);}; + + void on_checkEID_01_stateChanged(int arg1) {checkEID_stateChanged(1);}; + void on_checkEID_02_stateChanged(int arg1) {checkEID_stateChanged(2);}; + void on_checkEID_03_stateChanged(int arg1) {checkEID_stateChanged(3);}; + void on_checkEID_04_stateChanged(int arg1) {checkEID_stateChanged(4);}; + void on_checkEID_05_stateChanged(int arg1) {checkEID_stateChanged(5);}; + void on_checkEID_06_stateChanged(int arg1) {checkEID_stateChanged(6);}; + void on_checkEID_07_stateChanged(int arg1) {checkEID_stateChanged(7);}; + void on_checkEID_08_stateChanged(int arg1) {checkEID_stateChanged(8);}; + void on_checkEID_09_stateChanged(int arg1) {checkEID_stateChanged(9);}; + void on_checkEID_10_stateChanged(int arg1) {checkEID_stateChanged(10);}; + void on_checkEID_11_stateChanged(int arg1) {checkEID_stateChanged(11);}; + void on_checkEID_12_stateChanged(int arg1) {checkEID_stateChanged(12);}; + void on_checkEID_13_stateChanged(int arg1) {checkEID_stateChanged(13);}; + void on_checkEID_14_stateChanged(int arg1) {checkEID_stateChanged(14);}; + void on_checkEID_15_stateChanged(int arg1) {checkEID_stateChanged(15);}; + + void on_checkRTR_01_stateChanged(int arg1) {checkRTR_stateChanged(1);}; + void on_checkRTR_02_stateChanged(int arg1) {checkRTR_stateChanged(2);}; + void on_checkRTR_03_stateChanged(int arg1) {checkRTR_stateChanged(3);}; + void on_checkRTR_04_stateChanged(int arg1) {checkRTR_stateChanged(4);}; + void on_checkRTR_05_stateChanged(int arg1) {checkRTR_stateChanged(5);}; + void on_checkRTR_06_stateChanged(int arg1) {checkRTR_stateChanged(6);}; + void on_checkRTR_07_stateChanged(int arg1) {checkRTR_stateChanged(7);}; + void on_checkRTR_08_stateChanged(int arg1) {checkRTR_stateChanged(8);}; + void on_checkRTR_09_stateChanged(int arg1) {checkRTR_stateChanged(9);}; + void on_checkRTR_10_stateChanged(int arg1) {checkRTR_stateChanged(10);}; + void on_checkRTR_11_stateChanged(int arg1) {checkRTR_stateChanged(11);}; + void on_checkRTR_12_stateChanged(int arg1) {checkRTR_stateChanged(12);}; + void on_checkRTR_13_stateChanged(int arg1) {checkRTR_stateChanged(13);}; + void on_checkRTR_14_stateChanged(int arg1) {checkRTR_stateChanged(14);}; + void on_checkRTR_15_stateChanged(int arg1) {checkRTR_stateChanged(15);}; + + void ValidationID(unsigned int numID); + void on_lineID_01_textChanged(const QString &arg1) {ValidationID(1);} + void on_lineID_02_textChanged(const QString &arg1) {ValidationID(2);} + void on_lineID_03_textChanged(const QString &arg1) {ValidationID(3);} + void on_lineID_04_textChanged(const QString &arg1) {ValidationID(4);} + void on_lineID_05_textChanged(const QString &arg1) {ValidationID(5);} + void on_lineID_06_textChanged(const QString &arg1) {ValidationID(6);} + void on_lineID_07_textChanged(const QString &arg1) {ValidationID(7);} + void on_lineID_08_textChanged(const QString &arg1) {ValidationID(8);} + void on_lineID_09_textChanged(const QString &arg1) {ValidationID(9);} + void on_lineID_10_textChanged(const QString &arg1) {ValidationID(10);} + void on_lineID_11_textChanged(const QString &arg1) {ValidationID(11);} + void on_lineID_12_textChanged(const QString &arg1) {ValidationID(12);} + void on_lineID_13_textChanged(const QString &arg1) {ValidationID(13);} + void on_lineID_14_textChanged(const QString &arg1) {ValidationID(14);} + void on_lineID_15_textChanged(const QString &arg1) {ValidationID(15);} + + void on_checkHEX_01_stateChanged(int arg1) {checkHEX_stateChanged(1);}; + void on_checkHEX_02_stateChanged(int arg1) {checkHEX_stateChanged(2);}; + void on_checkHEX_03_stateChanged(int arg1) {checkHEX_stateChanged(3);}; + void on_checkHEX_04_stateChanged(int arg1) {checkHEX_stateChanged(4);}; + void on_checkHEX_05_stateChanged(int arg1) {checkHEX_stateChanged(5);}; + void on_checkHEX_06_stateChanged(int arg1) {checkHEX_stateChanged(6);}; + void on_checkHEX_07_stateChanged(int arg1) {checkHEX_stateChanged(7);}; + void on_checkHEX_08_stateChanged(int arg1) {checkHEX_stateChanged(8);}; + void on_checkHEX_09_stateChanged(int arg1) {checkHEX_stateChanged(9);}; + void on_checkHEX_10_stateChanged(int arg1) {checkHEX_stateChanged(10);}; + void on_checkHEX_11_stateChanged(int arg1) {checkHEX_stateChanged(11);}; + void on_checkHEX_12_stateChanged(int arg1) {checkHEX_stateChanged(12);}; + void on_checkHEX_13_stateChanged(int arg1) {checkHEX_stateChanged(13);}; + void on_checkHEX_14_stateChanged(int arg1) {checkHEX_stateChanged(14);}; + void on_checkHEX_15_stateChanged(int arg1) {checkHEX_stateChanged(15);}; + +// void on_comboDLC_01_stateChanged(int arg1) {comboDLC_stateChanged(1);}; +// void on_comboDLC_02_stateChanged(int arg1) {comboDLC_stateChanged(2);}; +// void on_comboDLC_03_stateChanged(int arg1) {comboDLC_stateChanged(3);}; +// void on_comboDLC_04_stateChanged(int arg1) {comboDLC_stateChanged(4);}; +// void on_comboDLC_05_stateChanged(int arg1) {comboDLC_stateChanged(5);}; +// void on_comboDLC_06_stateChanged(int arg1) {comboDLC_stateChanged(6);}; +// void on_comboDLC_07_stateChanged(int arg1) {comboDLC_stateChanged(7);}; +// void on_comboDLC_08_stateChanged(int arg1) {comboDLC_stateChanged(8);}; +// void on_comboDLC_09_stateChanged(int arg1) {comboDLC_stateChanged(9);}; +// void on_comboDLC_10_stateChanged(int arg1) {comboDLC_stateChanged(10);}; +// void on_comboDLC_11_stateChanged(int arg1) {comboDLC_stateChanged(11);}; +// void on_comboDLC_12_stateChanged(int arg1) {comboDLC_stateChanged(12);}; +// void on_comboDLC_13_stateChanged(int arg1) {comboDLC_stateChanged(13);}; +// void on_comboDLC_14_stateChanged(int arg1) {comboDLC_stateChanged(14);}; +// void on_comboDLC_15_stateChanged(int arg1) {comboDLC_stateChanged(15);}; + + bool ValidationMcrs(unsigned int numID); + void on_lineMcrs_01_textChanged(const QString &arg1) {ValidationMcrs(1);} + void on_lineMcrs_02_textChanged(const QString &arg1) {ValidationMcrs(2);} + void on_lineMcrs_03_textChanged(const QString &arg1) {ValidationMcrs(3);} + void on_lineMcrs_04_textChanged(const QString &arg1) {ValidationMcrs(4);} + void on_lineMcrs_05_textChanged(const QString &arg1) {ValidationMcrs(5);} + void on_lineMcrs_06_textChanged(const QString &arg1) {ValidationMcrs(6);} + void on_lineMcrs_07_textChanged(const QString &arg1) {ValidationMcrs(7);} + void on_lineMcrs_08_textChanged(const QString &arg1) {ValidationMcrs(8);} + void on_lineMcrs_09_textChanged(const QString &arg1) {ValidationMcrs(9);} + void on_lineMcrs_10_textChanged(const QString &arg1) {ValidationMcrs(10);} + void on_lineMcrs_11_textChanged(const QString &arg1) {ValidationMcrs(11);} + void on_lineMcrs_12_textChanged(const QString &arg1) {ValidationMcrs(12);} + void on_lineMcrs_13_textChanged(const QString &arg1) {ValidationMcrs(13);} + void on_lineMcrs_14_textChanged(const QString &arg1) {ValidationMcrs(14);} + void on_lineMcrs_15_textChanged(const QString &arg1) {ValidationMcrs(15);} + + void on_comboDLC_01_currentIndexChanged(int arg1) {comboDLC_stateChanged(1);}; + void on_comboDLC_02_currentIndexChanged(int arg1) {comboDLC_stateChanged(2);}; + void on_comboDLC_03_currentIndexChanged(int arg1) {comboDLC_stateChanged(3);}; + void on_comboDLC_04_currentIndexChanged(int arg1) {comboDLC_stateChanged(4);}; + void on_comboDLC_05_currentIndexChanged(int arg1) {comboDLC_stateChanged(5);}; + void on_comboDLC_06_currentIndexChanged(int arg1) {comboDLC_stateChanged(6);}; + void on_comboDLC_07_currentIndexChanged(int arg1) {comboDLC_stateChanged(7);}; + void on_comboDLC_08_currentIndexChanged(int arg1) {comboDLC_stateChanged(8);}; + void on_comboDLC_09_currentIndexChanged(int arg1) {comboDLC_stateChanged(9);}; + void on_comboDLC_10_currentIndexChanged(int arg1) {comboDLC_stateChanged(10);}; + void on_comboDLC_11_currentIndexChanged(int arg1) {comboDLC_stateChanged(11);}; + void on_comboDLC_12_currentIndexChanged(int arg1) {comboDLC_stateChanged(12);}; + void on_comboDLC_13_currentIndexChanged(int arg1) {comboDLC_stateChanged(13);}; + void on_comboDLC_14_currentIndexChanged(int arg1) {comboDLC_stateChanged(14);}; + void on_comboDLC_15_currentIndexChanged(int arg1) {comboDLC_stateChanged(15);}; + +private: + Ui::MacrosSetting *ui; + void checkPeriod_stateChanged(int index, int arg1); + void checkEID_stateChanged(int index); + void checkRTR_stateChanged(int index); + void checkHEX_stateChanged(int index); + void comboDLC_stateChanged(int index); + bool checkErrors(); + + void GetMcrs(); + void Init(); +}; + +#endif // MACROSSETTING_H diff --git a/macrossetting.ui b/macrossetting.ui new file mode 100644 index 0000000..bdbc52a --- /dev/null +++ b/macrossetting.ui @@ -0,0 +1,4019 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MacrosSetting</class> + <widget class="QDialog" name="MacrosSetting"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>737</width> + <height>550</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>620</width> + <height>550</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>550</height> + </size> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="3" column="1"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="1" column="2"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <layout class="QGridLayout" name="gridLayout"> + <item row="16" column="3"> + <widget class="QLineEdit" name="lineID_15"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="13" column="1"> + <widget class="QLineEdit" name="lineMcrsName_12"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QLabel" name="label_25"> + <property name="text"> + <string>RTR</string> + </property> + </widget> + </item> + <item row="2" column="6"> + <widget class="QComboBox" name="comboDLC_02"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="9" column="7"> + <widget class="QLineEdit" name="lineMcrs_09"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="14" column="1"> + <widget class="QLineEdit" name="lineMcrsName_13"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="4" column="9"> + <widget class="QCheckBox" name="checkPeriod_04"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="15" column="7"> + <widget class="QLineEdit" name="lineMcrs_14"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="7" column="3"> + <widget class="QLineEdit" name="lineID_07"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="3" column="3"> + <widget class="QLineEdit" name="lineID_03"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="5" column="7"> + <widget class="QLineEdit" name="lineMcrs_05"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="1" column="7"> + <widget class="QLineEdit" name="lineMcrs_01"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string/> + </property> + <property name="clearButtonEnabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="11" column="8"> + <widget class="QSpinBox" name="spinCount_11"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="9" column="10"> + <widget class="QSpinBox" name="spinPeriod_09"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="15" column="4"> + <widget class="QCheckBox" name="checkRTR_14"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="6" column="9"> + <widget class="QCheckBox" name="checkPeriod_06"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="3" column="7"> + <widget class="QLineEdit" name="lineMcrs_03"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="8" column="8"> + <widget class="QSpinBox" name="spinCount_08"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>M03</string> + </property> + </widget> + </item> + <item row="7" column="9"> + <widget class="QCheckBox" name="checkPeriod_07"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="16" column="7"> + <widget class="QLineEdit" name="lineMcrs_15"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="13" column="0"> + <widget class="QLabel" name="label_14"> + <property name="text"> + <string>M12</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_24"> + <property name="text"> + <string>E-ID</string> + </property> + </widget> + </item> + <item row="5" column="8"> + <widget class="QSpinBox" name="spinCount_05"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="11" column="3"> + <widget class="QLineEdit" name="lineID_11"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="8" column="4"> + <widget class="QCheckBox" name="checkRTR_08"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="14" column="6"> + <widget class="QComboBox" name="comboDLC_13"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLineEdit" name="lineMcrsName_05"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="lineMcrsName_03"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="8" column="0"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>M08</string> + </property> + </widget> + </item> + <item row="14" column="4"> + <widget class="QCheckBox" name="checkRTR_13"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="3" column="5"> + <widget class="QCheckBox" name="checkHEX_03"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="13" column="2"> + <widget class="QCheckBox" name="checkEID_12"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="8" column="3"> + <widget class="QLineEdit" name="lineID_08"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="1" column="9"> + <widget class="QCheckBox" name="checkPeriod_01"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="8" column="10"> + <widget class="QSpinBox" name="spinPeriod_08"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="7" column="4"> + <widget class="QCheckBox" name="checkRTR_07"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="1" column="6"> + <widget class="QComboBox" name="comboDLC_01"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="13" column="9"> + <widget class="QCheckBox" name="checkPeriod_12"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QLineEdit" name="lineMcrsName_06"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="14" column="3"> + <widget class="QLineEdit" name="lineID_13"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="4" column="10"> + <widget class="QSpinBox" name="spinPeriod_04"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="5" column="2"> + <widget class="QCheckBox" name="checkEID_05"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="3"> + <widget class="QLineEdit" name="lineID_02"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="7" column="6"> + <widget class="QComboBox" name="comboDLC_07"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="8" column="1"> + <widget class="QLineEdit" name="lineMcrsName_08"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="4" column="2"> + <widget class="QCheckBox" name="checkEID_04"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="4"> + <widget class="QCheckBox" name="checkRTR_02"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="1" column="5"> + <widget class="QCheckBox" name="checkHEX_01"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="7" column="8"> + <widget class="QSpinBox" name="spinCount_07"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="1" column="8"> + <widget class="QSpinBox" name="spinCount_01"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="14" column="9"> + <widget class="QCheckBox" name="checkPeriod_13"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="9" column="2"> + <widget class="QCheckBox" name="checkEID_09"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="9" column="6"> + <widget class="QComboBox" name="comboDLC_09"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="4" column="1"> + <widget class="QLineEdit" name="lineMcrsName_04"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="5" column="5"> + <widget class="QCheckBox" name="checkHEX_05"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="16" column="2"> + <widget class="QCheckBox" name="checkEID_15"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="11" column="5"> + <widget class="QCheckBox" name="checkHEX_11"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="16" column="5"> + <widget class="QCheckBox" name="checkHEX_15"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="15" column="5"> + <widget class="QCheckBox" name="checkHEX_14"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="13" column="6"> + <widget class="QComboBox" name="comboDLC_12"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="6" column="10"> + <widget class="QSpinBox" name="spinPeriod_06"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QCheckBox" name="checkEID_02"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="8" column="9"> + <widget class="QCheckBox" name="checkPeriod_08"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="10" column="5"> + <widget class="QCheckBox" name="checkHEX_10"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="2" column="7"> + <widget class="QLineEdit" name="lineMcrs_02"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>M07</string> + </property> + </widget> + </item> + <item row="13" column="4"> + <widget class="QCheckBox" name="checkRTR_12"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="8" column="6"> + <widget class="QComboBox" name="comboDLC_08"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="10" column="2"> + <widget class="QCheckBox" name="checkEID_10"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="2" column="8"> + <widget class="QSpinBox" name="spinCount_02"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="9" column="1"> + <widget class="QLineEdit" name="lineMcrsName_09"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Name</string> + </property> + </widget> + </item> + <item row="13" column="10"> + <widget class="QSpinBox" name="spinPeriod_12"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="7" column="2"> + <widget class="QCheckBox" name="checkEID_07"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="15" column="3"> + <widget class="QLineEdit" name="lineID_14"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="10" column="10"> + <widget class="QSpinBox" name="spinPeriod_10"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="14" column="2"> + <widget class="QCheckBox" name="checkEID_13"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="11" column="4"> + <widget class="QCheckBox" name="checkRTR_11"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="13" column="3"> + <widget class="QLineEdit" name="lineID_12"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="11" column="0"> + <widget class="QLabel" name="label_13"> + <property name="text"> + <string>M11</string> + </property> + </widget> + </item> + <item row="9" column="9"> + <widget class="QCheckBox" name="checkPeriod_09"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="11" column="9"> + <widget class="QCheckBox" name="checkPeriod_11"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QCheckBox" name="checkRTR_01"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="9" column="0"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>M09</string> + </property> + </widget> + </item> + <item row="10" column="8"> + <widget class="QSpinBox" name="spinCount_10"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="11" column="2"> + <widget class="QCheckBox" name="checkEID_11"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="15" column="8"> + <widget class="QSpinBox" name="spinCount_14"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="6" column="4"> + <widget class="QCheckBox" name="checkRTR_06"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="6" column="3"> + <widget class="QLineEdit" name="lineID_06"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="5" column="10"> + <widget class="QSpinBox" name="spinPeriod_05"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="6" column="8"> + <widget class="QSpinBox" name="spinCount_06"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="14" column="5"> + <widget class="QCheckBox" name="checkHEX_13"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="4" column="8"> + <widget class="QSpinBox" name="spinCount_04"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="14" column="10"> + <widget class="QSpinBox" name="spinPeriod_13"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="7" column="7"> + <widget class="QLineEdit" name="lineMcrs_07"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="3" column="10"> + <widget class="QSpinBox" name="spinPeriod_03"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="5" column="4"> + <widget class="QCheckBox" name="checkRTR_05"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="10" column="6"> + <widget class="QComboBox" name="comboDLC_10"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="15" column="10"> + <widget class="QSpinBox" name="spinPeriod_14"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="15" column="1"> + <widget class="QLineEdit" name="lineMcrsName_14"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="9" column="3"> + <widget class="QLineEdit" name="lineID_09"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="11" column="7"> + <widget class="QLineEdit" name="lineMcrs_11"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="label_23"> + <property name="text"> + <string>ID</string> + </property> + </widget> + </item> + <item row="10" column="9"> + <widget class="QCheckBox" name="checkPeriod_10"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_19"> + <property name="text"> + <string>№</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="14" column="7"> + <widget class="QLineEdit" name="lineMcrs_13"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="11" column="10"> + <widget class="QSpinBox" name="spinPeriod_11"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="9" column="5"> + <widget class="QCheckBox" name="checkHEX_09"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="5" column="6"> + <widget class="QComboBox" name="comboDLC_05"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="15" column="0"> + <widget class="QLabel" name="label_16"> + <property name="text"> + <string>M14</string> + </property> + </widget> + </item> + <item row="0" column="5"> + <widget class="QLabel" name="label_18"> + <property name="text"> + <string>HEX</string> + </property> + </widget> + </item> + <item row="16" column="9"> + <widget class="QCheckBox" name="checkPeriod_15"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>M01</string> + </property> + </widget> + </item> + <item row="16" column="1"> + <widget class="QLineEdit" name="lineMcrsName_15"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="3" column="8"> + <widget class="QSpinBox" name="spinCount_03"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="8" column="5"> + <widget class="QCheckBox" name="checkHEX_08"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="4" column="6"> + <widget class="QComboBox" name="comboDLC_04"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="13" column="8"> + <widget class="QSpinBox" name="spinCount_12"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="10" column="7"> + <widget class="QLineEdit" name="lineMcrs_10"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="1" column="10"> + <widget class="QSpinBox" name="spinPeriod_01"> + <property name="minimumSize"> + <size> + <width>60</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QCheckBox" name="checkEID_01"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>M04</string> + </property> + </widget> + </item> + <item row="0" column="7"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Macros</string> + </property> + </widget> + </item> + <item row="4" column="3"> + <widget class="QLineEdit" name="lineID_04"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="16" column="4"> + <widget class="QCheckBox" name="checkRTR_15"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="14" column="0"> + <widget class="QLabel" name="label_15"> + <property name="text"> + <string>M13</string> + </property> + </widget> + </item> + <item row="2" column="9"> + <widget class="QCheckBox" name="checkPeriod_02"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="6" column="6"> + <widget class="QComboBox" name="comboDLC_06"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="13" column="7"> + <widget class="QLineEdit" name="lineMcrs_12"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="15" column="9"> + <widget class="QCheckBox" name="checkPeriod_14"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="8" column="7"> + <widget class="QLineEdit" name="lineMcrs_08"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="0" column="10"> + <widget class="QLabel" name="label_22"> + <property name="text"> + <string>ms</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="10" column="4"> + <widget class="QCheckBox" name="checkRTR_10"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>M05</string> + </property> + </widget> + </item> + <item row="16" column="10"> + <widget class="QSpinBox" name="spinPeriod_15"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="5" column="3"> + <widget class="QLineEdit" name="lineID_05"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="3" column="6"> + <widget class="QComboBox" name="comboDLC_03"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="8" column="2"> + <widget class="QCheckBox" name="checkEID_08"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="0" column="9"> + <widget class="QLabel" name="label_21"> + <property name="text"> + <string>Period</string> + </property> + </widget> + </item> + <item row="16" column="8"> + <widget class="QSpinBox" name="spinCount_15"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="2" column="10"> + <widget class="QSpinBox" name="spinPeriod_02"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="15" column="2"> + <widget class="QCheckBox" name="checkEID_14"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="4" column="5"> + <widget class="QCheckBox" name="checkHEX_04"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="6" column="7"> + <widget class="QLineEdit" name="lineMcrs_06"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="4" column="4"> + <widget class="QCheckBox" name="checkRTR_04"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QLineEdit" name="lineMcrsName_07"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="14" column="8"> + <widget class="QSpinBox" name="spinCount_13"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="7" column="10"> + <widget class="QSpinBox" name="spinPeriod_07"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>2147483647</number> + </property> + </widget> + </item> + <item row="9" column="4"> + <widget class="QCheckBox" name="checkRTR_09"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="2" column="5"> + <widget class="QCheckBox" name="checkHEX_02"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>M02</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>M06</string> + </property> + </widget> + </item> + <item row="16" column="0"> + <widget class="QLabel" name="label_17"> + <property name="text"> + <string>M15</string> + </property> + </widget> + </item> + <item row="7" column="5"> + <widget class="QCheckBox" name="checkHEX_07"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="10" column="3"> + <widget class="QLineEdit" name="lineID_10"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="4" column="7"> + <widget class="QLineEdit" name="lineMcrs_04"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="lineMcrsName_02"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="13" column="5"> + <widget class="QCheckBox" name="checkHEX_12"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QCheckBox" name="checkEID_03"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="10" column="1"> + <widget class="QLineEdit" name="lineMcrsName_10"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="3" column="4"> + <widget class="QCheckBox" name="checkRTR_03"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="0" column="8"> + <widget class="QLabel" name="label_20"> + <property name="text"> + <string>Count</string> + </property> + </widget> + </item> + <item row="6" column="5"> + <widget class="QCheckBox" name="checkHEX_06"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="6" column="2"> + <widget class="QCheckBox" name="checkEID_06"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>25</horstretch> + <verstretch>25</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="tristate"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLineEdit" name="lineID_01"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>16777215</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + <property name="maxLength"> + <number>3</number> + </property> + </widget> + </item> + <item row="3" column="9"> + <widget class="QCheckBox" name="checkPeriod_03"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="9" column="8"> + <widget class="QSpinBox" name="spinCount_09"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>256</number> + </property> + </widget> + </item> + <item row="5" column="9"> + <widget class="QCheckBox" name="checkPeriod_05"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="11" column="6"> + <widget class="QComboBox" name="comboDLC_11"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="15" column="6"> + <widget class="QComboBox" name="comboDLC_14"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="10" column="0"> + <widget class="QLabel" name="label_12"> + <property name="text"> + <string>M10</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLineEdit" name="lineMcrsName_01"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="11" column="1"> + <widget class="QLineEdit" name="lineMcrsName_11"> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maxLength"> + <number>9</number> + </property> + </widget> + </item> + <item row="16" column="6"> + <widget class="QComboBox" name="comboDLC_15"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="0" column="6"> + <widget class="QLabel" name="label_DLC"> + <property name="text"> + <string>DLC</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="1"> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>MacrosSetting</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>MacrosSetting</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..27e9ebe --- /dev/null +++ b/main.cpp @@ -0,0 +1,23 @@ +#include "ProjectSettings.h" + +#include <QApplication> + +#define WITH_MEM_LEAK_TESTING +#ifdef WITH_MEM_LEAK_TESTING + #define _CRTDBG_MAP_ALLOC + #include <stdlib.h> + #include <crtdbg.h> +#endif + +int main(int argc, char *argv[]) +{ +#ifdef WITH_MEM_LEAK_TESTING + _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); +#endif + QApplication a(argc, argv); + setlocale(LC_ALL, ""); + //Для отключения консоли при запуске нужно в файле .pro сделать: #CONFIG += console + UnionCOM w; + w.show(); + return a.exec(); +} diff --git a/mainmenu.cpp b/mainmenu.cpp new file mode 100644 index 0000000..8c25703 --- /dev/null +++ b/mainmenu.cpp @@ -0,0 +1,37 @@ +#include "mainmenu.h" +#include "ui_mainmenu.h" +//#include "ProjectSettings.h" +//#include "QMenu" + + +MainMenu::MainMenu(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::MainMenu) +{ + //CanUsb *wCan = new CanUsb(this); + ui->setupUi(this); + + //ui->tabWidget->addTab(wCan, "CAN"); + + // connect(actionCAN, SIGNAL(activated()), this, SLOT(CAN)); +} + +MainMenu::~MainMenu() +{ + delete ui; +} +void MainMenu::BackToMainMenu() +{ + ui->gridLayoutWidget->show(); +} + +void MainMenu::CAN() +{ + + +} + +void MainMenu::Bluetooth() +{ + +} diff --git a/mainmenu.h b/mainmenu.h new file mode 100644 index 0000000..5547ca2 --- /dev/null +++ b/mainmenu.h @@ -0,0 +1,28 @@ +#ifndef MAINMENU_H +#define MAINMENU_H + +#include <QMainWindow> + +namespace Ui { +class MainMenu; +} + +class MainMenu : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainMenu(QWidget *parent = nullptr); + ~MainMenu(); + +private slots: + + void CAN(); + void BackToMainMenu(); + void Bluetooth(); + +private: + Ui::MainMenu *ui; +}; + +#endif // MAINMENU_H diff --git a/mainmenu.ui b/mainmenu.ui new file mode 100644 index 0000000..e1c4fa4 --- /dev/null +++ b/mainmenu.ui @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>MainMenu</class> + <widget class="QMainWindow" name="MainMenu"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>445</width> + <height>410</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>445</width> + <height>410</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>445</width> + <height>410</height> + </size> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <widget class="QWidget" name="gridLayoutWidget"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QTabWidget" name="tabWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="currentIndex"> + <number>-1</number> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menuBar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>445</width> + <height>20</height> + </rect> + </property> + </widget> + <action name="actionCAN"> + <property name="text"> + <string>CAN</string> + </property> + </action> + <action name="actionBluetooth"> + <property name="text"> + <string>Bluetooth</string> + </property> + </action> + </widget> + <resources/> + <connections/> +</ui> diff --git a/slcan.h b/slcan.h new file mode 100644 index 0000000..c9dc89e --- /dev/null +++ b/slcan.h @@ -0,0 +1,510 @@ +#ifndef __SLCAN_H__ +#define __SLCAN_H__ + +#include <windows.h> + +#define STDCALL __stdcall +#ifdef SLCAN_EXPORT +#define SLCANAPI __declspec(dllexport) +#else +#define SLCANAPI __declspec(dllimport) +#endif + +#define SLCAN_PROPERTY_INDEX_LINKNAME 0 +#define SLCAN_PROPERTY_INDEX_INSTANCEID 1 + +#define SLCAN_PROPERTY_INDEX_DEVICEDESC 2 +#define SLCAN_PROPERTY_INDEX_FRIENDLYNAME 3 +#define SLCAN_PROPERTY_INDEX_PHOBJECTNAME 4 +#define SLCAN_PROPERTY_INDEX_MFG 5 +#define SLCAN_PROPERTY_INDEX_LOCATIONINFO 6 +#define SLCAN_PROPERTY_INDEX_ENUMERATOR 7 +#define SLCAN_PROPERTY_INDEX_CLASS 8 +#define SLCAN_PROPERTY_INDEX_CLASSGUID 9 +#define SLCAN_PROPERTY_INDEX_SERVICE 10 +#define SLCAN_PROPERTY_INDEX_DRIVER 11 +#define SLCAN_PROPERTY_INDEX_PORTNAME 12 +#define SLCAN_PROPERTY_INDEX_PRODUCT 13L +#define SLCAN_PROPERTY_INDEX_MANUFACTURER 14L +#define SLCAN_PROPERTY_INDEX_CONFIGURATION 15L +#define SLCAN_PROPERTY_INDEX_INTERFACE 16L +#define SLCAN_PROPERTY_INDEX_SERIAL 17L +#define SLCAN_PROPERTY_INDEX_ALIAS 18L +#define SLCAN_PROPERTY_INDEX_CHANNELLINK 19L +#define SLCAN_PROPERTY_INDEX_SERIALID 20L + + +#define SLCAN_MODE_CONFIG 0x00 +#define SLCAN_MODE_NORMAL 0x01 +#define SLCAN_MODE_LISTENONLY 0x02 +#define SLCAN_MODE_LOOPBACK 0x03 +#define SLCAN_MODE_SLEEP 0x04 + +#define SLCAN_BR_CIA_1000K 0x8000 +#define SLCAN_BR_CIA_800K 0x8001 +#define SLCAN_BR_CIA_500K 0x8002 +#define SLCAN_BR_CIA_250K 0x8003 +#define SLCAN_BR_CIA_125K 0x8004 +#define SLCAN_BR_CIA_50K 0x8005 +#define SLCAN_BR_CIA_20K 0x8006 +#define SLCAN_BR_CIA_10K 0x8007 +#define SLCAN_BR_400K 0x8008 +#define SLCAN_BR_200K 0x8009 +#define SLCAN_BR_100K 0x800A +#define SLCAN_BR_83333 0x800B +#define SLCAN_BR_33333 0x800C +#define SLCAN_BR_25K 0x800D +#define SLCAN_BR_5K 0x800E +#define SLCAN_BR_30K 0x800F +#define SLCAN_BR_300K 0x8010 +#define SLCAN_BR_LASTINDEX SLCAN_BR_300K + + + + + +#define SLCAN_CAP_MODE_NORMAL 0x01 +#define SLCAN_CAP_MODE_LISTEN_ONLY 0x02 +#define SLCAN_CAP_MODE_LOOP_BACK 0x04 +#define SLCAN_CAP_MODE_SLEEP 0x08 + +#define SLCAN_CAP_TXMODE_ONE_SHOT 0x01 +#define SLCAN_CAP_TXMODE_TIMESTAMP 0x02 + + +#define SLCAN_CAP_CONTR_EXTERNAL 0x00 +#define SLCAN_CAP_CONTR_MCP2515 0x01 +#define SLCAN_CAP_CONTR_SJA1000 0x02 + +#define SLCAN_CAP_CONTR_INTERNAL 0x80 +#define SLCAN_CAP_CONTR_LPC 0x81 +#define SLCAN_CAP_CONTR_STM32 0x82 +#define SLCAN_CAP_CONTR_STM8 0x83 +#define SLCAN_CAP_CONTR_PIC 0x84 +#define SLCAN_CAP_CONTR_PIC_ECAN 0x85 + +#define SLCAN_CAP_PHYS_HS 0x01 +#define SLCAN_CAP_PHYS_LS 0x02 +#define SLCAN_CAP_PHYS_SW 0x04 +#define SLCAN_CAP_PHYS_J1708 0x08 +#define SLCAN_CAP_PHYS_LIN 0x10 +#define SLCAN_CAP_PHYS_KLINE 0x20 + +#define SLCAN_CAP_PHYS_LOAD 0x01 + +#define SLCAN_CAP_BITRATE_INDEX 0x01 +#define SLCAN_CAP_BITRATE_CUSTOM 0x02 +#define SLCAN_CAP_BITRATE_AUTOMATIC 0x04 + + +#define SLCAN_EVT_LEVEL_RX_MSG 0 +#define SLCAN_EVT_LEVEL_TIME_STAMP 1 +#define SLCAN_EVT_LEVEL_TX_MSG 2 +#define SLCAN_EVT_LEVEL_BUS_STATE 3 +#define SLCAN_EVT_LEVEL_COUNTS 4 +#define SLCAN_EVT_LEVEL_ERRORS 5 + +#define SLCAN_EVT_TYPE_RX 0x0 +#define SLCAN_EVT_TYPE_START_TX 0x1 +#define SLCAN_EVT_TYPE_END_TX 0x2 +#define SLCAN_EVT_TYPE_ABORT_TX 0x3 +#define SLCAN_EVT_TYPE_BUS_STATE 0x4 +#define SLCAN_EVT_TYPE_ERROR_COUNTS 0x5 +#define SLCAN_EVT_TYPE_BUS_ERROR 0x6 +#define SLCAN_EVT_TYPE_ARBITRATION_ERROR 0x7 +#define SLCAN_EVT_STAMP_INC 0xF + +#define SLCAN_BUS_STATE_ERROR_ACTIVE 0x00 +#define SLCAN_BUS_STATE_ERROR_ACTIVE_WARN 0x01 +#define SLCAN_BUS_STATE_ERROR_PASSIVE 0x02 +#define SLCAN_BUS_STATE_BUSOFF 0x03 + +#define SLCAN_MES_INFO_EXT 0x01 +#define SLCAN_MES_INFO_RTR 0x02 +#define SLCAN_MES_INFO_ONESHOT 0x04 + + + +#define SLCAN_DEVOP_CREATE 0x00000000 +#define SLCAN_DEVOP_CREATEHANDLE 0x00000001 +#define SLCAN_DEVOP_OPEN 0x00000002 +#define SLCAN_DEVOP_CLOSE 0x00000003 +#define SLCAN_DEVOP_DESTROYHANDLE 0x00000004 +#define SLCAN_DEVOP_DESTROY 0x00000005 + + +#define SLCAN_INVALID_HANDLE_ERROR 0xE0001001 +#define SLCAN_DEVICE_INVALID_HANDLE_ERROR 0xE0001120 +#define SLCAN_HANDLE_INIT_ERROR 0xE0001017 +#define SLCAN_DEVICE_NOTOPEN_ERROR 0xE0001121 + +#define SLCAN_EVT_ERR_TYPE_BIT 0x00 +#define SLCAN_EVT_ERR_TYPE_FORM 0x01 +#define SLCAN_EVT_ERR_TYPE_STUFF 0x02 +#define SLCAN_EVT_ERR_TYPE_OTHER 0x03 + +#define SLCAN_EVT_ERR_DIR_TX 0x00 +#define SLCAN_EVT_ERR_DIR_RX 0x01 + +#define SLCAN_EVT_ERR_FRAME_SOF 0x03 +#define SLCAN_EVT_ERR_FRAME_ID28_ID21 0x02 +#define SLCAN_EVT_ERR_FRAME_ID20_ID18 0x06 +#define SLCAN_EVT_ERR_FRAME_SRTR 0x04 +#define SLCAN_EVT_ERR_FRAME_IDE 0x05 +#define SLCAN_EVT_ERR_FRAME_ID17_ID13 0x07 +#define SLCAN_EVT_ERR_FRAME_ID12_ID5 0x0F +#define SLCAN_EVT_ERR_FRAME_ID4_ID0 0x0E +#define SLCAN_EVT_ERR_FRAME_RTR 0x0C +#define SLCAN_EVT_ERR_FRAME_RSRV0 0x0D +#define SLCAN_EVT_ERR_FRAME_RSRV1 0x09 +#define SLCAN_EVT_ERR_FRAME_DLC 0x0B +#define SLCAN_EVT_ERR_FRAME_DATA 0x0A +#define SLCAN_EVT_ERR_FRAME_CRC_SEQ 0x08 +#define SLCAN_EVT_ERR_FRAME_CRC_DEL 0x18 +#define SLCAN_EVT_ERR_FRAME_ACK_SLOT 0x19 +#define SLCAN_EVT_ERR_FRAME_ACK_DEL 0x1B +#define SLCAN_EVT_ERR_FRAME_EOF 0x1A +#define SLCAN_EVT_ERR_FRAME_INTER 0x12 +#define SLCAN_EVT_ERR_FRAME_AER_FLAG 0x11 +#define SLCAN_EVT_ERR_FRAME_PER_FLAG 0x16 +#define SLCAN_EVT_ERR_FRAME_TDB 0x13 +#define SLCAN_EVT_ERR_FRAME_ERR_DEL 0x17 +#define SLCAN_EVT_ERR_FRAME_OVER_FLAG 0x1C + +#define SLCAN_TX_STATUS_OK 0x00 +#define SLCAN_TX_STATUS_TIMEOUT 0x01 +#define SLCAN_TX_STATUS_BUSOFF 0x02 +#define SLCAN_TX_STATUS_ABORT 0x03 +#define SLCAN_TX_STATUS_NOT_ENA 0x04 +#define SLCAN_TX_STATUS_ERROR_ONE_SHOT 0x05 +#define SLCAN_TX_STATUS_INVALID_MODE 0x06 +#define SLCAN_TX_STATUS_UNKNOWN 0x0F + +#define SLCAN_PURGE_TX_ABORT 0x01 +#define SLCAN_PURGE_RX_ABORT 0x02 +#define SLCAN_PURGE_TX_CLEAR 0x04 +#define SLCAN_PURGE_RX_CLEAR 0x08 + +#pragma pack(push,1) + +#ifdef __cplusplus +extern "C"{ +#endif + +typedef PVOID HSLCAN; + +typedef struct _SLCAN_CAPABILITIES{ + + BYTE bModes; + BYTE bTXModes; + BYTE bMaxEventLevel; + BYTE bController; + BYTE bPhysical; + BYTE bPhysicalLoad; + BYTE bBitrates; + BYTE bAdvancedModes; + DWORD dwCanBaseClk; + DWORD dwTimeStampClk; + WORD wMaxBRP; +}SLCAN_CAPABILITIES,*PSLCAN_CAPABILITIES; + +typedef struct _SLCAN_BITRATE { + WORD BRP; + BYTE TSEG1; + BYTE TSEG2; + BYTE SJW; + BYTE SAM; +}SLCAN_BITRATE,*PSLCAN_BITRATE; + + +typedef void (STDCALL* SLCAN_DEVICE_CALLBACK)( + HSLCAN hDevice, + DWORD dwIndex, + DWORD dwOperation, + PVOID pContext, + DWORD dwContextSize +); + +typedef VOID (STDCALL* SLCAN_DEVICELIST_CALLBACK)( + HSLCAN hDevice, + DWORD dwIndex, + PVOID pContext, + DWORD dwContextSize +); + +typedef struct _SLCAN_MESSAGE{ + BYTE Info; + DWORD ID; + BYTE DataCount; + BYTE Data[8]; +}SLCAN_MESSAGE,*PSLCAN_MESSAGE; + +typedef struct _SLCAN_TXMESSAGE{ + LONG dwDelay; + SLCAN_MESSAGE Msg; +}SLCAN_TXMESSAGE,*PSLCAN_TXMESSAGE; + +typedef struct _SLCAN_EVENT{ + BYTE EventType; + DWORD TimeStampLo; + union { + SLCAN_MESSAGE Msg; + DWORD TimeStamp[2]; + DWORD64 TimeStamp64; + struct { + BYTE BusMode; + BYTE Dummy1; + BYTE ErrCountRx; + BYTE ErrCountTx; + BYTE ErrType; + BYTE ErrDir; + BYTE ErrFrame; + BYTE LostArbitration; + }; + }; +}SLCAN_EVENT,*PSLCAN_EVENT; + +typedef struct _SLCAN_STATE{ + BYTE BusMode; + BYTE Dummy1; + BYTE ErrCountRX; + BYTE ErrCountTX; +}SLCAN_STATE,*PSLCAN_STATE; + +typedef union _SLCAN_TIMESTAMP{ + UINT64 Value; + DWORD dwValue[2]; + USHORT wValue[4]; + BYTE bValue[8]; +}SLCAN_TIMESTAMP,*PSLCAN_TIMESTAMP; + + + +SLCANAPI BOOL STDCALL SlCan_Load( + SLCAN_DEVICE_CALLBACK DeviceProc, + SLCAN_DEVICELIST_CALLBACK DeviceListProc +); + +SLCANAPI BOOL STDCALL SlCan_Free( + BOOL bDoCallBack +); + +SLCANAPI BOOL STDCALL SlCan_Update(); + +SLCANAPI HSLCAN STDCALL SlCan_GetDevice( + DWORD dwIndex +); + +SLCANAPI DWORD STDCALL SlCan_GetDeviceCount(); + + +SLCANAPI HANDLE STDCALL SlCan_DeviceGetHandle( + DWORD dwIndex +); + +SLCANAPI DWORD STDCALL SlCan_DeviceGetProperty( + HSLCAN hDevice, + DWORD dwIndex, + PCHAR pBuf, + DWORD dwSize +); + +SLCANAPI DWORD STDCALL SlCan_DeviceGetPropertyW( + HSLCAN hDevice, + DWORD dwIndex, + PWCHAR pBuf, + DWORD dwSize +); + +SLCANAPI HKEY STDCALL SlCan_DeviceGetRegKey( + HSLCAN hDevice, + DWORD dwIndex +); + +SLCANAPI PVOID STDCALL SlCan_DeviceSetContext( + HSLCAN hDevice, + PVOID pBuf, + DWORD dwBufSize +); + +SLCANAPI PVOID STDCALL SlCan_DeviceGetContext( + HSLCAN hDevice +); + +SLCANAPI DWORD STDCALL SlCan_DeviceGetContextSize( + HSLCAN hDevice +); + +SLCANAPI BOOL STDCALL SlCan_DeviceSetAlias( + HSLCAN hDevice, + PCHAR pBuf +); + +SLCANAPI BOOL STDCALL SlCan_DeviceSetAliasW( + HSLCAN hDevice, + PWCHAR pBuf +); + +SLCANAPI DWORD STDCALL SlCan_DeviceGetAlias( + HSLCAN hDevice, + PCHAR pBuf, + DWORD dwSize +); + +SLCANAPI DWORD STDCALL SlCan_DeviceGetAliasW( + HSLCAN hDevice, + PWCHAR pBuf, + DWORD dwSize +); +SLCANAPI BOOL STDCALL SlCan_DeviceGetCapabilities( + HSLCAN hDevice, + PSLCAN_CAPABILITIES pCapabilities +); + +SLCANAPI BOOL STDCALL SlCan_DeviceOpen( + HSLCAN hDevice +); + +SLCANAPI BOOL STDCALL SlCan_DeviceClose( + HSLCAN hDevice +); + +SLCANAPI BOOL STDCALL SlCan_DeviceSetMode( + HSLCAN hDevice, + DWORD dwMode +); +SLCANAPI BOOL STDCALL SlCan_DeviceGetMode( + HSLCAN hDevice, + PDWORD pdwMode +); + +SLCANAPI BOOL STDCALL SlCan_DeviceGetState( + HSLCAN hDevice, + PSLCAN_STATE pState +); + + +SLCANAPI BOOL STDCALL SlCan_DeviceSetTXTimeOut( + HSLCAN hDevice, + DWORD dwMillisecond +); +SLCANAPI BOOL STDCALL SlCan_DeviceGetTXTimeOut( + HSLCAN hDevice, + PDWORD pdwMillisecond +); + +SLCANAPI BOOL STDCALL SlCan_DeviceGetBitRate( + HSLCAN hDevice, + PSLCAN_BITRATE pBitRate +); + +SLCANAPI BOOL STDCALL SlCan_DeviceSetBitRate( + HSLCAN hDevice, + PSLCAN_BITRATE pBitRate +); + + +SLCANAPI BOOL STDCALL SlCan_DeviceEnaRec( + HSLCAN hDevice, + BYTE bValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceSetLatency( + HSLCAN hDevice, + BYTE bValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceGetLatency( + HSLCAN hDevice, + PBYTE pbValue +); + +SLCANAPI BOOL STDCALL SlCan_DevicePurge( + HSLCAN hDevice, + BYTE bValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceSetEventLevel( + HSLCAN hDevice, + BYTE bValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceGetEventLevel( + HSLCAN hDevice, + PBYTE pbValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceSetStartTimeStamp( + HSLCAN hDevice, + PSLCAN_TIMESTAMP pValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceGetStartTimeStamp( + HSLCAN hDevice, + PSLCAN_TIMESTAMP pValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceGetTimeStamp( + HSLCAN hDevice, + PSLCAN_TIMESTAMP pValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceSetTimeStampPeriod( + HSLCAN hDevice, + LONG lValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceGetTimeStampPeriod( + HSLCAN hDevice, + PLONG plValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceSetExMode( + HSLCAN hDevice, + BYTE bValue +); + +SLCANAPI BOOL STDCALL SlCan_DeviceGetExMode( + HSLCAN hDevice, + PBYTE pbValue +); + + +SLCANAPI BOOL STDCALL SlCan_DeviceWriteMessages( + HSLCAN hDevice, + PSLCAN_MESSAGE pMsg, + DWORD dwCount, + PBYTE pbStatus +); + +SLCANAPI BOOL STDCALL SlCan_DeviceWriteMessagesEx( + HSLCAN hDevice, + PSLCAN_TXMESSAGE pMsg, + DWORD dwCount, + PBYTE pbStatus, + PDWORD pdwCount +); + +SLCANAPI BOOL STDCALL SlCan_DeviceReadMessages( + HSLCAN hDevice, + DWORD dwTimeOut, + PSLCAN_MESSAGE pMsg, + DWORD dwCount, + PDWORD pdwCount +); + +SLCANAPI BOOL STDCALL SlCan_DeviceReadEvents( + HSLCAN hDevice, + DWORD dwTimeOut, + PSLCAN_EVENT pEvent, + DWORD dwCount, + PDWORD pdwCount +); + +#ifdef __cplusplus +} +#endif + +#pragma pack(pop) + +#endif //__SLCAN_H diff --git a/slcan.lib b/slcan.lib new file mode 100644 index 0000000000000000000000000000000000000000..04cd3c6ce45ce7b4b7aa1d6c318ed01a5cb15929 GIT binary patch literal 12884 zcmdT~%Wqp%8voJ&p`nzJ7D!)-^G=#a^Rg4rXs}5$O%*4#>{Nv!<eKERSW4r_aicPu z>5>I&7O1<CSg`1JHY`{mHb@K-5=%y6g;*f|07mdT_uTWi=bm$I$L>gD>B~L$e2?FG ze&>AO&EQ{3)twLi+I=Mv{>?8gr&5c{%X5q2`nlkBac(&%-svWy_lV9d5M9_Ny7&>% zd|yD1@C04C8_>6Sg64nWH1`>iPb+wWhGB})L@%fQDiNcR+W~!tCunq?)8vmtj0W<Y zF6W3C4SdZh@q~!c6l^mZoCxSKo}ii2oQ8h}E@%ugjAnl4H1;{(L5VjwUH%I8LH$2* zn*NlC(Qu8^1p3NoieZ9=&T^VT9i!1NIE^QW7|o(@jK)9VG(84;prMaB&Hf5L=+Y0I zChwxZpo!lY6^qw5b2swa#j9(D)%^9`_Kke8kX_AeQL(snGn<XF=^s9ybGO%TZfz8= zX0|g_EbOh8_KVp{X*azB?ehJDqEV+L)*jkqcrBOuTh;T@OJO^rPDwz+BExIB)Xjt4 zQq4=xg)OOCE_KbTUG<L2JKk#L!G6t@j&cnxvk_8(F}N%@55{_Fe|Im^H49tUyK&&{ zn;=|8aCGU_y~?2jL9%ptv?^Dv9C+2*hw1rLc%)>*LJ|(`TlLksh@qeN?rnG<noB}L zE4Hpz@M@X8a_P{nrgL>I^p$JPFE~1?*t(vucPk#wXX|<b5B-h><a|SOwRBK=zr0tj zl|4r{VcrzdZJ^bwmHnFcu;zd_1aw_yI?y%tn4B1mZ`Ul8|L$0b%DRxzEudMOm0iy{ z)`F?)z@n(uosVp+U>Z7w8uJf^$C65tt81Zk+i!1|?|U~M)a;t3gszQt*3mX44DGkd zwR~KgHNLKiHffyb5QX`==GuNK@9o%os(88vY-Q2J{T;`q4)b+Q^gUKH%-1z@532VZ z6De7`Jle2!<n7n8-jTOw?_5Mg*GEh0=|@C#eHh2;s@B*-LgD^_vkg%(-3~ya0@3NU ziWzq5GzBI?61p~eBY8QmTCPNH0enx{<#bCrN}MIToNkFt-$SwOqazYx>w2&prx#-D zdbg_Onz!j49+vLGU)xX8h|HT#3%JIl-?_G)%e<Y-+~l{i;^tbRkh!*&PH*HgYq`uu z`gU-NwQfdlN8T&#%8o1;mnS}v5fM}0-yDZ&x3&^!I&xS@F7P1YPWQV+v~Z4S`vTEN z7m51ji5`LOULpDx^b5+L%@M7DSYXhL`+K#Y==KQFccArAq8}%T@&iP<%S2z}`2_ds zl_}hh2Z<hoPR|hi4BZvntA9uNb3EUG%vX^A3AR3+CaQt|2)3U<@9YrDkoy9*6XU>} zCHe%<G01%k-miH7;S$;i+~1({|MWwcMzi!HC8(FqQa`;yuTdY3(lot5Lv)@_(@WGt z<8*;8(F9$lQyBC)x<W7085*EhX@sU|kj~K<U8G5xq35WJy6Gf6L(kIl)IlenqV-N{ z?>4dCrtK#poQC~kDHzrZpmt#E+Y35zw?4*JH#bv}b8NRR=!H)-LsdCNgP~#?gP|Se z21mGMqq^}Z!%(!x2<TDtY&0|>z%PJCedv;A^7J#?#Z!luE@2DUtoIY<V3msug^{to z7sr~6i*#U79|=*waI7<M#6n`xi($>ZR-k8JD_}U51UR-Of$I1Pgn)CR7*9-;eKI1a zanMIsrh$(DRuw-3Rd_F}WCDSUigbv2(~}%34H3<=)Jwzg3`^_&EP5}JUM<Q}zAehb z5GW7lX2%4=+A6f_n?BDjqU-&<(On7D6MPe?N7zyPOt=ifqu=2%LurfnFGFAd( z?Mmk;e`&Q4-E=OonBY0IF|GP?d)i|k45XA$8#ro7_|zyzde$h*@UM1(I+tL080l-H z1_algGm2gDP}jY$)qcH|3LDB3TP?&cMX0-%BAAUV6NuGW2uvdCr=zWndTU)q_-wN- znj@CZ+DxfRhV<gPG2zS2I_}Z+TItsvxpF^)K6^Er4FaEfUrLr%lEF8VJKfoiPU`yp z#e7!>;lAwuI%aph_aEFFDTp}YO%#y+5B<{A^VVz`$?($1f?(j&0(}GePf*c`XPV}| z4CGQlHSXs`{{;y-R-dNCmnZP-!QGwxPRdS=)0v(w)G%x8$FwU)y_@BoYUQwUx0aa5 zPbRY0w>EsP@#hrYnIbbl2ntxK2Y;XSOA>?9JC*wfXlLc<G5zs}0Aup(#~Ow}BIs_K z$ZzTgqQ>tSL+KPXOH2k8BxRDShSej=lRsviXj#59tS!8??_)~0>}Z24WMOGVTOlX> z74k1Mi8qz3D`Z#e04r)MWKpo#3i+pa37%|)FuQG@`9@|GF*8Ql@nNdzF<V~J#*FW( z?*R}uW-+@e84QoVXxXmPf7-5E67_7c{#(2R&o+*2BjbsjiR*h_v!nUCa8U{NHJ5G4 zYzOmGY?qHB3()dSRW^v4-W|#LV4{t-4fvyeDjeB}>u)P~L3S!(;3a_9fw2fhQu0o% z0A;Dc-Jf)f{V?!On0Pqk<UL&i9b-&W_Awm+W~U3&zx*puS!%SOF__O-FxB-+B9SaL zh?#P%9i;AXC>e8!u{DAe3D@2ce$Iw0BOe7SOO5tc{Bwq}a#@nH%Z(XCQxdJ|QBJ;Y zUrk7w;+7K~<<PxX!8Y$1Vs_3+8?FfZo)Tua1yjb7tzgFNoEI#ZDk@N*vee*OO3MHH z37-f^r~@%Nr$MA4VUDq5#3jgBy-3$1V;x1*BWVRIOO5t3X6>GiLG`0^33iO$#;o0! zEVwe{ZvivqnA0hYaE}Eu5+JsKofOwKV|Ist{jwd~PfjRES!#4<W7boz1yPT4C06sk zFb4IE4OPU>NTM7cHRTvxe6qrKp6K3*M(oGOPC8B<7IeL0Vh72d7SJ3gI=c<NYNCk* zl7eggj9IpyZTL8dZ)e8HhO<(wpvHKmJ{zi@>S_hov5wd-J!j$~^CR+S3R0FD-K8;p z@VpC=<>VyLF??^#d3wQu*^ZlNGG-lJv|wt<!&Z74vyLuVQ2!S<vwj<HJ8ot%vpQhG zeA>69gaxzpTT<K^K4?K~>lq$%whdXZ+jFAEoo&N5RB@upj}B@B$x?&fDdjlZSVT2q zVn;IE5=}X)262}hez*^~V+uFOnzw-C*fZyWGaknAGx04TIXn?d3Qi~_nZ!qSUx77$ zYCFb{onw<0H1WwmLCR7aW{mwGO^`JTK0`?Bs*{c4#LU=K7{~v#@pO=;6_Wg1qLBUs DkSig* literal 0 HcmV?d00001 diff --git a/union_modbus.cpp b/union_modbus.cpp new file mode 100644 index 0000000..9541d81 --- /dev/null +++ b/union_modbus.cpp @@ -0,0 +1,445 @@ +#include "union_modbus.h" +#include "ui_union_modbus.h" + +#include "writeregistermodel.h" + +#include <QtSerialBus/QModbusTcpClient> +#include <QtSerialBus/QModbusRtuSerialMaster> +#include <QStandardItemModel> +#include <QUrl> + +enum ModbusConnection { + Serial, + Tcp +}; + +union_modbus *this_modbus; + +static void stepToPeriodRequest() +{ + this_modbus->readModbus(); +} + +union_modbus::union_modbus(QWidget *parent) : + QWidget(parent), + ui(new Ui::union_modbus) +{ + ui->setupUi(this); + + initActions(); + + writeModel = new WriteRegisterModel(this); + writeModel->setStartAddress(ui->spinTXStartAddress->value()); + writeModel->setNumberOfValues(ui->comboTXNumberOfValues->currentText()); + + ui->writeValueTable->setModel(writeModel); + ui->writeValueTable->hideColumn(2); + connect(writeModel, &WriteRegisterModel::updateViewport, + ui->writeValueTable->viewport(), QOverload<>::of(&QWidget::update)); + + ui->comboTable->addItem(tr("Coils"), QModbusDataUnit::Coils); + ui->comboTable->addItem(tr("Discrete Inputs"), QModbusDataUnit::DiscreteInputs); + ui->comboTable->addItem(tr("Input Registers"), QModbusDataUnit::InputRegisters); + ui->comboTable->addItem(tr("Holding Registers"), QModbusDataUnit::HoldingRegisters); + + this_modbus=this; + RequestPeriodTimer.setSingleShot(true); + connect(&RequestPeriodTimer, &QTimer::timeout, this, &stepToPeriodRequest); + +#if QT_CONFIG(modbus_serialport) + ui->connectType->setCurrentIndex(0); + onConnectTypeChanged(0); +#else + // lock out the serial port option + ui->connectType->setCurrentIndex(1); + onConnectTypeChanged(1); + ui->connectType->setEnabled(false); +#endif + + auto model = new QStandardItemModel(10, 1, this); + for (int i = 0; i < 100; ++i) + model->setItem(i, new QStandardItem(QStringLiteral("%1").arg(i + 1))); + ui->comboTXNumberOfValues->setModel(model); + + connect(ui->comboTXNumberOfValues, &QComboBox::currentTextChanged, + writeModel, &WriteRegisterModel::setNumberOfValues); + ui->comboTXNumberOfValues->setCurrentText("10"); + auto valueChanged = QOverload<int>::of(&QSpinBox::valueChanged); + connect(ui->spinTXStartAddress, valueChanged, writeModel, &WriteRegisterModel::setStartAddress); + connect(ui->spinTXStartAddress, valueChanged, this, [this, model](int i) { + int lastPossibleIndex = 0; + const int currentIndex = ui->comboTXNumberOfValues->currentIndex(); + for (int ii = 0; ii < 10; ++ii) { + if (ii < (10 - i)) { + lastPossibleIndex = ii; + model->item(ii)->setEnabled(true); + } else { + model->item(ii)->setEnabled(false); + } + } + if (currentIndex > lastPossibleIndex) + ui->comboTXNumberOfValues->setCurrentIndex(lastPossibleIndex); + }); +} + +union_modbus::~union_modbus() +{ + if(modbusDevice->state()==QModbusDevice::ConnectedState) + { + modbusDevice->disconnectDevice(); + } + delete ui; +} + +void union_modbus::statusBarClear() +{ + ui->StatusBar->clear(); +} + +void union_modbus::initActions() +{ + connect(ui->buttonConnectOrDisconnect, &QPushButton::clicked, + this, &union_modbus::onConnectButtonClicked); + connect(ui->buttonRead, &QPushButton::clicked, + this, &union_modbus::onReadButtonClicked); + connect(ui->buttonWrite, &QPushButton::clicked, + this, &union_modbus::onWriteButtonClicked); + connect(ui->buttonReadWrite, &QPushButton::clicked, + this, &union_modbus::onReadWriteButtonClicked); + connect(ui->comboTable, QOverload<int>::of(&QComboBox::currentIndexChanged), + this, &union_modbus::onWriteTableChanged); + connect(ui->connectType, QOverload<int>::of(&QComboBox::currentIndexChanged), + this, &union_modbus::onConnectTypeChanged); + + statusBarTimeOut.setSingleShot(true); + connect(&statusBarTimeOut, &QTimer::timeout, this, &union_modbus::statusBarClear); +} + +void union_modbus::onConnectTypeChanged(int index) +{ + if (modbusDevice) { + modbusDevice->disconnectDevice(); + delete modbusDevice; + modbusDevice = nullptr; + } + + auto type = static_cast<ModbusConnection>(index); + if (type == Serial) { +#if QT_CONFIG(modbus_serialport) + ui->portEdit->clear(); + modbusDevice = new QModbusRtuSerialMaster(this); +#endif + } else if (type == Tcp) { + modbusDevice = new QModbusTcpClient(this); + if (ui->portEdit->text().isEmpty()) + ui->portEdit->setText(QLatin1String("127.0.0.1:502")); + } + + connect(modbusDevice, &QModbusClient::errorOccurred, [this](QModbusDevice::Error) { + ui->StatusBar->setText(modbusDevice->errorString()); + statusBarTimeOut.start(5000); + }); + + if (!modbusDevice) { + ui->buttonConnectOrDisconnect->setDisabled(true); + if (type == Serial) + { + ui->StatusBar->setText(tr("Could not create Modbus master.")); + statusBarTimeOut.start(5000); + } + else + { + ui->StatusBar->setText(tr("Could not create Modbus client.")); + statusBarTimeOut.start(5000); + } + } else { + connect(modbusDevice, &QModbusClient::stateChanged, + this, &union_modbus::onModbusStateChanged); + } +} +void union_modbus::ApplySettings() +{ +#if QT_CONFIG(modbus_serialport) + m_settings.parity = ui->conboParity->currentIndex(); + if (m_settings.parity > 0) + m_settings.parity++; + m_settings.baud = ui->comboBaudRate->currentText().toInt(); + m_settings.dataBits = ui->comboDataBits->currentText().toInt(); + m_settings.stopBits = ui->comboStopBits->currentText().toInt(); +#endif + m_settings.responseTime = ui->spinResponseTimeout->value(); + m_settings.numberOfRetries = ui->spinNumberOfRetries->value(); +} +void union_modbus::onConnectButtonClicked() +{ + if (!modbusDevice) + return; + statusBarTimeOut.stop(); + ui->StatusBar->clear(); + RequestPeriodTimer.stop(); + if (modbusDevice->state() != QModbusDevice::ConnectedState) { + ApplySettings(); + if (static_cast<ModbusConnection>(ui->connectType->currentIndex()) == Serial) { + modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, + ui->portEdit->text()); +#if QT_CONFIG(modbus_serialport) + modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, + m_settings.parity); + modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, + m_settings.baud); + modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, + m_settings.dataBits); + modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, + m_settings.stopBits); +#endif + } else { + const QUrl url = QUrl::fromUserInput(ui->portEdit->text()); + modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, url.port()); + modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, url.host()); + } + modbusDevice->setTimeout(m_settings.responseTime); + modbusDevice->setNumberOfRetries(m_settings.numberOfRetries); + + if (!modbusDevice->connectDevice()) { + ui->StatusBar->setText(tr("Connect failed: ") + modbusDevice->errorString()); + statusBarTimeOut.start(5000); + } + else + { + ui->frameSettings->setEnabled(false); + ui->frameSerialTCPPort->setEnabled(false); + } + } else { + modbusDevice->disconnectDevice(); + ui->frameSettings->setEnabled(true); + ui->frameSerialTCPPort->setEnabled(true); + } +} + +void union_modbus::onModbusStateChanged(int state) +{ + bool connected = (state != QModbusDevice::UnconnectedState); + + if (state == QModbusDevice::UnconnectedState) + ui->buttonConnectOrDisconnect->setText(tr("Connect")); + else if (state == QModbusDevice::ConnectedState) + ui->buttonConnectOrDisconnect->setText(tr("Disconnect")); +} + +void union_modbus::onReadButtonClicked() +{ + if(CurrentReadButtonPosition) + { + if(ui->checkPeriodRequest->checkState()==Qt::Checked) + { + ui->buttonRead->setText("Stop Read"); + CurrentReadButtonPosition = false; + readModbus(); + } + else + { + readModbus(); + } + } + else + { + ui->buttonRead->setText("Read"); + CurrentReadButtonPosition = true; + RequestPeriodTimer.stop(); + } +} +void union_modbus::readModbus() +{ + if (!modbusDevice) + return; + statusBarTimeOut.stop(); + ui->StatusBar->clear(); + if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) { + if (!reply->isFinished()) + connect(reply, &QModbusReply::finished, this, &union_modbus::onReadReady); + else + delete reply; // broadcast replies return immediately + + } else { + ui->StatusBar->setText(tr("Read error: ") + modbusDevice->errorString()); + statusBarTimeOut.start(5000); + } +// if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) { +// if (!reply->isFinished()) +// connect(reply, &QModbusReply::finished, this, &union_modbus::onReadReady); +// else +// delete reply; // broadcast replies return immediately +// } else { +// ui->StatusBar->setText(tr("Read error: ") + modbusDevice->errorString()); +// statusBarTimeOut.start(5000); +// } +// if (auto *reply = modbusDevice->sendReadRequest(readRequest(), ui->serverEdit->value())) { +// if (!reply->isFinished()) +// connect(reply, &QModbusReply::finished, this, &union_modbus::onReadReady); +// else +// delete reply; // broadcast replies return immediately +// } else { +// ui->StatusBar->setText(tr("Read error: ") + modbusDevice->errorString()); +// statusBarTimeOut.start(5000); +// } +} + +void union_modbus::onReadReady() +{ + auto reply = qobject_cast<QModbusReply *>(sender()); + if (!reply) + return; + + ui->readValue->clear(); + if (reply->error() == QModbusDevice::NoError) { + ui->StatusBar->clear(); + const QModbusDataUnit unit = reply->result(); + for (int i = 0, total = int(unit.valueCount()); i < total; ++i) { + const QString entry = tr("Address: %1, Value: %2").arg(unit.startAddress() + i) + .arg(QString::number(unit.value(i), + unit.registerType() <= QModbusDataUnit::Coils ? 10 : 16)); + ui->readValue->addItem(entry); + } + if(CurrentReadButtonPosition == false) + { + RequestPeriodTimer.start(ui->spinPeriodTime->value()); + } + reply->deleteLater(); + return; + } else if (reply->error() == QModbusDevice::ProtocolError) { + ui->StatusBar->setText(tr("Read response error: %1 (Mobus exception: 0x%2)"). + arg(reply->errorString()). + arg(reply->rawResult().exceptionCode(), -1, 16)); + statusBarTimeOut.start(5000); + } else { + ui->StatusBar->setText(tr("Read response error: %1 (code: 0x%2)"). + arg(reply->errorString()). + arg(reply->error(), -1, 16)); + statusBarTimeOut.start(5000); + } + if(CurrentReadButtonPosition==false) + onReadButtonClicked(); + reply->deleteLater(); +} + +void union_modbus::onWriteButtonClicked() +{ + if (!modbusDevice) + return; + statusBarTimeOut.stop(); + ui->StatusBar->clear(); + + QModbusDataUnit writeUnit = writeRequest(); + QModbusDataUnit::RegisterType table = writeUnit.registerType(); + for (int i = 0, total = int(writeUnit.valueCount()); i < total; ++i) { + if (table == QModbusDataUnit::Coils) + writeUnit.setValue(i, writeModel->m_coils[i + writeUnit.startAddress()]); + else + writeUnit.setValue(i, writeModel->m_holdingRegisters[i + writeUnit.startAddress()]); + } + + if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, ui->serverEdit->value())) { + if (!reply->isFinished()) { + connect(reply, &QModbusReply::finished, this, [this, reply]() { + if (reply->error() == QModbusDevice::ProtocolError) { + ui->StatusBar->setText(tr("Write response error: %1 (Mobus exception: 0x%2)") + .arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16)); + statusBarTimeOut.start(5000); + } else if (reply->error() != QModbusDevice::NoError) { + ui->StatusBar->setText(tr("Write response error: %1 (code: 0x%2)"). + arg(reply->errorString()).arg(reply->error(), -1, 16)); + statusBarTimeOut.start(5000); + } + reply->deleteLater(); + }); + } else { + // broadcast replies return immediately + reply->deleteLater(); + } + } else { + ui->StatusBar->setText(tr("Write error: ") + modbusDevice->errorString()); + statusBarTimeOut.start(5000); + } +} + +void union_modbus::onReadWriteButtonClicked() +{ + if (!modbusDevice) + return; + ui->readValue->clear(); + ui->StatusBar->clear(); + statusBarTimeOut.stop(); + + QModbusDataUnit writeUnit = writeRequest(); + QModbusDataUnit::RegisterType table = writeUnit.registerType(); + for (int i = 0, total = int(writeUnit.valueCount()); i < total; ++i) { + if (table == QModbusDataUnit::Coils) + writeUnit.setValue(i, writeModel->m_coils[i + writeUnit.startAddress()]); + else + writeUnit.setValue(i, writeModel->m_holdingRegisters[i + writeUnit.startAddress()]); + } + + if (auto *reply = modbusDevice->sendReadWriteRequest(readRequest(), writeUnit, + ui->serverEdit->value())) { + if (!reply->isFinished()) + connect(reply, &QModbusReply::finished, this, &union_modbus::onReadReady); + else + delete reply; // broadcast replies return immediately + } else { + ui->StatusBar->setText(tr("Read error: ") + modbusDevice->errorString()); + statusBarTimeOut.start(5000); + } +} + +void union_modbus::onWriteTableChanged(int index) +{ + const bool coilsOrHolding = index == 0 || index == 3; + if (coilsOrHolding) { + ui->writeValueTable->setColumnHidden(1, index != 0); + ui->writeValueTable->setColumnHidden(2, index != 3); + ui->writeValueTable->resizeColumnToContents(0); + } + + ui->buttonReadWrite->setEnabled(index == 3); + ui->buttonWrite->setEnabled(coilsOrHolding); + ui->layoutTX->setEnabled(coilsOrHolding); +} + +QModbusDataUnit union_modbus::readRequest() const +{ + const auto table = + static_cast<QModbusDataUnit::RegisterType>(ui->comboTable->currentData().toInt()); + + int startAddress = ui->spinRXStartAddress->value(); + Q_ASSERT(startAddress >= 0 && startAddress < 340); + + // do not go beyond 10 entries + quint16 numberOfEntries = qMin(ui->comboRXNumberOfValues->currentText().toUShort(), quint16(340 - startAddress)); + return QModbusDataUnit(table, startAddress, numberOfEntries); +} + +QModbusDataUnit union_modbus::writeRequest() const +{ + const auto table = + static_cast<QModbusDataUnit::RegisterType>(ui->comboTable->currentData().toInt()); + + int startAddress = ui->spinTXStartAddress->value(); + Q_ASSERT(startAddress >= 0 && startAddress < 340); + + // do not go beyond 10 entries + quint16 numberOfEntries = qMin(ui->comboTXNumberOfValues->currentText().toUShort(), quint16(340 - startAddress)); + return QModbusDataUnit(table, startAddress, numberOfEntries); +} + +void union_modbus::on_checkPeriodRequest_stateChanged(int arg1) +{ + if (ui->checkPeriodRequest->checkState()==Qt::Checked) + { + ui->spinPeriodTime->setEnabled(true); + } + else + { + ui->spinPeriodTime->setEnabled(false); + RequestPeriodTimer.stop(); + } +} diff --git a/union_modbus.h b/union_modbus.h new file mode 100644 index 0000000..0f0ef6c --- /dev/null +++ b/union_modbus.h @@ -0,0 +1,80 @@ +#ifndef UNION_MODBUS_H +#define UNION_MODBUS_H + +#include "QTimer" +#include <QWidget> +#include <QtSerialBus/QModbusDataUnit> +#include "writeregistermodel.h" + +#include <QtSerialBus/qtserialbusglobal.h> +#include <QDialog> +#if QT_CONFIG(modbus_serialport) +#include <QSerialPort> +#endif + +class QModbusClient; +class QModbusReply; + +namespace Ui { +class union_modbus; +} + +class union_modbus : public QWidget +{ + Q_OBJECT + +public: + explicit union_modbus(QWidget *parent = nullptr); + ~union_modbus(); + + struct Settings { +#if QT_CONFIG(modbus_serialport) + int parity = QSerialPort::NoParity; + int baud = QSerialPort::Baud115200; + int dataBits = QSerialPort::Data8; + int stopBits = QSerialPort::OneStop; +#endif + int responseTime = 1000; + int numberOfRetries = 3; + }; + +public slots: + void onReadButtonClicked(); + void readModbus(); +private slots: + void onConnectButtonClicked(); + void onModbusStateChanged(int state); + + void onReadReady(); + + void onWriteButtonClicked(); + void onReadWriteButtonClicked(); + + void onConnectTypeChanged(int); + void onWriteTableChanged(int); + + void on_checkPeriodRequest_stateChanged(int arg1); + +private: + bool CurrentReadButtonPosition = true; + void initActions(); + void statusBarClear(); + void ApplySettings(); + + QTimer RequestPeriodTimer; + QTimer statusBarTimeOut; + + Settings m_settings; + + QModbusDataUnit readRequest() const; + QModbusDataUnit writeRequest() const; + + WriteRegisterModel *writeModel = nullptr; + + QModbusReply *lastRequest = nullptr; + QModbusClient *modbusDevice = nullptr; + + Ui::union_modbus *ui; +}; + +#endif // UNION_MODBUS_H diff --git a/union_modbus.ui b/union_modbus.ui new file mode 100644 index 0000000..1644e95 --- /dev/null +++ b/union_modbus.ui @@ -0,0 +1,675 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>union_modbus</class> + <widget class="QWidget" name="union_modbus"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>390</width> + <height>350</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>390</width> + <height>350</height> + </size> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="4" column="0"> + <widget class="QLabel" name="StatusBar"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>15</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>15</height> + </size> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QGroupBox" name="groupMain"> + <layout class="QGridLayout" name="layoutMain"> + <property name="spacing"> + <number>3</number> + </property> + <item row="3" column="0"> + <layout class="QGridLayout" name="layoutTXAndRX"> + <item row="0" column="0"> + <widget class="QGroupBox" name="boxRX"> + <layout class="QGridLayout" name="layoutRX"> + <item row="0" column="0"> + <layout class="QGridLayout" name="layoutRXSettings"> + <item row="1" column="1"> + <widget class="QComboBox" name="comboRXNumberOfValues"> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + <item> + <property name="text"> + <string>9</string> + </property> + </item> + <item> + <property name="text"> + <string>10</string> + </property> + </item> + <item> + <property name="text"> + <string>120</string> + </property> + </item> + <item> + <property name="text"> + <string>240</string> + </property> + </item> + <item> + <property name="text"> + <string>340</string> + </property> + </item> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="spinRXStartAddress"/> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="labelRXStartAddress"> + <property name="text"> + <string>Start address</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelRXNumberOfValues"> + <property name="text"> + <string>Number of values</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="checkPeriodRequest"> + <property name="text"> + <string>Period</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QSpinBox" name="spinPeriodTime"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="suffix"> + <string> ms</string> + </property> + <property name="minimum"> + <number>100</number> + </property> + <property name="maximum"> + <number>5000</number> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="0"> + <widget class="QListWidget" name="readValue"/> + </item> + </layout> + </widget> + </item> + <item row="0" column="1"> + <widget class="QGroupBox" name="boxTX"> + <layout class="QGridLayout" name="layoutTX"> + <item row="2" column="0"> + <widget class="QTableView" name="writeValueTable"> + <property name="showGrid"> + <bool>true</bool> + </property> + <attribute name="horizontalHeaderVisible"> + <bool>false</bool> + </attribute> + <attribute name="horizontalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + <attribute name="horizontalHeaderStretchLastSection"> + <bool>true</bool> + </attribute> + <attribute name="verticalHeaderVisible"> + <bool>false</bool> + </attribute> + <attribute name="verticalHeaderHighlightSections"> + <bool>false</bool> + </attribute> + </widget> + </item> + <item row="0" column="0"> + <layout class="QGridLayout" name="layoutTXSettings"> + <item row="1" column="1"> + <widget class="QComboBox" name="comboTXNumberOfValues"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="currentText"> + <string>1</string> + </property> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + <item> + <property name="text"> + <string>9</string> + </property> + </item> + <item> + <property name="text"> + <string>10</string> + </property> + </item> + <item> + <property name="text"> + <string>120</string> + </property> + </item> + <item> + <property name="text"> + <string>240</string> + </property> + </item> + <item> + <property name="text"> + <string>340</string> + </property> + </item> + </widget> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="spinTXStartAddress"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelTXNumberOfValues"> + <property name="text"> + <string>Number of values</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="labelTXStartAddress"> + <property name="text"> + <string>Start address</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="comboTable"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelTable"> + <property name="text"> + <string>Table</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item row="1" column="0"> + <widget class="QFrame" name="frameSettings"> + <layout class="QGridLayout" name="layoutSettings"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="2" column="3"> + <widget class="QComboBox" name="comboStopBits"> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + </widget> + </item> + <item row="3" column="2"> + <widget class="QLabel" name="labelResponseTimeout"> + <property name="text"> + <string>Response Timeout:</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QLabel" name="labelStopBits"> + <property name="text"> + <string>Stop Bits:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelBaudRate"> + <property name="text"> + <string>Baud Rate:</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="labelNumberOfRetries"> + <property name="text"> + <string>Number of retries:</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="labelParity"> + <property name="text"> + <string>Parity:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="comboBaudRate"> + <property name="currentIndex"> + <number>7</number> + </property> + <item> + <property name="text"> + <string>1200</string> + </property> + </item> + <item> + <property name="text"> + <string>2400</string> + </property> + </item> + <item> + <property name="text"> + <string>4800</string> + </property> + </item> + <item> + <property name="text"> + <string>9600</string> + </property> + </item> + <item> + <property name="text"> + <string>19200</string> + </property> + </item> + <item> + <property name="text"> + <string>38400</string> + </property> + </item> + <item> + <property name="text"> + <string>57600</string> + </property> + </item> + <item> + <property name="text"> + <string>115200</string> + </property> + </item> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="conboParity"> + <property name="currentIndex"> + <number>1</number> + </property> + <item> + <property name="text"> + <string>No</string> + </property> + </item> + <item> + <property name="text"> + <string>Even</string> + </property> + </item> + <item> + <property name="text"> + <string>Odd</string> + </property> + </item> + <item> + <property name="text"> + <string>Space</string> + </property> + </item> + <item> + <property name="text"> + <string>Mark</string> + </property> + </item> + </widget> + </item> + <item row="3" column="1"> + <widget class="QSpinBox" name="spinNumberOfRetries"> + <property name="value"> + <number>3</number> + </property> + </widget> + </item> + <item row="3" column="3"> + <widget class="QSpinBox" name="spinResponseTimeout"> + <property name="suffix"> + <string> ms</string> + </property> + <property name="minimum"> + <number>-1</number> + </property> + <property name="maximum"> + <number>5000</number> + </property> + <property name="value"> + <number>1000</number> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="labelDataBits"> + <property name="text"> + <string>Data Bits:</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QComboBox" name="comboDataBits"> + <property name="currentIndex"> + <number>3</number> + </property> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="0"> + <layout class="QGridLayout" name="layoutCMDButtons"> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonRead"> + <property name="text"> + <string>Read</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QPushButton" name="buttonReadWrite"> + <property name="text"> + <string>Read-Write</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QPushButton" name="buttonWrite"> + <property name="text"> + <string>Write</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonConnectOrDisconnect"> + <property name="text"> + <string>Connect</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="0"> + <widget class="QFrame" name="frameSerialTCPPort"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>40</height> + </size> + </property> + <layout class="QGridLayout" name="layoutSerialTCPPort" rowstretch="0"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="labelTypeOfConnection"> + <property name="text"> + <string>Type:</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLineEdit" name="portEdit"/> + </item> + <item row="0" column="5"> + <widget class="QLabel" name="labelServerAddress"> + <property name="text"> + <string>Server Address:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="connectType"> + <item> + <property name="text"> + <string>Serial</string> + </property> + </item> + <item> + <property name="text"> + <string>TCP</string> + </property> + </item> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="labelPort"> + <property name="text"> + <string>Port:</string> + </property> + </widget> + </item> + <item row="0" column="4"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="6"> + <widget class="QSpinBox" name="serverEdit"> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>247</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/union_modbus_slave.cpp b/union_modbus_slave.cpp new file mode 100644 index 0000000..969be0f --- /dev/null +++ b/union_modbus_slave.cpp @@ -0,0 +1,335 @@ +#include "union_modbus_slave.h" +#include "ui_union_modbus_slave.h" + +#include <QtSerialBus/QModbusRtuSerialSlave> +#include <QtSerialBus/QModbusTcpServer> +#include <QRegularExpression> +#include <QRegularExpressionValidator> +#include <QStatusBar> +#include <QUrl> + +enum ModbusConnection { + Serial, + Tcp +}; + +union_modbus_slave::union_modbus_slave(QWidget *parent) : + QWidget(parent), + ui(new Ui::union_modbus_slave) +{ + ui->setupUi(this); + setupWidgetContainers(); + +#if QT_CONFIG(modbus_serialport) + ui->connectType->setCurrentIndex(0); + onCurrentConnectTypeChanged(0); +#else + // lock out the serial port option + ui->connectType->setCurrentIndex(1); + onCurrentConnectTypeChanged(1); + ui->connectType->setEnabled(false); +#endif + + //m_settingsDialog = new SettingsDialog(this); + initActions(); +} + +union_modbus_slave::~union_modbus_slave() +{ + if (modbusDevice) + modbusDevice->disconnectDevice(); + delete modbusDevice; + + delete ui; +} + +void union_modbus_slave::statusBarClear() +{ + statusBarTimeOut.stop(); + ui->StatusBar->clear(); +} + +void union_modbus_slave::initActions() +{ +// ui->actionConnect->setEnabled(true); +// ui->actionDisconnect->setEnabled(false); +// ui->actionExit->setEnabled(true); +// ui->actionOptions->setEnabled(true); + + connect(ui->connectButton, &QPushButton::clicked, + this, &union_modbus_slave::onConnectButtonClicked); +// connect(ui->actionConnect, &QAction::triggered, +// this, &union_modbus_slave::onConnectButtonClicked); +// connect(ui->actionDisconnect, &QAction::triggered, +// this, &union_modbus_slave::onConnectButtonClicked); + connect(ui->connectType, QOverload<int>::of(&QComboBox::currentIndexChanged), + this, &union_modbus_slave::onCurrentConnectTypeChanged); + +// connect(ui->actionExit, &QAction::triggered, this, &union_modbus_slave::close); +// connect(ui->actionOptions, &QAction::triggered, m_settingsDialog, &QDialog::show); + + statusBarTimeOut.setSingleShot(true); + connect(&statusBarTimeOut, &QTimer::timeout, this, &union_modbus_slave::statusBarClear); +} + +void union_modbus_slave::onCurrentConnectTypeChanged(int index) +{ + if (modbusDevice) { + modbusDevice->disconnect(); + delete modbusDevice; + modbusDevice = nullptr; + } + + auto type = static_cast<ModbusConnection>(index); + if (type == Serial) { +#if QT_CONFIG(modbus_serialport) + modbusDevice = new QModbusRtuSerialSlave(this); +#endif + } else if (type == Tcp) { + modbusDevice = new QModbusTcpServer(this); + if (ui->portEdit->text().isEmpty()) + ui->portEdit->setText(QLatin1String("127.0.0.1:502")); + } + ui->listenOnlyBox->setEnabled(type == Serial); + + if (!modbusDevice) { + ui->connectButton->setDisabled(true); + if (type == Serial) + { + //statusBar()->showMessage(tr("Could not create Modbus ."), 5000); + ui->StatusBar->setText(tr("Could not create Modbus slave.")); + statusBarTimeOut.start(5000); + } + else + { + ui->StatusBar->setText(tr("Could not create Modbus server.")); + statusBarTimeOut.start(5000); + //statusBar()->showMessage(tr("Could not create Modbus ."), 5000); + } + } else { + QModbusDataUnitMap reg; + reg.insert(QModbusDataUnit::Coils, { QModbusDataUnit::Coils, 0, 100 }); + reg.insert(QModbusDataUnit::DiscreteInputs, { QModbusDataUnit::DiscreteInputs, 0, 100 }); + reg.insert(QModbusDataUnit::InputRegisters, { QModbusDataUnit::InputRegisters, 0, 100 }); + reg.insert(QModbusDataUnit::HoldingRegisters, { QModbusDataUnit::HoldingRegisters, 0, 100 }); + modbusDevice->setMap(reg); + + connect(modbusDevice, &QModbusServer::dataWritten, + this, &union_modbus_slave::updateWidgets); + connect(modbusDevice, &QModbusServer::stateChanged, + this, &union_modbus_slave::onStateChanged); + connect(modbusDevice, &QModbusServer::errorOccurred, + this, &union_modbus_slave::handleDeviceError); + + connect(ui->listenOnlyBox, &QCheckBox::toggled, this, [this](bool toggled) { + if (modbusDevice) + modbusDevice->setValue(QModbusServer::ListenOnlyMode, toggled); + }); + emit ui->listenOnlyBox->toggled(ui->listenOnlyBox->isChecked()); + connect(ui->setBusyBox, &QCheckBox::toggled, this, [this](bool toggled) { + if (modbusDevice) + modbusDevice->setValue(QModbusServer::DeviceBusy, toggled ? 0xffff : 0x0000); + }); + emit ui->setBusyBox->toggled(ui->setBusyBox->isChecked()); + + setupDeviceData(); + } +} + +void union_modbus_slave::handleDeviceError(QModbusDevice::Error newError) +{ + if (newError == QModbusDevice::NoError || !modbusDevice) + return; + + //statusBar()->showMessage(modbusDevice->errorString(), 5000); + ui->StatusBar->setText(tr("Could not create Modbus master.")); + statusBarTimeOut.start(5000); +} + +void union_modbus_slave::onConnectButtonClicked() +{ + bool intendToConnect = (modbusDevice->state() == QModbusDevice::UnconnectedState); + + //statusBar()->clearMessage(); + statusBarClear(); + + if (intendToConnect) { + if (static_cast<ModbusConnection>(ui->connectType->currentIndex()) == Serial) { + modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, + ui->portEdit->text()); +#if QT_CONFIG(modbus_serialport) + short parityStep = ui->parityCombo->currentIndex(); + if (parityStep>0) parityStep++; + modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, + parityStep); + modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, + ui->baudCombo->currentText().toInt()); + modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, + ui->dataBitsCombo->currentText().toInt()); + modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, + ui->stopBitsCombo->currentText().toInt()); +#endif + } else { + const QUrl url = QUrl::fromUserInput(ui->portEdit->text()); + modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, url.port()); + modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, url.host()); + } + modbusDevice->setServerAddress(ui->serverEdit->text().toInt()); + if (!modbusDevice->connectDevice()) { + //statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString(), 5000); + ui->StatusBar->setText(tr("Connect failed: ") + modbusDevice->errorString()); + statusBarTimeOut.start(5000); + } else { + ui->serverFrame->setEnabled(false); + ui->modbusSettings->setEnabled(false); +// ui->actionConnect->setEnabled(false); +// ui->actionDisconnect->setEnabled(true); + } + } else { + modbusDevice->disconnectDevice(); + ui->serverFrame->setEnabled(true); + ui->modbusSettings->setEnabled(true); +// ui->actionConnect->setEnabled(true); +// ui->actionDisconnect->setEnabled(false); + } +} + +void union_modbus_slave::onStateChanged(int state) +{ + bool connected = (state != QModbusDevice::UnconnectedState); +// ui->actionConnect->setEnabled(!connected); +// ui->actionDisconnect->setEnabled(connected); + + if (state == QModbusDevice::UnconnectedState) + ui->connectButton->setText(tr("Connect")); + else if (state == QModbusDevice::ConnectedState) + ui->connectButton->setText(tr("Disconnect")); +} + +void union_modbus_slave::coilChanged(int id) +{ + QAbstractButton *button = coilButtons.button(id); + bitChanged(id, QModbusDataUnit::Coils, button->isChecked()); +} + +void union_modbus_slave::discreteInputChanged(int id) +{ + QAbstractButton *button = discreteButtons.button(id); + bitChanged(id, QModbusDataUnit::DiscreteInputs, button->isChecked()); +} + +void union_modbus_slave::bitChanged(int id, QModbusDataUnit::RegisterType table, bool value) +{ + if (!modbusDevice) + return; + + if (!modbusDevice->setData(table, quint16(id), value)) + { + //statusBar()->showMessage(tr("Could not set data: ") + modbusDevice->errorString(), 5000); + ui->StatusBar->setText(tr("Could not set data: ") + modbusDevice->errorString()); + statusBarTimeOut.start(5000); + } +} + +void union_modbus_slave::setRegister(const QString &value) +{ + if (!modbusDevice) + return; + + const QString objectName = QObject::sender()->objectName(); + if (registers.contains(objectName)) { + bool ok = true; + const quint16 id = quint16(QObject::sender()->property("ID").toUInt()); + if (objectName.startsWith(QStringLiteral("inReg"))) + ok = modbusDevice->setData(QModbusDataUnit::InputRegisters, id, value.toUShort(&ok, 16)); + else if (objectName.startsWith(QStringLiteral("holdReg"))) + ok = modbusDevice->setData(QModbusDataUnit::HoldingRegisters, id, value.toUShort(&ok, 16)); + + if (!ok) + { + ui->StatusBar->setText(tr("Could not set register: ") + modbusDevice->errorString()); + statusBarTimeOut.start(5000); + //statusBar()->showMessage(tr("Could not set register: ") + modbusDevice->errorString(), + // 5000); + } + } +} + +void union_modbus_slave::updateWidgets(QModbusDataUnit::RegisterType table, int address, int size) +{ + for (int i = 0; i < size; ++i) { + quint16 value; + QString text; + switch (table) { + case QModbusDataUnit::Coils: + modbusDevice->data(QModbusDataUnit::Coils, quint16(address + i), &value); + coilButtons.button(address + i)->setChecked(value); + break; + case QModbusDataUnit::HoldingRegisters: + modbusDevice->data(QModbusDataUnit::HoldingRegisters, quint16(address + i), &value); + registers.value(QStringLiteral("holdReg_%1").arg(address + i))->setText(text + .setNum(value, 16)); + break; + default: + break; + } + } +} + +// -- private + +void union_modbus_slave::setupDeviceData() +{ + if (!modbusDevice) + return; + + for (quint16 i = 0; i < coilButtons.buttons().count(); ++i) + modbusDevice->setData(QModbusDataUnit::Coils, i, coilButtons.button(i)->isChecked()); + + for (quint16 i = 0; i < discreteButtons.buttons().count(); ++i) { + modbusDevice->setData(QModbusDataUnit::DiscreteInputs, i, + discreteButtons.button(i)->isChecked()); + } + + bool ok; + for (QLineEdit *widget : qAsConst(registers)) { + if (widget->objectName().startsWith(QStringLiteral("inReg"))) { + modbusDevice->setData(QModbusDataUnit::InputRegisters, quint16(widget->property("ID").toUInt()), + widget->text().toUShort(&ok, 16)); + } else if (widget->objectName().startsWith(QStringLiteral("holdReg"))) { + modbusDevice->setData(QModbusDataUnit::HoldingRegisters, quint16(widget->property("ID").toUInt()), + widget->text().toUShort(&ok, 16)); + } + } +} + +void union_modbus_slave::setupWidgetContainers() +{ + coilButtons.setExclusive(false); + discreteButtons.setExclusive(false); + //Массив указателей на чекбоксы. + //При установке значения в бокс, вызывается функция + //которая высчитывает номер регистра (Значение спинбокса + номер от 0 до 4) + //И передаёт в функцию bitChanged + QRegularExpression regexp(QStringLiteral("coils_(?<ID>\\d+)")); + const QList<QCheckBox *> coils = findChildren<QCheckBox *>(regexp); + for (QCheckBox *cbx : coils) + coilButtons.addButton(cbx, regexp.match(cbx->objectName()).captured("ID").toInt()); + connect(&coilButtons, SIGNAL(buttonClicked(int)), this, SLOT(coilChanged(int))); + + regexp.setPattern(QStringLiteral("disc_(?<ID>\\d+)")); + const QList<QCheckBox *> discs = findChildren<QCheckBox *>(regexp); + for (QCheckBox *cbx : discs) + discreteButtons.addButton(cbx, regexp.match(cbx->objectName()).captured("ID").toInt()); + connect(&discreteButtons, SIGNAL(buttonClicked(int)), this, SLOT(discreteInputChanged(int))); + + regexp.setPattern(QLatin1String("(in|hold)Reg_(?<ID>\\d+)")); + const QList<QLineEdit *> qle = findChildren<QLineEdit *>(regexp); + for (QLineEdit *lineEdit : qle) { + registers.insert(lineEdit->objectName(), lineEdit); + lineEdit->setProperty("ID", regexp.match(lineEdit->objectName()).captured("ID").toInt()); + lineEdit->setValidator(new QRegularExpressionValidator(QRegularExpression(QStringLiteral("[0-9a-f]{0,4}"), + QRegularExpression::CaseInsensitiveOption), this)); + connect(lineEdit, &QLineEdit::textChanged, this, &union_modbus_slave::setRegister); + } +} diff --git a/union_modbus_slave.h b/union_modbus_slave.h new file mode 100644 index 0000000..276c4ee --- /dev/null +++ b/union_modbus_slave.h @@ -0,0 +1,77 @@ +#ifndef UNION_MODBUS_SLAVE_H +#define UNION_MODBUS_SLAVE_H + +#include <QWidget> +#include <QButtonGroup> +#include <QModbusServer> +#include <QTimer> + +QT_BEGIN_NAMESPACE + +class QLineEdit; + +namespace Ui { +class union_modbus_slave; +class SettingsDialog; +} + +QT_END_NAMESPACE + +//namespace Ui { +//class union_modbus_slave; +//} + +//class union_modbus_slave : public QWidget +//{ +// Q_OBJECT + +//public: +// explicit union_modbus_slave(QWidget *parent = nullptr); +// ~union_modbus_slave(); + +//private: +// Ui::union_modbus_slave *ui; +//}; + +class SettingsDialog; + +class union_modbus_slave : public QWidget +{ + Q_OBJECT + +public: + explicit union_modbus_slave(QWidget *parent = nullptr); + ~union_modbus_slave(); + +private Q_SLOTS: + void onConnectButtonClicked(); + void onStateChanged(int state); + + void coilChanged(int id); + void discreteInputChanged(int id); + void bitChanged(int id, QModbusDataUnit::RegisterType table, bool value); + + void setRegister(const QString &value); + void updateWidgets(QModbusDataUnit::RegisterType table, int address, int size); + + void onCurrentConnectTypeChanged(int); + + void handleDeviceError(QModbusDevice::Error newError); + +private: + QTimer statusBarTimeOut; + void statusBarClear(); + + void initActions(); + void setupDeviceData(); + void setupWidgetContainers(); + + Ui::union_modbus_slave *ui = nullptr; + QModbusServer *modbusDevice = nullptr; + + QButtonGroup coilButtons; + QButtonGroup discreteButtons; + QHash<QString, QLineEdit *> registers; + //SettingsDialog *m_settingsDialog = nullptr; +}; +#endif // UNION_MODBUS_SLAVE_H diff --git a/union_modbus_slave.ui b/union_modbus_slave.ui new file mode 100644 index 0000000..ecd56f6 --- /dev/null +++ b/union_modbus_slave.ui @@ -0,0 +1,798 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>union_modbus_slave</class> + <widget class="QWidget" name="union_modbus_slave"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>408</width> + <height>527</height> + </rect> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="12" column="0"> + <widget class="QLabel" name="StatusBar"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="11" column="0"> + <widget class="QGroupBox" name="regModbus"> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="2"> + <widget class="QLabel" name="label_10"> + <property name="text"> + <string>Address</string> + </property> + </widget> + </item> + <item row="8" column="0"> + <widget class="QCheckBox" name="coils_7"> + <property name="text"> + <string>7</string> + </property> + </widget> + </item> + <item row="9" column="0"> + <widget class="QCheckBox" name="coils_8"> + <property name="text"> + <string>8</string> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QLabel" name="label_12"> + <property name="text"> + <string>Holding Registers</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="coils_0"> + <property name="text"> + <string>0</string> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLineEdit" name="inReg_0"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_8"> + <property name="text"> + <string>Coils</string> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QLineEdit" name="holdReg_0"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="label_13"> + <property name="text"> + <string>0</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="coils_1"> + <property name="text"> + <string>1</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>Input Registers</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_9"> + <property name="text"> + <string>Discrete Inputs</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QCheckBox" name="coils_2"> + <property name="text"> + <string>2</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QCheckBox" name="coils_3"> + <property name="text"> + <string>3</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QCheckBox" name="disc_1"> + <property name="text"> + <string>1</string> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QCheckBox" name="coils_6"> + <property name="text"> + <string>6</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QCheckBox" name="coils_4"> + <property name="text"> + <string>4</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QCheckBox" name="coils_5"> + <property name="text"> + <string>5</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QCheckBox" name="disc_0"> + <property name="text"> + <string>0</string> + </property> + </widget> + </item> + <item row="10" column="0"> + <widget class="QCheckBox" name="coils_9"> + <property name="text"> + <string>9</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QCheckBox" name="disc_2"> + <property name="text"> + <string>2</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QCheckBox" name="disc_3"> + <property name="text"> + <string>3</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QCheckBox" name="disc_4"> + <property name="text"> + <string>4</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QCheckBox" name="disc_5"> + <property name="text"> + <string>5</string> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QCheckBox" name="disc_6"> + <property name="text"> + <string>6</string> + </property> + </widget> + </item> + <item row="8" column="1"> + <widget class="QCheckBox" name="disc_7"> + <property name="text"> + <string>7</string> + </property> + </widget> + </item> + <item row="9" column="1"> + <widget class="QCheckBox" name="disc_8"> + <property name="text"> + <string>8</string> + </property> + </widget> + </item> + <item row="10" column="1"> + <widget class="QCheckBox" name="disc_9"> + <property name="text"> + <string>9</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QLabel" name="label_14"> + <property name="text"> + <string>1</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QLabel" name="label_15"> + <property name="text"> + <string>2</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="4" column="2"> + <widget class="QLabel" name="label_16"> + <property name="text"> + <string>3</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="5" column="2"> + <widget class="QLabel" name="label_17"> + <property name="text"> + <string>4</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="6" column="2"> + <widget class="QLabel" name="label_18"> + <property name="text"> + <string>5</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="7" column="2"> + <widget class="QLabel" name="label_19"> + <property name="text"> + <string>6</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="8" column="2"> + <widget class="QLabel" name="label_20"> + <property name="text"> + <string>7</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="9" column="2"> + <widget class="QLabel" name="label_21"> + <property name="text"> + <string>8</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="10" column="2"> + <widget class="QLabel" name="label_22"> + <property name="text"> + <string>9</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="2" column="3"> + <widget class="QLineEdit" name="inReg_1"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="3" column="3"> + <widget class="QLineEdit" name="inReg_2"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="4" column="3"> + <widget class="QLineEdit" name="inReg_3"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="5" column="3"> + <widget class="QLineEdit" name="inReg_4"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="6" column="3"> + <widget class="QLineEdit" name="inReg_5"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="7" column="3"> + <widget class="QLineEdit" name="inReg_6"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="8" column="3"> + <widget class="QLineEdit" name="inReg_7"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="9" column="3"> + <widget class="QLineEdit" name="inReg_8"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="10" column="3"> + <widget class="QLineEdit" name="inReg_9"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="2" column="4"> + <widget class="QLineEdit" name="holdReg_1"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="3" column="4"> + <widget class="QLineEdit" name="holdReg_2"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="4" column="4"> + <widget class="QLineEdit" name="holdReg_3"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="5" column="4"> + <widget class="QLineEdit" name="holdReg_4"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="6" column="4"> + <widget class="QLineEdit" name="holdReg_5"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="7" column="4"> + <widget class="QLineEdit" name="holdReg_6"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="8" column="4"> + <widget class="QLineEdit" name="holdReg_7"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="9" column="4"> + <widget class="QLineEdit" name="holdReg_8"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + <item row="10" column="4"> + <widget class="QLineEdit" name="holdReg_9"> + <property name="placeholderText"> + <string>Hexadecimal A-F, a-f, 0-9.</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="1" column="0"> + <widget class="QGroupBox" name="serverSettingsBox"> + <layout class="QGridLayout" name="gridLayout_3"> + <property name="leftMargin"> + <number>9</number> + </property> + <property name="topMargin"> + <number>9</number> + </property> + <property name="rightMargin"> + <number>9</number> + </property> + <property name="bottomMargin"> + <number>9</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="2" column="0"> + <widget class="QFrame" name="modbusSettings"> + <layout class="QGridLayout" name="gridLayout_2"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="3"> + <widget class="QLabel" name="label_5"> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="text"> + <string>Data Bits:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QComboBox" name="stopBitsCombo"> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>Baud Rate:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Stop Bits:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Parity:</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QComboBox" name="baudCombo"> + <property name="currentIndex"> + <number>7</number> + </property> + <item> + <property name="text"> + <string>1200</string> + </property> + </item> + <item> + <property name="text"> + <string>2400</string> + </property> + </item> + <item> + <property name="text"> + <string>4800</string> + </property> + </item> + <item> + <property name="text"> + <string>9600</string> + </property> + </item> + <item> + <property name="text"> + <string>19200</string> + </property> + </item> + <item> + <property name="text"> + <string>38400</string> + </property> + </item> + <item> + <property name="text"> + <string>57600</string> + </property> + </item> + <item> + <property name="text"> + <string>115200</string> + </property> + </item> + </widget> + </item> + <item row="0" column="4"> + <widget class="QComboBox" name="dataBitsCombo"> + <property name="currentIndex"> + <number>3</number> + </property> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="0" column="2"> + <widget class="QComboBox" name="parityCombo"> + <property name="currentIndex"> + <number>1</number> + </property> + <item> + <property name="text"> + <string>No</string> + </property> + </item> + <item> + <property name="text"> + <string>Even</string> + </property> + </item> + <item> + <property name="text"> + <string>Odd</string> + </property> + </item> + <item> + <property name="text"> + <string>Space</string> + </property> + </item> + <item> + <property name="text"> + <string>Mark</string> + </property> + </item> + </widget> + </item> + </layout> + </widget> + </item> + <item row="3" column="0"> + <layout class="QGridLayout" name="serverModeLayout"> + <item row="0" column="3"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="2"> + <widget class="QCheckBox" name="listenOnlyBox"> + <property name="text"> + <string>Set server listen only</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QCheckBox" name="setBusyBox"> + <property name="text"> + <string>Set server busy</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QPushButton" name="connectButton"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>90</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Connect</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="0" column="0"> + <layout class="QGridLayout" name="serverTurnOnLayout"> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="0"> + <widget class="QFrame" name="serverFrame"> + <layout class="QGridLayout" name="serverPort"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="3"> + <widget class="QLineEdit" name="portEdit"/> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="connectType"> + <item> + <property name="text"> + <string>Serial</string> + </property> + </item> + <item> + <property name="text"> + <string>TCP</string> + </property> + </item> + </widget> + </item> + <item row="0" column="4"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="6"> + <widget class="QSpinBox" name="serverEdit"> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>247</number> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Type:</string> + </property> + </widget> + </item> + <item row="0" column="5"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Server Address:</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Port:</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/unioncom.cpp b/unioncom.cpp new file mode 100644 index 0000000..e70f4a9 --- /dev/null +++ b/unioncom.cpp @@ -0,0 +1,3280 @@ +#include "unioncom.h" +#include "ui_unioncom.h" +#include "ProjectSettings.h" +#include <QSerialPort> +#include "QDialogButtonBox" + +QWidget* init(QWidget *parent) +{ + return new UnionCOM(parent); +} + +////////////// +//Оглавление// +////////////// +/* + Прототипы статичных функций - строка №51 + + Callback функции - строка №83 + + Инициализация программы - строка №223 + + Очистка логгера от сообщений - строка №349 + + Включение и отключение Modbus - строка №369 + + Настройки подключения в зависимости от типа - строка №408 + + Подключение устройства или com-порта - строка №478 + + Отключение устройства или com-порта - строка №687 + + Приём данных - строка №794 + + Загрузка файла - строка №1487 + + Базовые функции отправки данных - строка №1647 + + Отправка команды из строки - строка №1765 + + Отправка пакета байтов, задаваемых на форме в HEX - строка №1970 + + Отправка файла - строка №2187 + + Работа с макросами - строка №2428 +*/ + +UnionCOM *com_target; +CanUsb *wCan = nullptr; +USettingsRS *wRS = nullptr; +union_modbus *ModbusMaster = nullptr; +union_modbus_slave *ModbusSlave = nullptr; + +unsigned div_up(unsigned x, unsigned y) {return (x - 1) / y + 1;} + +/////////////////////////////// +//Прототипы статичных функций// +/////////////////////////////// + +static void turnOnSendFile(); +static void turnOnCMDTX(); +static void turnOnCMDHEXTX(); +static void turnOnMcrsTX(int index); + + +static void stepToStartMCRS1(); +static void stepToStartMCRS2(); +static void stepToStartMCRS3(); +static void stepToStartMCRS4(); +static void stepToStartMCRS5(); +static void stepToStartMCRS6(); +static void stepToStartMCRS7(); +static void stepToStartMCRS8(); +static void stepToStartMCRS9(); +static void stepToStartMCRS10(); +static void stepToStartMCRS11(); +static void stepToStartMCRS12(); +static void stepToStartMCRS13(); +static void stepToStartMCRS14(); +static void stepToStartMCRS15(); +void (*funcptr[])(){stepToStartMCRS1, stepToStartMCRS2, stepToStartMCRS3, + stepToStartMCRS4, stepToStartMCRS5, stepToStartMCRS6, + stepToStartMCRS7, stepToStartMCRS8, stepToStartMCRS9, + stepToStartMCRS10, stepToStartMCRS11, stepToStartMCRS12, + stepToStartMCRS13, stepToStartMCRS14, stepToStartMCRS15}; +static void canReaderThread(UnionCOM* obj); + +//////////////////// +//Callback функции// +//////////////////// + +//Callback функция из библиотеки SlCan, обрабатывающая изменения состояния устройства slcan. +static void __stdcall Device_Callback(HSLCAN cbDevice, DWORD dwIndex, DWORD dwOperation, PVOID pContext, DWORD dwContextSize) +{ + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Изменение состояния устройства slcan."); + qDebug() << msg; + //dwIndex - номер устройства в списке устройств. + if(dwIndex!=0) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] dwIndex = %1.").arg(dwIndex); + qDebug() << msg; + } + //pContext - указатель на контекст устройства. + if(pContext!=nullptr) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] pContext = %1.").arg((long long int)pContext); + qDebug() << msg; + } + //dwContextSize - размер контекста устройства в байтах. + if(dwContextSize!=0) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] dwContextSize = %1.").arg(dwContextSize); + qDebug() << msg; + } + static bool DevOp_Close; + //Пополнение в списке доступных для работы устройств. + if(dwOperation == SLCAN_DEVOP_CREATE) + { + wCan->Refresh(); + if(wCan->GetCount()==0) + { + com_target->gotors(); + } + } + //Открытие устройства для работы. + else if(dwOperation == SLCAN_DEVOP_OPEN) + { + com_target->Connect_Notification(); + } + //Закрытие устройства для работы в нормальных условиях. + else if(dwOperation == SLCAN_DEVOP_CLOSE) + { + com_target->Disconnect_Notification(); + //Флаг необходим, т.к. после отключения Callback функция сработает повторно с операцией SLCAN_DEVOP_DESTROYHANDLE. + DevOp_Close=1; + } + //Закрытие (в том числе - аварийное) устройства. + else if(dwOperation == SLCAN_DEVOP_DESTROYHANDLE) + { + if(com_target->device == cbDevice) + { + //Очистка буффера отправляемых фреймов + SlCan_DevicePurge(com_target->device, SLCAN_PURGE_TX_ABORT|SLCAN_PURGE_TX_CLEAR); + SlCan_DeviceClose(com_target->device); + com_target->AfterDisconnection(); + if(DevOp_Close==0) + { + //Уведомление о аварийном отключении устройства. + com_target->Emergency_Disconnect_Notification(); + } + DevOp_Close=0; + } + //Обновление списка устройств. + wCan->Refresh(); + if(wCan->GetCount()==0) + { + com_target->gotors(); + } + } + //Выбывание устройства из списка доступных устройств. + else if(dwOperation == SLCAN_DEVOP_DESTROY) + { + wCan->Refresh(); + if(wCan->GetCount()==0) + { + com_target->gotors(); + } + } +} + +///Callback функция изменения состояния списка устройств slcan. +static void __stdcall DeviceList_Callback(HSLCAN cbDevice, DWORD dwIndex, PVOID pContext, DWORD dwContextSize) +{ + //cbDevice - ссылнка на устройство + //Если параметр равен 0xFFFFFFFF, то это означает, что список устройств изменился. + if((unsigned long long int)cbDevice==0xffffffff) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Изменение состояние списка устройств slcan."); + qDebug() << msg; + } + //Если параметр не равен 0xFFFFFFFF, то это означает, + //что вновь подключенное устройство уже добавлено + //в спиок и с ним можно работать, например, + //открыть и передавать и принимать фреймы. + else + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] cbDevice = %1.").arg((unsigned long long int)cbDevice); + qDebug() << msg; + } + //dwIndex - номер устройства в списке устройств. + //Может принимать значение 0xFFFFFFFF. + if(dwIndex!=0) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] dwIndex = %1.").arg(dwIndex); + qDebug() << msg; + } + //pContext - указатель на контекст устройства. + if(pContext!=nullptr) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] pContext = %1.").arg((long long int)pContext); + qDebug() << msg; + } + //dwContextSize - размер контекста устройства в байтах. + if(dwContextSize!=0) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] dwContextSize = %1.").arg(dwContextSize); + qDebug() << msg; + } + //Обновление списка доступных устройств. + wCan->Refresh(); + if(wCan->GetCount()==0) + { + com_target->gotors(); + } +} + +static const int THREAD_COUNT = QThread::idealThreadCount(); + +/////////////////////////// +//Инициализация программы// +/////////////////////////// + +UnionCOM::UnionCOM(QWidget *parent) : + QWidget(parent), + ui(new Ui::UnionCOM) +{ + ui->setupUi(this); + com_target=this; + Init(); +} + +UnionCOM::~UnionCOM() +{ + if(ui->buttonDisconnect->isEnabled()) + { + on_buttonDisconnect_clicked(); + } + delete ui; +} + +void UnionCOM::Init() +{ + m_serial = new QSerialPort(this); + SettingWidget(); + AfterDisconnection(); + ui->widgetsModbus->hide(); + //HEX поля для ввода байтов. + { + HEXByteField[0] = ui->HEXByte_0; + HEXByteField[1] = ui->HEXByte_1; + HEXByteField[2] = ui->HEXByte_2; + HEXByteField[3] = ui->HEXByte_3; + HEXByteField[4] = ui->HEXByte_4; + HEXByteField[5] = ui->HEXByte_5; + HEXByteField[6] = ui->HEXByte_6; + HEXByteField[7] = ui->HEXByte_7; + } + //Кнопки макросов. + { + McrsButtons[0] = ui->buttonMacros_01; + McrsButtons[1] = ui->buttonMacros_02; + McrsButtons[2] = ui->buttonMacros_03; + McrsButtons[3] = ui->buttonMacros_04; + McrsButtons[4] = ui->buttonMacros_05; + McrsButtons[5] = ui->buttonMacros_06; + McrsButtons[6] = ui->buttonMacros_07; + McrsButtons[7] = ui->buttonMacros_08; + McrsButtons[8] = ui->buttonMacros_09; + McrsButtons[9] = ui->buttonMacros_10; + McrsButtons[10] = ui->buttonMacros_11; + McrsButtons[11] = ui->buttonMacros_12; + McrsButtons[12] = ui->buttonMacros_13; + McrsButtons[13] = ui->buttonMacros_14; + McrsButtons[14] = ui->buttonMacros_15; + } + //Кнопки остановки переодической отправки макросов. + { + McrsStopButtons[0] = ui->buttonStopMacros_01; + McrsStopButtons[1] = ui->buttonStopMacros_02; + McrsStopButtons[2] = ui->buttonStopMacros_03; + McrsStopButtons[3] = ui->buttonStopMacros_04; + McrsStopButtons[4] = ui->buttonStopMacros_05; + McrsStopButtons[5] = ui->buttonStopMacros_06; + McrsStopButtons[6] = ui->buttonStopMacros_07; + McrsStopButtons[7] = ui->buttonStopMacros_08; + McrsStopButtons[8] = ui->buttonStopMacros_09; + McrsStopButtons[9] = ui->buttonStopMacros_10; + McrsStopButtons[10] = ui->buttonStopMacros_11; + McrsStopButtons[11] = ui->buttonStopMacros_12; + McrsStopButtons[12] = ui->buttonStopMacros_13; + McrsStopButtons[13] = ui->buttonStopMacros_14; + McrsStopButtons[14] = ui->buttonStopMacros_15; + } + //Стартовые значения макросов. + { + for(int i = 0; i < 15; i++) + { + //Имя макроса по умолчанию - название кнопки. "М" + номер макроса. + MacrosMain[i].Name = McrsButtons[i]->text(); + //Поле макроса + MacrosMain[i].Mcrs.clear(); + //Макрос задаётся в HEX или символами. По умолчанию - символы. + MacrosMain[i].IsHEX = Qt::Unchecked; + MacrosMain[i].DLC = 8; + //Отправляется ли макрос раз в N период. По умолчанию - нет. + MacrosMain[i].IsPeriod = Qt::Unchecked; + //Количество отправок за одну передачу. По умолчанию - 1. + MacrosMain[i].Count = 1; + //Период в мс. По умолчанию - 1. + MacrosMain[i].Period = 1; + } + } + //Выключаются кнопки макросов при запуске приложения. + { + for(int i = 0; i < 15; i++) + { + McrsStopButtons[i]->setEnabled(FALSE); + notTimeToStopPeriodMcrs[i]=FALSE; + } + } + //Создаются таймеры для периодических макросов. + { + for(int index = 0; index < 15; index++) + { + McrsPeriodTransfer[index] = new QTimer(this); + McrsPeriodTransfer[index]->setSingleShot(TRUE); + connect(McrsPeriodTransfer[index], &QTimer::timeout, this, funcptr[index]); + } + } + ui->groupRXErrors->hide(); + ui->groupTXErrors->hide(); + tableInit(); + + + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Инициализация завершена."); + qDebug()<<msg; + +} + +void UnionCOM::gotors() +{ + ui->cboxTypeConnection->setCurrentIndex(1); +} + +//////////////////////////////// +//Очистка логгера от сообщений// +//////////////////////////////// +void UnionCOM::appendToLogger(QString msgToLogger) +{ + ui->logger->append(msgToLogger); +} + +void UnionCOM::on_buttonClearLogger_clicked() +{ + ui->logger->clear(); + RxCanModel->removeRows(0, RxCanModel->rowCount()); + RxCanRequesterModel->removeRows(0, RxCanRequesterModel->rowCount()); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Очистка логгера."; + counterOfLoggerMSG=0; + qDebug() << msg; +} + +///////////////////////////////// +//Включение и отключение Modbus// +///////////////////////////////// + +void UnionCOM::on_checkModbusEnabled_stateChanged(int arg1) +{ + if(ui->checkModbusEnabled->checkState()==Qt::Checked) + { + ui->verticalSpacerModbus->changeSize(0, 0, QSizePolicy::Fixed, QSizePolicy::Fixed); + ui->widgetsModbus->show(); + ModbusMaster = new union_modbus(nullptr); + ModbusSlave = new union_modbus_slave(nullptr); + ui->widgetsModbus->addTab(ModbusMaster, "Master"); + ui->widgetsModbus->addTab(ModbusSlave, "Slave"); + } + else + { + if(ModbusMaster!=nullptr) + { + ModbusMaster->close(); + ModbusMaster->~union_modbus(); + ModbusMaster = nullptr; + } + if(ModbusSlave!=nullptr) + { + ModbusSlave->close(); + ModbusSlave->~union_modbus_slave(); + ModbusSlave = nullptr; + } + ui->verticalSpacerModbus->changeSize(0, 50, QSizePolicy::Expanding, QSizePolicy::Expanding); + ui->widgetsModbus->hide(); + } +} + +///////////////////////// +//Настройки подключения// +//в зависимости от типа// +///////////////////////// + +//QT-слот, срабатывающий при изменении типа подключения. +void UnionCOM::on_cboxTypeConnection_currentIndexChanged(int index) +{ + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Изменение типа подключения. Текущий тип: "); + switch (index) { + case 0: + msg += "CAN."; + break; + case 1: + msg += "RS."; + break; + } + qDebug() << msg; + SettingWidget(); +} + +void UnionCOM::SettingWidget() +{ + switch (ui->cboxTypeConnection->currentIndex()) { + case 0: + //CAN + //Если перед этим было открыто окно настроек для RS - оно закрывается. + { + if (wRS) + { + wRS->close(); + delete wRS; + wRS=nullptr; + } + //Загрузка библиотеки и настраивание callback функций. + SlCan_Load(Device_Callback, DeviceList_Callback); + //Создание окна настроек CAN. + wCan = new CanUsb(ui->widget); + if(wCan->GetCount()==0) + { + ui->cboxTypeConnection->setCurrentIndex(1); + } + else + { + //Отображение окна + wCan->show(); + } + break; + } + case 1: + //RS + //Если перед этим было открыто окно настроек для CAN - оно закрывается. Освобождается библиотека. + { + if (wCan) + { + SlCan_Free(FALSE); + wCan->close(); + delete wCan; + wCan=nullptr; + } + } + //Создание окна настроек RS. + wRS = new USettingsRS(ui->widget); + //Отображение окна. + wRS->show(); + break; + } +} + +////////////////////////// +//Подключение устройства// +// или com-порта // +////////////////////////// + +QString UnionCOM::errors_RS(int ConnectionError) +{ + QString error_msg = QString::number(ConnectionError, 10); + error_msg += ": "; + switch (ConnectionError) { + case 0: + error_msg += "No error occurred."; + break; + case 1: + error_msg += "An error occurred while attempting to open an non-existing device."; + break; + case 2: + error_msg += "An error occurred while attempting to open an already opened device by another process or a user not having enough permission and credentials to open."; + break; + case 3: + error_msg += "An error occurred while attempting to open an already opened device in this object."; + break; + case 4: + error_msg += "Parity error detected by the hardware while reading data. This value is obsolete. We strongly advise against using it in new code."; + break; + case 5: + error_msg += "Framing error detected by the hardware while reading data. This value is obsolete. We strongly advise against using it in new code."; + break; + case 6: + error_msg += "Break condition detected by the hardware on the input line. This value is obsolete. We strongly advise against using it in new code."; + break; + case 7: + error_msg += "An I/O error occurred while writing the data."; + break; + case 8: + error_msg += "An I/O error occurred while reading the data."; + break; + case 9: + error_msg += "An I/O error occurred when a resource becomes unavailable, e.g. when the device is unexpectedly removed from the system."; + break; + case 10: + error_msg += "The requested device operation is not supported or prohibited by the running operating system."; + break; + case 11: + error_msg += "An unidentified error occurred."; + break; + case 12: + error_msg += "A timeout error occurred."; + break; + case 13: + error_msg += "This error occurs when an operation is executed that can only be successfully performed if the device is open."; + break; + } + return error_msg; +} + +//QT-слот, обрабатывающий подключение устройства/порта в зависимости от выбранного типа подключения. +void UnionCOM::on_buttonConnect_clicked() +{ + switch (ui->cboxTypeConnection->currentIndex()) { + case 0: + //CAN + openCAN(); + break; + case 1: + //RS + openSerialPort(); + break; + } +} + +//Функция открытия устройства CAN. +void UnionCOM::openCAN() +{ + //Если было подключено устройство - отключаем. + SlCan_DeviceClose(device); + //Получаем ссылку на новое устройство. + device = wCan->GetDevice(); + //Получаем настройки устройства и сообщений. + int indx = wCan->GetBR(); + //Получаем режим устройства. + SLCAN_MODE = wCan->GetMode(); + br.BRP = 0x8000 + indx; + ID = wCan->GetID(); + //Попытка открыть устройство. + if(SlCan_DeviceOpen(device)) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Настройка устройства CAN."; + qDebug() << msg; + //Настройка устройства. + //Устройство переходит в режим настройки. + SlCan_DeviceSetMode(device, SLCAN_MODE_CONFIG); + //Настройка битрейта. + SlCan_DeviceSetBitRate(device, &br); + //Настройка уровня генерации событий. + SlCan_DeviceSetEventLevel(device, SLCAN_EVT_LEVEL_ERRORS); + // + SlCan_DeviceSetStartTimeStamp(device, 0); + SlCan_DeviceSetTimeStampPeriod(device, 1); + //Устройство возвращается к работе. + SlCan_DeviceSetMode(device, SLCAN_MODE); + //Настройка сообщения. + outMsg.ID = ID; + outMsg.Info = SLCAN_MES_INFO_EXT; + outMsg.DataCount = 8; + //Перевод режима работы приложения с этапа настройки на этап работы с выбранным устройством. + AfterConnection(); + timeFromRXErrorClear = new QTimer(); + timeFromTXErrorClear = new QTimer(); + connect(timeFromRXErrorClear, SIGNAL(timeout()), this, SLOT(rxErrorTimer_anotherSec())); + connect(timeFromTXErrorClear, SIGNAL(timeout()), this, SLOT(txErrorTimer_anotherSec())); + ui->spinRXErrorCount->setValue(0); + ui->spinTXErrorCount->setValue(0); + timeFromRXErrorClear->start(1000); + timeFromTXErrorClear->start(1000); + TimeToStopCANRead = FALSE; + QtConcurrent::run(canReaderThread, this); + ui->groupRXErrors->show(); + ui->groupTXErrors->show(); + } + else + { + //Ошибка при открытии. + QMessageBox msgBox; + msgBox.setText("Не удалось подключиться к устройству."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + ui->logger->setTextColor(Qt::red); + msg += QString("[SYS] Не удалось подключиться к устройству."); + ui->logger->append(msg); + ui->logger->setTextColor(Qt::black); + qDebug() << msg; + } +} + +//Открытие порта RS. +void UnionCOM::openSerialPort() +{ + wRS->device_connect(); + //Настройки порта: + m_serial->setPortName(wRS->m_currentSettings.name); + m_serial->setBaudRate(wRS->m_currentSettings.baudRate); + m_serial->setDataBits(wRS->m_currentSettings.dataBits); + m_serial->setParity(wRS->m_currentSettings.parity); + m_serial->setStopBits(wRS->m_currentSettings.stopBits); + m_serial->setFlowControl(wRS->m_currentSettings.flowControl); + + //Попытка открыть порт. + if (m_serial->open(QIODevice::ReadWrite)) { + //Успешно + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Устройство подключено."); + ui->logger->setTextColor(Qt::blue); + ui->logger->append(msg); + ui->logger->setTextColor(Qt::black); + qDebug() << msg; + //Включается функция приёма сообщений. + connect(m_serial, &QSerialPort::readyRead, this, &UnionCOM::readData); + AfterConnection(); + } else { + //Ошибка при открытии. + QMessageBox msgBox; + msgBox.setText("Не удалось подключиться к устройству."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + ui->logger->setTextColor(Qt::red); + msg += QString("[SYS] Не удалось подключиться к устройству. Error №%1").arg(errors_RS(m_serial->error())); + ui->logger->append(msg); + ui->logger->setTextColor(Qt::black); + qDebug() << msg; + } +} + +//Уведомление о подключении устройства. +void UnionCOM::Connect_Notification() +{ + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Устройство подключено."); + ui->logger->setTextColor(Qt::blue); + ui->logger->append(msg); + ui->logger->setTextColor(Qt::black); + qDebug() << msg; +} + +//Перевод приложения в режим работы с устройством. +void UnionCOM::AfterConnection() +{ + switch (ui->cboxTypeConnection->currentIndex()) { + case 0: //CAN + { + wCan->AfterConnection(); + if(wCan->GetMode()!=SLCAN_MODE_LISTENONLY) + { + ui->TXgridFrame->setEnabled(TRUE); + } + break; + } + case 1: //RS + { + wRS->AfterConnection(); + ui->TXgridFrame->setEnabled(TRUE); + break; + } + } + ui->cboxTypeConnection->setEnabled(FALSE); + ui->buttonConnect->setEnabled(FALSE); + ui->buttonDisconnect->setEnabled(TRUE); +} + +///////////////////////// +//Отключение устройства// +// или com-порта // +///////////////////////// + +//QT-слот обработчик отключения от устройства/порта. +void UnionCOM::on_buttonDisconnect_clicked() +{ + for(int i = 0; i < 15; i++) + { + if(MacrosMain[i].IsPeriod==Qt::Checked) + stopMcrs(i+1); + } + switch (ui->cboxTypeConnection->currentIndex()) { + case 0: + { + //CAN + //Очистка буффера отправляемых сообщений. + ui->groupRXErrors->hide(); + ui->spinRXErrorCount->setValue(0); + ui->groupTXErrors->hide(); + ui->spinTXErrorCount->setValue(0); + timeFromRXErrorClear->stop(); + timeFromTXErrorClear->stop(); + QTime time(0, 0, 0); + ui->timeEditRX->setTime(time); + ui->timeEditTX->setTime(time); + //SlCan_DevicePurge(device, SLCAN_PURGE_TX_ABORT|SLCAN_PURGE_TX_CLEAR|SLCAN_PURGE_RX_ABORT|SLCAN_PURGE_RX_CLEAR); + stopCANReadThread(); + //Отключение устройства. + SlCan_DeviceClose(device); + break; + } + case 1: + { + //RS + //Отключается функция приёма сообщений. + disconnect(m_serial, &QSerialPort::readyRead, this, &UnionCOM::readData); + //Если устройство открыто - отключение. + if (m_serial->isOpen()) + m_serial->close(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Устройство отключено."); + ui->logger->setTextColor(Qt::blue); + ui->logger->append(msg); + ui->logger->setTextColor(Qt::black); + qDebug() << msg; + break; + } + } + AfterDisconnection(); +} + +//Уведомление о отключении устройства. +void UnionCOM::Disconnect_Notification() +{ + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Устройство отключено."); + ui->logger->setTextColor(Qt::blue); + ui->logger->append(msg); + ui->logger->setTextColor(Qt::black); + qDebug() << msg; +} + +//Уведомление о аварийном отключении устройства. +void UnionCOM::Emergency_Disconnect_Notification() +{ + ui->logger->setTextColor(Qt::red); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Устройство аварийно завершило работу."); + ui->logger->append(msg); + ui->logger->setTextColor(Qt::black); + qDebug() << msg; + ui->groupRXErrors->hide(); + ui->spinRXErrorCount->setValue(0); + ui->groupTXErrors->hide(); + ui->spinTXErrorCount->setValue(0); + timeFromRXErrorClear->stop(); + timeFromTXErrorClear->stop(); + QTime time(0, 0, 0); + ui->timeEditRX->setTime(time); + ui->timeEditTX->setTime(time); +} + +//Перевод приложения в режим настройки и выбора подключения. +void UnionCOM::AfterDisconnection() +{ + switch (ui->cboxTypeConnection->currentIndex()) { + case 0: + //CAN + { + wCan->AfterDisconnection(); + break; + } + case 1: + //RS + { + wRS->AfterDisconnection(); + break; + } + } + ui->cboxTypeConnection->setEnabled(TRUE); + ui->buttonConnect->setEnabled(TRUE); + ui->buttonDisconnect->setEnabled(FALSE); + ui->TXgridFrame->setEnabled(FALSE); +} + +//////////////// +//Приём данных// +//////////////// +void UnionCOM::deleteTopLine() +{ + QTextCursor cursor = ui->logger->textCursor(); + cursor.movePosition(QTextCursor::Start); + cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, 0); + cursor.select(QTextCursor::LineUnderCursor); + cursor.removeSelectedText(); + cursor.deleteChar(); +} + +void UnionCOM::rxErrorTimer_clear() +{ + QTime time(0, 0, 0); + ui->timeEditRX->setTime(time); + timeFromRXErrorClear->start(1000); +} + +void UnionCOM::txErrorTimer_clear() +{ + QTime time(0, 0, 0); + ui->timeEditTX->setTime(time); + timeFromTXErrorClear->start(1000); +} + +void UnionCOM::rxErrorTimer_anotherSec() +{ + QTime time = ui->timeEditRX->time().addSecs(1); + ui->timeEditRX->setTime(time); +} + +void UnionCOM::txErrorTimer_anotherSec() +{ + QTime time = ui->timeEditTX->time().addSecs(1); + ui->timeEditTX->setTime(time); +} + +static void canReaderThread(UnionCOM* obj) +{ + obj->canReadingInThread = TRUE; + obj->TimeToReadEvents(); +} + +//QString timeInterval(const QString& from, const QString& to, const QString& format = "hh:mm:ss:ms") +//{ +// QDateTime fromDt = QDateTime::fromString(from, format); +// QDateTime toDt = QDateTime::fromString(to, format); +// if (fromDt.isValid() && toDt.isValid()) { +// QDateTime interval = QDateTime::fromMSecsSinceEpoch(toDt.toMSecsSinceEpoch() - fromDt.toMSecsSinceEpoch()); +// return interval.toString(format); +// } +// return QString(); +//} + +bool UnionCOM::event(QEvent* event) +{ + if (event->type() == QEvent::User) + { + if(counterOfLoggerMSG>=500) + { + deleteTopLine(); + } + else + { + counterOfLoggerMSG++; + } + MyEvent* postedEvent = static_cast<MyEvent*>(event); + switch (postedEvent->msgType()) { + case NORMAL_MSG_TO_LOGGER: + ui->logger->setTextColor(Qt::black); + break; + case WARNING_TO_LOGGER: + ui->logger->setTextColor(Qt::red); + break; + case GHOST_TO_LOGGER: + ui->logger->setTextColor(Qt::gray); + break; + case TX_ERROR_EVENT: + ui->spinTXErrorCount->stepUp(); + postedEvent->~MyEvent(); + event->~QEvent(); + return true; + case RX_ERROR_EVENT: + ui->spinRXErrorCount->stepUp(); + postedEvent->~MyEvent(); + event->~QEvent(); + return true; + } + ui->logger->append(postedEvent->message()); + ui->logger->setTextColor(Qt::black); + postedEvent->~MyEvent(); + event->~QEvent(); + return true; + } + if(event->type() == RxCanEvent::EventType) + { + int i; + RxCanEvent* postedEvent = static_cast<RxCanEvent*>(event); + unsigned long long periodtmp = postedEvent->time_stamp(); + QTime Period(0, 0, 0); + for(i = 0; i < RxCanModel->rowCount(); i++) + { + if(RxCanModel->item(i, RX_CAN_GROUP_TABLE_ID_COLUMN)->text().toUInt(nullptr, 16)==postedEvent->msg().ID) + { + PSLCAN_TIMESTAMP per_tmp = new SLCAN_TIMESTAMP(); + per_tmp->Value = periodtmp - RxCanModel->item(i, RX_CAN_GROUP_TABLE_TMPS)->text().toULongLong(nullptr, 10); + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_PERIOD_COLUMN, //(QStringLiteral("%1").arg(postedEvent->msg().ID, 8, 16, QLatin1Char('0') + new QStandardItem(QString("%1:%2:%3.%4.%5").arg(QString::number(microsecondToHours(per_tmp->Value)), + QStringLiteral("%1").arg(microsecondToMinutes(per_tmp->Value), 2, 10, QLatin1Char('0')), + QStringLiteral("%1").arg(microsecondToSeconds(per_tmp->Value), 2, 10, QLatin1Char('0')), + QStringLiteral("%1").arg(microsecondToMilliseconds(per_tmp->Value), 3, 10, QLatin1Char('0')), + QStringLiteral("%1").arg(per_tmp->Value%1000, 3, 10, QLatin1Char('0'))))); + delete per_tmp; +// Period = Period.addMSecs((QTime::fromString(RxCanModel->item(i, RX_CAN_GROUP_TABLE_TIME_COLUMN)->text(), "hh:mm:ss.zzz")).msecsTo(postedEvent->time())); +// RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_PERIOD_COLUMN, +// new QStandardItem(Period.toString("hh:mm:ss.zzz"))); + + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_TMPS, new QStandardItem(QString::number(periodtmp))); + + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_TIME_COLUMN, + new QStandardItem(postedEvent->time().toString("hh:mm:ss.zzz"))); + + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_COUNT_COLUMN, + new QStandardItem(QString::number(RxCanModel->item(i, RX_CAN_GROUP_TABLE_COUNT_COLUMN)->text().toInt(nullptr, 10)+1, 10))); + + QStandardItem *E_Standard = new QStandardItem(true); + E_Standard->setCheckable(true); + if(postedEvent->msg().Info&0b1) + { + E_Standard->setCheckState(Qt::Checked); + } + else + { + E_Standard->setCheckState(Qt::Unchecked); + } + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_E_COLUMN, E_Standard); + QStandardItem *R_Standard = new QStandardItem(true); + R_Standard->setCheckable(true); + if(postedEvent->msg().Info&0b10) + { + R_Standard->setCheckState(Qt::Checked); + } + else + { + R_Standard->setCheckState(Qt::Unchecked); + } + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_R_COLUMN, R_Standard); + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_DLC_COLUMN, new QStandardItem(QString::number(postedEvent->msg().DataCount, 10))); + QString Data; + for (int j = 0; (j < postedEvent->msg().DataCount)&&!(postedEvent->msg().Info&0b10); j++) { + Data += QStringLiteral("%1").arg(postedEvent->msg().Data[j], 2, 16, QLatin1Char('0')); + if((j+1)<postedEvent->msg().DataCount) + Data += " "; + } + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_DATA_COLUMN, new QStandardItem(Data.toUpper())); + break; + } + } + if(i>=RxCanModel->rowCount()) + { + RxCanModel->insertRow(i); + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_ID_COLUMN, new QStandardItem(QStringLiteral("%1").arg(postedEvent->msg().ID, 8, 16, QLatin1Char('0')).toUpper())); + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_TIME_COLUMN, + new QStandardItem(postedEvent->time().toString("hh:mm:ss.zzz"))); + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_TMPS, new QStandardItem(QString::number(periodtmp))); + + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_COUNT_COLUMN, + new QStandardItem("1")); + QStandardItem *E_Standard = new QStandardItem(true); + + E_Standard->setCheckable(true); + if(postedEvent->msg().Info&0b1) + { + E_Standard->setCheckState(Qt::Checked); + } + else + { + E_Standard->setCheckState(Qt::Unchecked); + } + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_E_COLUMN, E_Standard); + QStandardItem *R_Standard = new QStandardItem(true); + R_Standard->setCheckable(true); + + if(postedEvent->msg().Info&0b10) + { + R_Standard->setCheckState(Qt::Checked); + } + else + { + R_Standard->setCheckState(Qt::Unchecked); + } + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_R_COLUMN, R_Standard); + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_DLC_COLUMN, new QStandardItem(QString::number(postedEvent->msg().DataCount, 10))); + + QString Data; + for (int j = 0; (j < postedEvent->msg().DataCount)&&!(postedEvent->msg().Info&0b10); j++) { + Data += QStringLiteral("%1").arg(postedEvent->msg().Data[j], 2, 16, QLatin1Char('0')); + if((j+1)<postedEvent->msg().DataCount) + Data += " "; + } + RxCanModel->setItem(i, RX_CAN_GROUP_TABLE_DATA_COLUMN, new QStandardItem(Data.toUpper())); + Data.clear(); + } + for(i = 0; i < RxCanRequesterModel->rowCount(); i++) + { + if(RxCanRequesterModel->item(i, RX_CAN_REQUESTER_GROUP_TABLE_ID_COLUMN)->text().toUInt(nullptr, 16)==postedEvent->msg().ID) + { +// Period = Period.addMSecs((QTime::fromString(RxCanRequesterModel->item(i, RX_CAN_REQUESTER_GROUP_TABLE_TIME_COLUMN)->text(), "hh:mm:ss.zzz")).msecsTo(postedEvent->time())); +// RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_PERIOD_COLUMN, +// new QStandardItem(Period.toString("hh:mm:ss.zzz"))); + + PSLCAN_TIMESTAMP per_tmp = new SLCAN_TIMESTAMP(); + per_tmp->Value = periodtmp - RxCanRequesterModel->item(i, RX_CAN_REQUESTER_GROUP_TABLE_TMPS)->text().toULongLong(nullptr, 10); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_PERIOD_COLUMN, + new QStandardItem(QString("%1:%2:%3.%4.%5").arg(QString::number(microsecondToHours(per_tmp->Value)), + QStringLiteral("%1").arg(microsecondToMinutes(per_tmp->Value), 2, 10, QLatin1Char('0')), + QStringLiteral("%1").arg(microsecondToSeconds(per_tmp->Value), 2, 10, QLatin1Char('0')), + QStringLiteral("%1").arg(microsecondToMilliseconds(per_tmp->Value), 3, 10, QLatin1Char('0')), + QStringLiteral("%1").arg(per_tmp->Value%1000, 3, 10, QLatin1Char('0'))))); + delete per_tmp; + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_TMPS, new QStandardItem(QString::number(periodtmp))); + + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_TIME_COLUMN, + new QStandardItem(postedEvent->time().toString("hh:mm:ss.zzz"))); + + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_COUNT_COLUMN, + new QStandardItem(QString::number(RxCanRequesterModel->item(i, RX_CAN_REQUESTER_GROUP_TABLE_COUNT_COLUMN)->text().toInt(nullptr, 10)+1, 10))); + + QStandardItem *E_Requester = new QStandardItem(true); + E_Requester->setCheckable(true); + if(postedEvent->msg().Info&0b1) + { + E_Requester->setCheckState(Qt::Checked); + } + else + { + E_Requester->setCheckState(Qt::Unchecked); + } + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_E_COLUMN, E_Requester); + QStandardItem *R_Requester = new QStandardItem(true); + R_Requester->setCheckable(true); + if(postedEvent->msg().Info&0b10) + { + R_Requester->setCheckState(Qt::Checked); + } + else + { + R_Requester->setCheckState(Qt::Unchecked); + } + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_R_COLUMN, R_Requester); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DLC_COLUMN, new QStandardItem(QString::number(postedEvent->msg().DataCount, 10))); + QString Data; + for (int j = 0; (j < postedEvent->msg().DataCount)&&!(postedEvent->msg().Info&0b10); j++) { + Data += QStringLiteral("%1").arg(postedEvent->msg().Data[j], 2, 16, QLatin1Char('0')); + if((j+1)<postedEvent->msg().DataCount) + Data += " "; + } + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DATA_COLUMN, new QStandardItem(Data.toUpper())); + break; + } + } + if(i>=RxCanRequesterModel->rowCount()) + { + RxCanRequesterModel->insertRow(i); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_TMPS, new QStandardItem(QString::number(periodtmp))); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_ID_COLUMN, new QStandardItem(QStringLiteral("%1").arg(postedEvent->msg().ID, 8, 16, QLatin1Char('0')).toUpper())); + QStandardItem *RxCanRoute = new QStandardItem(true); + RxCanRoute->setCheckable(true); + Requester_ID eID; + eID.ID_All = postedEvent->msg().ID; + QString datatype; + switch (eID.Standard.DataType) + { + case 0: + datatype = "Широковещательные"; + break; + case 1: + datatype = "Дискретные"; + break; + case 2: + datatype = "Аналоговые"; + break; + case 3: + datatype = "Modbus Coil"; + break; + case 4: + datatype = "Modbus Discrete"; + break; + case 5: + datatype = "Modbus Holding"; + break; + case 6: + datatype = "Modbus Input"; + break; + case 7: + datatype = "Ошибки"; + break; + case 0xF: + datatype = "Пульс"; + break; + default: + datatype = "Unknown"; + break; + } + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DATATYPE, new QStandardItem(datatype)); + datatype.clear(); + datatype.~QString(); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_SENSORID, new QStandardItem(QString::number(eID.Standard.SensorID, 16).toUpper())); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DEVICE, new QStandardItem(QString::number(eID.Standard.Device, 16).toUpper())); + QString sensortype; + switch (eID.Standard.DataType) + { + case 0: + switch (eID.Standard.SensorType) { + case 0: + sensortype = "Статус"; + break; + case 1: + sensortype = "Запрос на вкл/выкл"; + break; + case 2: + sensortype = "Рестарт устройств"; + break; + case 3: + sensortype = "Установка времени"; + break;} + break; + case 1: + switch (eID.Standard.SensorType) { + case 0: + sensortype = "Аварии"; + break; + case 1: + sensortype = "Предупреждения"; + break; + case 2: + sensortype = "Управляющие сигналы"; + break; + case 3: + sensortype = "Флаги"; + break; + case 4: + sensortype = "Рестарт устройства"; + break; + case 5: + sensortype = "Изменение режима работы устройства"; + break; + case 6: + sensortype = "Запрос перечня п-мтров на устройство"; + break;} + break; + case 2: + switch (eID.Standard.SensorType) { + case 0: + sensortype = "Универсальный запрос"; + break; + case 1: + sensortype = "Уставки"; + break; + case 2: + sensortype = "Напряжение"; + break; + case 3: + sensortype = "Ток"; + break; + case 4: + sensortype = "Температура"; + break;} + break; + case 3: + case 4: + case 5: + case 6: + sensortype = QString::number(eID.Modbus.CountReg, 10); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_SENSORID, new QStandardItem(QString::number(eID.Modbus.CountReg, 16).toUpper())); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DEVICE, new QStandardItem(QString::number(eID.Modbus.Device, 16).toUpper())); + break; + default: + break; + } + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_SENSORTYPE, new QStandardItem(sensortype)); + if(eID.Standard.Route) + { + RxCanRoute->setCheckState(Qt::Checked); + } + else + { + RxCanRoute->setCheckState(Qt::Unchecked); + } + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_ROUTE, RxCanRoute); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_TIME_COLUMN, + new QStandardItem(postedEvent->time().toString("hh:mm:ss.zzz"))); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_COUNT_COLUMN, + new QStandardItem("1")); + QStandardItem *E_Requester = new QStandardItem(true); + E_Requester->setCheckable(true); + if(postedEvent->msg().Info&0b1) + { + E_Requester->setCheckState(Qt::Checked); + } + else + { + E_Requester->setCheckState(Qt::Unchecked); + } + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_E_COLUMN, E_Requester); + + QStandardItem *R_Requester = new QStandardItem(true); + R_Requester->setCheckable(true); + if(postedEvent->msg().Info&0b10) + { + R_Requester->setCheckState(Qt::Checked); + } + else + { + R_Requester->setCheckState(Qt::Unchecked); + } + QString Data; + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_R_COLUMN, R_Requester); + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DLC_COLUMN, new QStandardItem(QString::number(postedEvent->msg().DataCount, 10))); + for (int j = 0; (j < postedEvent->msg().DataCount)&&!(postedEvent->msg().Info&0b10); j++) { + Data += QStringLiteral("%1").arg(postedEvent->msg().Data[j], 2, 16, QLatin1Char('0')); + if((j+1)<postedEvent->msg().DataCount) + Data += " "; + } + RxCanRequesterModel->setItem(i, RX_CAN_REQUESTER_GROUP_TABLE_DATA_COLUMN, new QStandardItem(Data.toUpper())); + } + ui->loggertable->resizeColumnsToContents(); + if(ui->requestBox->checkState()==Qt::Checked) + { + ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, false); + ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, true); + } + else + { + ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, true); + ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, false); + } + postedEvent->~RxCanEvent(); + event->~QEvent(); + return true; + } + return QWidget::event(event); +} + +void UnionCOM::stopCANReadThread() +{ + TimeToStopCANRead = TRUE; +} + +//Функция чтения сообщений (доступна при работе по RS). +void UnionCOM::readData() +{ + //Если идёт загрузка файла, то запускается/обновляется таймер, + //а полученные данные записываются в буффер. + if(UsartFileLoading) + { + TransferEndTimer->start(5000); + const QByteArray data = m_serial->readAll(); + BufferForLoadFile += QString(data); + } + //Стандартный приём. + else + { + const QByteArray data = m_serial->readAll(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[RX]"; + //Вывод полученного сообщения доступен в двух вариантах: символы и HEX код. + if(ui->checkRXHEX->checkState()!=Qt::Checked) + { + msg += " "; + msg += data; + } + else + { + msg += "[HEX] "; + for(int i = 0; i<data.size(); i++) + { + msg += (QString::number((byte)data[i], 16)).toUpper(); + msg += " "; + } + } + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + } +} + +//Функция обработки событий и приёма сообщений по CAN. +void UnionCOM::TimeToReadEvents() +{ + do{ + SlCan_DeviceReadEvents(device, 0, inputEvents, FRAMES, &cntrInput); + for(unsigned i = 0; i < cntrInput; i++) + { + switch(inputEvents[i].EventType) + { + case 0: //Принят CAN фрейм. + { + PSLCAN_TIMESTAMP per_t = new SLCAN_TIMESTAMP(); + SlCan_DeviceGetTimeStamp(device, per_t); + RxCanEvent* rxCanEvent = new RxCanEvent(inputEvents[i].Msg, QTime::currentTime(), per_t->Value); + QCoreApplication::postEvent(this, rxCanEvent); + delete per_t; + if(ui->checkPushMsgToLogger->checkState()==Qt::Checked) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[RX]"); + if(ui->checkRXHEX->checkState()==Qt::Checked) + { + msg += QString("[HEX]"); + } + msg += QString(" "); + if(ui->checkRXHEX->checkState()!=Qt::Checked) + { + msg += QString::fromLocal8Bit((char*)inputEvents[i].Msg.Data, inputEvents[i].Msg.DataCount); + } + else + { + for(int j = 0; j < inputEvents[i].Msg.DataCount; j++) + { + msg += QString::number((int)inputEvents[i].Msg.Data[j], 16); + msg += " "; + } + } + MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + msg.clear(); + } + break; + } + case 1: //Начата передача CAN. + { + if(ui->checkEchoMode->checkState()==Qt::Checked) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[TX]"); + if(ui->checkRXHEX->checkState()==Qt::Checked) + { + msg += QString("[HEX]"); + } + msg += QString(" "); + if(ui->checkRXHEX->checkState()==Qt::Checked) + { + for (int k = 0; k < inputEvents[i].Msg.DataCount; k++) + { + msg += QString::number(inputEvents[i].Msg.Data[k], 16); + msg += " "; + } + } + else + { + msg += QString::fromLocal8Bit((char*)inputEvents[i].Msg.Data, inputEvents[i].Msg.DataCount); + } + MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + } + break; + } + case 2: //Передача CAN фрейма успешно завершена. + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Передача успешно завершена."); + MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + break; + } + case 3: //Передача CAN фрейма отменена. + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Передача CAN фрейма отменена."); + MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + break; + } + case 4: //Изменилось состояние CAN контроллера. + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Изменилось состояние CAN контроллера."); + MyEvent* myEvent = new MyEvent(msg, GHOST_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + break; + } + case 5: //Изменилось значение одного из счётчика ошибок. + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Счётчик(-и) ошибок устройства изменился(-ись). RX: %1. TX: %2.").arg(QString::number(inputEvents[i].ErrCountRx), QString::number(inputEvents[i].ErrCountTx)); + MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + break; + } + case 6: //Произошла ошибка шины CAN. + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Произошла ошибка шины CAN."); + MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += " BUSMODE: "; + switch(inputEvents[i].BusMode) + { + case SLCAN_BUS_STATE_ERROR_ACTIVE: + msg += "SLCAN_BUS_STATE_ERROR_ACTIVE."; + break; + case SLCAN_BUS_STATE_ERROR_ACTIVE_WARN: + msg += "SLCAN_BUS_STATE_ERROR_ACTIVE_WARN."; + break; + case SLCAN_BUS_STATE_ERROR_PASSIVE: + msg += "SLCAN_BUS_STATE_ERROR_PASSIVE."; + break; + case SLCAN_BUS_STATE_BUSOFF: + msg += "SLCAN_BUS_STATE_BUSOFF."; + break; + } + msg += QString(tr(" ErrCountRX: %1.").arg(inputEvents[i].ErrCountRx)); + msg += QString(tr(" ErrCountTX: %1.").arg(inputEvents[i].ErrCountTx)); + switch(inputEvents[i].ErrType) + { + case SLCAN_EVT_ERR_TYPE_BIT: + msg += " SLCAN_EVT_ERR_TYPE_BIT."; + break; + case SLCAN_EVT_ERR_TYPE_FORM: + msg += " SLCAN_EVT_ERR_TYPE_FORM."; + break; + case SLCAN_EVT_ERR_TYPE_STUFF: + msg += " SLCAN_EVT_ERR_TYPE_STUFF."; + break; + case SLCAN_EVT_ERR_TYPE_OTHER: + msg += " SLCAN_EVT_ERR_TYPE_OTHER."; + break; + } + switch (inputEvents[i].ErrDir) { + case SLCAN_EVT_ERR_DIR_TX: + msg += " SLCAN_EVT_ERR_DIR_TX."; + break; + case SLCAN_EVT_ERR_DIR_RX: + msg += " SLCAN_EVT_ERR_DIR_RX."; + MyEvent* myEvent = new MyEvent(NULL, RX_ERROR_EVENT); + QCoreApplication::postEvent(this, myEvent); + break; + } + switch (inputEvents[i].ErrFrame){ + case SLCAN_EVT_ERR_FRAME_SOF: + msg += " SLCAN_EVT_ERR_FRAME_SOF."; + break; + case SLCAN_EVT_ERR_FRAME_ID28_ID21: + msg += " SLCAN_EVT_ERR_FRAME_ID28_ID21."; + break; + case SLCAN_EVT_ERR_FRAME_ID20_ID18: + msg += " SLCAN_EVT_ERR_FRAME_ID20_ID18."; + break; + case SLCAN_EVT_ERR_FRAME_SRTR: + msg += " SLCAN_EVT_ERR_FRAME_SRTR."; + break; + case SLCAN_EVT_ERR_FRAME_IDE: + msg += " SLCAN_EVT_ERR_FRAME_IDE."; + break; + case SLCAN_EVT_ERR_FRAME_ID17_ID13: + msg += " SLCAN_EVT_ERR_FRAME_ID17_ID13."; + break; + case SLCAN_EVT_ERR_FRAME_ID12_ID5: + msg += " SLCAN_EVT_ERR_FRAME_ID12_ID5."; + break; + case SLCAN_EVT_ERR_FRAME_ID4_ID0: + msg += " SLCAN_EVT_ERR_FRAME_ID4_ID0."; + break; + case SLCAN_EVT_ERR_FRAME_RTR: + msg += " SLCAN_EVT_ERR_FRAME_RTR."; + break; + case SLCAN_EVT_ERR_FRAME_RSRV0: + msg += " SLCAN_EVT_ERR_FRAME_RSRV0."; + break; + case SLCAN_EVT_ERR_FRAME_RSRV1: + msg += " SLCAN_EVT_ERR_FRAME_RSRV1."; + break; + case SLCAN_EVT_ERR_FRAME_DLC: + msg += " SLCAN_EVT_ERR_FRAME_DLC."; + break; + case SLCAN_EVT_ERR_FRAME_DATA: + msg += " SLCAN_EVT_ERR_FRAME_DATA."; + break; + case SLCAN_EVT_ERR_FRAME_CRC_SEQ: + msg += " SLCAN_EVT_ERR_FRAME_CRC_SEQ."; + break; + case SLCAN_EVT_ERR_FRAME_CRC_DEL: + msg += " SLCAN_EVT_ERR_FRAME_CRC_DEL."; + break; + case SLCAN_EVT_ERR_FRAME_ACK_SLOT: + msg += " SLCAN_EVT_ERR_FRAME_ACK_SLOT."; + break; + case SLCAN_EVT_ERR_FRAME_ACK_DEL: + msg += " SLCAN_EVT_ERR_FRAME_ACK_DEL."; + break; + case SLCAN_EVT_ERR_FRAME_EOF: + msg += " SLCAN_EVT_ERR_FRAME_EOF."; + break; + case SLCAN_EVT_ERR_FRAME_INTER: + msg += " SLCAN_EVT_ERR_FRAME_INTER."; + break; + case SLCAN_EVT_ERR_FRAME_AER_FLAG: + msg += " SLCAN_EVT_ERR_FRAME_AER_FLAG."; + break; + case SLCAN_EVT_ERR_FRAME_PER_FLAG: + msg += " SLCAN_EVT_ERR_FRAME_PER_FLAG."; + break; + case SLCAN_EVT_ERR_FRAME_TDB: + msg += " SLCAN_EVT_ERR_FRAME_TDB."; + break; + case SLCAN_EVT_ERR_FRAME_ERR_DEL: + msg += " SLCAN_EVT_ERR_FRAME_ERR_DEL."; + break; + case SLCAN_EVT_ERR_FRAME_OVER_FLAG: + msg += " SLCAN_EVT_ERR_FRAME_OVER_FLAG."; + break; + } + qDebug() << msg; + break; + } + case 7: //Произошла ошибка арбитража. + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Произошла ошибка арбитража."); + MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + break; + } + } + } + }while(!TimeToStopCANRead); + canReadingInThread = FALSE; +} + +////////////////// +//Загрузка файла// +////////////////// + +//QT-слот для выгрузки файла. +void UnionCOM::on_buttonLoadFile_clicked() +{ + switch (ui->cboxTypeConnection->currentIndex()) { + case 0: //CAN + { + SlCan_DevicePurge(device, SLCAN_PURGE_TX_ABORT|SLCAN_PURGE_TX_CLEAR|SLCAN_PURGE_RX_ABORT|SLCAN_PURGE_RX_CLEAR); + stopCANReadThread(); + fileName = QFileDialog::getSaveFileName(this, "Save File", "/home/", "Bin Files (*.bin);;All files (*.*)"); + if(fileName.isEmpty()) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Отмена выгрузки файла."); + qDebug()<<msg; + return; + } + SlCan_DeviceSetMode(device, SLCAN_MODE_CONFIG); + SlCan_DeviceSetBitRate(device, &br); + SlCan_DeviceSetEventLevel(device, SLCAN_EVT_LEVEL_RX_MSG); + SlCan_DeviceSetMode(device, SLCAN_MODE); + SlCan_DevicePurge(device, SLCAN_PURGE_RX_CLEAR); + clearMSG(); + QFile file(fileName); + fileName.clear(); + bool FirstRX = false; + if(file.open(QFile::WriteOnly)) + { + QString bufferToFile; + QByteArray vuffalo; + do{ + cntrInput=0; + if(FirstRX) + SlCan_DeviceReadMessages(device, READDELAY, inputMsg, FRAMES, &cntrInput); + else + { + SlCan_DeviceReadMessages(device, READDELAY, inputMsg, FRAMES, &cntrInput); + if(cntrInput==0) + { + QMessageBox msgBox; + msgBox.setText("Время ожидания вышло. Не удалось выгрузить файл."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Время ожидания вышло. Не удалось выгрузить файл."; + qDebug() << msg; + return; + } + FirstRX=TRUE; + } + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][RX] Принято пакетов: %1").arg(cntrInput); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + for(DWORD i = 0; i < cntrInput; i++) + { + for(int j = 0; j < inputMsg[i].DataCount; j++) + { + int Current = i*8+j; + vuffalo[Current] = inputMsg[i].Data[j]; + } + } + file.write(vuffalo); + vuffalo.clear(); + QCoreApplication::processEvents(); + }while(cntrInput==FRAMES); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][RX] Файл выгружен в:"); + qDebug()<<msg; + qDebug()<<file.fileName(); + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][RX] Файл выгружен."); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + file.close(); + } + else + { + QMessageBox msgBox; + msgBox.setText("Не удалось выгрузить файл."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Не удалось выгрузить файл."; + qDebug() << msg; + return; + } + SlCan_DeviceSetMode(device, SLCAN_MODE_CONFIG); + SlCan_DeviceSetBitRate(device, &br); + SlCan_DeviceSetEventLevel(device, SLCAN_EVT_LEVEL_ERRORS); + SlCan_DeviceSetMode(device, SLCAN_MODE); + TimeToStopCANRead = FALSE; + QtConcurrent::run(canReaderThread, this); + break; + } + case 1: //RS + { + fileName = QFileDialog::getSaveFileName(this, "Save File", "/home/", "Bin Files (*.bin);;All files (*.*)"); + if(fileName.isEmpty()) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Отмена выгрузки файла."); + qDebug()<<msg; + return; + } + TransferEndTimer = new QTimer(this); + TransferEndTimer->setSingleShot(TRUE); + connect(TransferEndTimer, &QTimer::timeout, this, &UnionCOM::EndOfUSARTLoadFile); + UsartFileLoading = 1; + break; + } + } +} + +//Функция, которая вызывается через 5 секунд после окончания передачи. Производится запись полученных байтов в файл. +void UnionCOM::EndOfUSARTLoadFile() +{ + UsartFileLoading=0; + if(BufferForLoadFile.isEmpty()) + { + QMessageBox msgBox; + msgBox.setText("Время ожидания вышло. Не удалось выгрузить файл."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Время ожидания вышло. Не удалось выгрузить файл."; + qDebug() << msg; + return; + } + QFile file(fileName); + fileName.clear(); + QByteArray Buffer; + Buffer.resize(BufferForLoadFile.size()); + if(file.open(QFile::WriteOnly)) + { + Buffer = BufferForLoadFile.toUtf8(); + file.write(Buffer); + file.close(); + BufferForLoadFile.clear(); + TransferEndTimer->~QTimer(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][RX] Файл выгружен в:"); + qDebug()<<msg; + qDebug()<<file.fileName(); + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][RX] Файл выгружен."); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + } + else + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Ошибка выгрузки файла: Не удалось создать и/или открыть файл.").arg(cntrInput); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug()<<msg; + } +} + +/////////////////// +//Базовые функции// +//отправки данных// +/////////////////// + +//Функция обработки ошибки при передаче. +void UnionCOM::Device_Error(PSLCAN_STATE DeviceState) +{ + //Если состояние устройства отличается от нормы: + if(DeviceState->BusMode) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Передача прервана. Устройство находится в состоянии "; + switch(DeviceState->BusMode) { + //CAN контроллер находится в состоянии ERROR ACTIVE. + //Значение одного из счетчиков ошибок больше или равно 96. + case SLCAN_BUS_STATE_ERROR_ACTIVE_WARN: + msg += "ERROR ACTIVE."; + break; + //CAN контроллер находится в состоянии ERROR PASSIVE + //Значение одного из счетчиков ошибок больше 127. + case SLCAN_BUS_STATE_ERROR_PASSIVE: + msg += "ERROR PASSIVE."; + break; + //CAN контроллер находится в состоянии BUS OFF. + //Контроллер переходит в это состояние + //при превышеии счетчика ошибок передачи значения 256. + case SLCAN_BUS_STATE_BUSOFF: + msg += "BUS OFF."; + break; + } + MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + //Очистка буфера устройства. + SlCan_DevicePurge(device, SLCAN_PURGE_TX_ABORT|SLCAN_PURGE_TX_CLEAR); + do{ + SlCan_DeviceReadEvents(device, 0, inputEvents, FRAMES, &cntrInput); + }while(cntrInput==FRAMES); + } +} + +//Функция отправки сообщения по CAN. +BYTE UnionCOM::writeMSG() +{ + BYTE WriteStatus; + //Попытка отправить сообщение. + if(SlCan_DeviceWriteMessages(device, &outMsg, 1, &WriteStatus)) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz][TX]"); + //Если при отправке сообщения возникла ошибка, то происходит вывод ошибки в логгер. + if(WriteStatus){ + TX_error_counter+=8; + ui->spinTXErrorCount->setValue(ui->spinTXErrorCount->value()+1); + switch (WriteStatus) { + case SLCAN_TX_STATUS_TIMEOUT: + msg += " Сообщения не переданы. Передача прервана из-за таймаута."; + break; + case SLCAN_TX_STATUS_BUSOFF: + msg += " Сообщения не переданы. " + "Передача прервана из-за ошибок на шине CAN и перехода CAN контроллера устройства в режим BUS OFF."; + break; + case SLCAN_TX_STATUS_ABORT: + msg += " Сообщения не переданы. Передача прервана внешней командой."; + break; + case SLCAN_TX_STATUS_NOT_ENA: + msg += " Сообщения не переданы. Передача запрещена."; + break; + case SLCAN_TX_STATUS_ERROR_ONE_SHOT: + msg += " Сообщение передавалось в режиме ONE SHOT и произошла ошибка."; + break; + case SLCAN_TX_STATUS_INVALID_MODE: + msg += " Сообщения не переданы. Режим устройства не поддерживает передачу."; + break; + case SLCAN_TX_STATUS_UNKNOWN: + msg += " Сообщения не переданы. Ошибка не известна."; + break; + } + MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + } + //Если передача прошла успешна, снижается счётчик ошибок. + else + { + if(TX_error_counter>0) TX_error_counter--; + } + //Считывается текущее состояние устройства. + SlCan_DeviceGetState(device, &DeviceState); + //Если устройство не находится в нормальном режиме работы или кол-во ошибок при отправке превышает порог, то обрабатывается ошибка устройства. + if(DeviceState.BusMode!=SLCAN_BUS_STATE_ERROR_ACTIVE && WriteStatus) + { + Device_Error(&DeviceState); + return 0x07; + } + //Выводится статус отправки сообщения. 0 - успех, остальное - ошибки. + return WriteStatus; + } + return 0x07; +} +//Функция очистки буффера сообщения по CAN. + +void UnionCOM::clearMSG() +{ + for(BYTE& byte: outMsg.Data){ + byte = 0; + } + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Очистка буффера сообщения по CAN."); + qDebug() << msg; +} + +////////////////////////////// +//Отправка команды из строки// +////////////////////////////// + +//QT-слот для обработки отправления +//сообщения(-ий) из командной строки. +void UnionCOM::on_buttonSendCMD_clicked() +{ + isTxIdle_CMD(); +} + +void UnionCOM::isTxIdle_CMD() +{ + if(isIdle) + { + //Вызов функции отправки. + startCMDTX(); + } + else + { + //Подключение функции отправки к сигналу о завершении. + QDialog *stopCurrentTX = new QDialog; + stopCurrentTX->setWindowTitle("Прервать текущую передачу?"); + stopCurrentTX->setMinimumSize(260, 50); + stopCurrentTX->setMaximumSize(260, 50); + QVBoxLayout *layoutCTX = new QVBoxLayout(stopCurrentTX); + stopCurrentTX->setLayout(layoutCTX); + QDialogButtonBox *yesOrNo = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, stopCurrentTX); + layoutCTX->addWidget(yesOrNo); + connect(yesOrNo, &QDialogButtonBox::accepted, stopCurrentTX, &QDialog::accept); + connect(yesOrNo, &QDialogButtonBox::rejected, stopCurrentTX, &QDialog::reject); + stopCurrentTX->exec(); + if(stopCurrentTX->result()==QDialog::Accepted) + { + connect(this, SIGNAL(isTxFinished()), this, SLOT(stepToStartCMDTX)); + userTXInterruption = TRUE; + } + delete stopCurrentTX; + } +} + +void UnionCOM::stepToStartCMDTX() +{ + if(userTXInterruption) + { + disconnect(this, SIGNAL(isTxFinished), this, SLOT(stepToStartCMDTX)); + userTXInterruption=FALSE; + } + startCMDTX(); +} + +void UnionCOM::startCMDTX() +{ + switch (ui->cboxTypeConnection->currentIndex()) + { + case 0: + { + QtConcurrent::run(turnOnCMDTX); + break; + } + case 1: + { + sendCMD_RS(); + break; + } + } +} + +static void turnOnCMDTX() +{ + com_target->sendCMD_CAN(); +} + +void UnionCOM::sendCMD_CAN() +{ + isIdle=FALSE; + //Считывается текст на отправку. + QString tx_data = ui->lineMSG->text(); + //Если информации для отправки нет - проходит сигнал и выход из функции. + if(tx_data.size()==0) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Пустое поле ввода."); + MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + isIdle=TRUE; + emit isTxFinished(); + return; + } + //Уведомление о начале передачи. + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Начало передачи."); + MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + //CAN + int i; + //Перевод из QString Unicod в Ascii. + QByteArray buffer = tx_data.toLocal8Bit(); + BYTE MSG_Status; + //Из строки символов формируются сообщения и отправляются. + for(i = 0; i<(tx_data.size()/8); i+=8) + { + outMsg.Data[0] = buffer[i]; + outMsg.Data[1] = buffer[i+1]; + outMsg.Data[2] = buffer[i+2]; + outMsg.Data[3] = buffer[i+3]; + outMsg.Data[4] = buffer[i+4]; + outMsg.Data[5] = buffer[i+5]; + outMsg.Data[6] = buffer[i+6]; + outMsg.Data[7] = buffer[i+7]; + //Попытка отправить сообщение. + do { + MSG_Status = writeMSG(); + //Если передать сообщение не удаётся, то происходит отмена отправки. + if (MSG_Status == 0x07 || userTXInterruption) + { + clearMSG(); + isIdle=TRUE; + emit isTxFinished(); + return; + } + } while(MSG_Status); + //Очистка буффера сообщения. + clearMSG(); + } + //Если остались символы, передаём их. + if(i!=tx_data.size()) + { + int j; + //Формируется сообщение из оставшихся символов. + for(j = 0; (j+i)<tx_data.size(); j++) + { + outMsg.Data[j]=buffer[j+i]; + } + //Задаётся количество оставшихся символов. + outMsg.DataCount = j; + //Попытка отправить сообщение. + do { + MSG_Status = writeMSG(); + //Если передать сообщение не удаётся, то происходит отмена отправки. + if (MSG_Status == 0x07 || userTXInterruption) + { + outMsg.DataCount = 8; + clearMSG(); + isIdle=TRUE; + emit isTxFinished(); + return; + } + } while(MSG_Status); + //Очистка буффера сообщения. + clearMSG(); + //Возвращение к стандартному количеству байт для отправки. + outMsg.DataCount = 8; + } + isIdle=TRUE; + emit isTxFinished(); +} + +void UnionCOM::sendCMD_RS() +{ + isIdle=FALSE; + //Считывается текст на отправку. + QString tx_data = ui->lineMSG->text(); + //Если информации для отправки нет - проходит сигнал и выход из функции. + if(tx_data.size()==0) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Пустое поле ввода."); + ui->logger->setTextColor(Qt::red); + ui->logger->append(msg); + ui->logger->setTextColor(Qt::black); + qDebug() << msg; + isIdle=TRUE; + emit isTxFinished(); + return; + } + //Уведомление о начале передачи. + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Начало передачи."); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + m_serial->write(tx_data.toUtf8(), tx_data.size()); + m_serial->waitForBytesWritten(); + if(ui->checkEchoMode->checkState()==Qt::Checked) + { + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[TX] "); + msg += tx_data; + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + } + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Передача успешно завершена."); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + isIdle=TRUE; + emit isTxFinished(); +} + +///////////////////////////// +// Отправка пакета байтов, // +//задаваемых на форме в HEX// +///////////////////////////// + +//Функция для отслеживания кол-ва отправляемых байт в команде. +void UnionCOM::on_boxDataCount_currentIndexChanged(int index) +{ + if(ui->checkHEXRTR->checkState()==Qt::Checked) + { + return; + } + index--; + for(int i = 0; i < 8; i++) + { + if(i > (index)) + { + HEXByteField[i]->setEnabled(FALSE); + } + else + { + HEXByteField[i]->setEnabled(TRUE); + } + } + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Количество байтов для отправки изменилось. Текущее количество: %1.").arg(index+1); + qDebug()<<msg; +} + +//QT-Слот для отправки 8 байт в HEX формате введённых в поля на форме. +void UnionCOM::on_buttonSendCMDHex_clicked() +{ + isTxIdle_CMDHEX(); +} + +void UnionCOM::isTxIdle_CMDHEX() +{ + if(isIdle) + { + //Вызов функции отправки + startCMDHEXTX(); + } + else + { + //Подключение функции отправки к сигналу о завершении. + QDialog *stopCurrentTX = new QDialog; + stopCurrentTX->setWindowTitle("Прервать текущую передачу?"); + stopCurrentTX->setMinimumSize(260, 50); + stopCurrentTX->setMaximumSize(260, 50); + QVBoxLayout *layoutCTX = new QVBoxLayout(stopCurrentTX); + stopCurrentTX->setLayout(layoutCTX); + QDialogButtonBox *yesOrNo = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, stopCurrentTX); + layoutCTX->addWidget(yesOrNo); + connect(yesOrNo, &QDialogButtonBox::accepted, stopCurrentTX, &QDialog::accept); + connect(yesOrNo, &QDialogButtonBox::rejected, stopCurrentTX, &QDialog::reject); + stopCurrentTX->exec(); + if(stopCurrentTX->result()==QDialog::Accepted) + { + connect(this, SIGNAL(isTxFinished), this, SLOT(stepToStartCMDHEXTX)); + userTXInterruption=TRUE; + } + delete stopCurrentTX; + } +} + +void UnionCOM::stepToStartCMDHEXTX() +{ + if(userTXInterruption) + { + disconnect(this, SIGNAL(isTxFinished), this, SLOT(stepToStartCMDHEXTX)); + userTXInterruption=FALSE; + } + startCMDHEXTX(); +} + +void UnionCOM::startCMDHEXTX() +{ + switch (ui->cboxTypeConnection->currentIndex()) + { + case 0: + { + QtConcurrent::run(turnOnCMDHEXTX); + break; + } + case 1: + { + sendCMD_RS(); + break; + } + } +} + +static void turnOnCMDHEXTX() +{ + com_target->sendCMDHEX_CAN(); +} + +void UnionCOM::sendCMDHEX_CAN() +{ + isIdle=FALSE; + int SizeOfHEXCMD = ui->boxDataCount->currentIndex(); + char tx_data[SizeOfHEXCMD]; + for(int i = 0; i < SizeOfHEXCMD; i++) + { + tx_data[i] = (BYTE)HEXByteField[i]->text().toInt(nullptr, 16); + } + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Начало передачи."); + MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + //CAN + BYTE MSG_Status; + DWORD oldID = outMsg.ID; + outMsg.ID = ui->lineHEXID->text().toInt(nullptr, 16); + BYTE oldInfo = outMsg.Info; + if(ui->checkHEXEID->checkState()==Qt::Checked) + { + outMsg.Info = oldInfo|0b1; + } + else + { + outMsg.Info = oldInfo&0b11111110; + } + if(ui->checkHEXRTR->checkState()==Qt::Checked) + { + outMsg.Info = outMsg.Info|0b10; + short oldDataCount = outMsg.DataCount; + outMsg.DataCount=SizeOfHEXCMD; + do { + MSG_Status = writeMSG(); + if (MSG_Status == 0x07 || userTXInterruption) + { + clearMSG(); + outMsg.DataCount = oldDataCount; + outMsg.ID = oldID; + outMsg.Info = oldInfo; + isIdle=TRUE; + emit isTxFinished(); + return; + } + } while(MSG_Status); + clearMSG(); + outMsg.DataCount = oldDataCount; + outMsg.ID = oldID; + outMsg.Info = oldInfo; + isIdle=TRUE; + emit isTxFinished(); + return; + } + else + { + outMsg.Info = outMsg.Info&0b11111101; + } + outMsg.DataCount=SizeOfHEXCMD; + for(int i = 0; i < SizeOfHEXCMD; i++) + { + outMsg.Data[i] = tx_data[i]; + } + do { + MSG_Status = writeMSG(); + if (MSG_Status == 0x07 || userTXInterruption) + { + clearMSG(); + outMsg.DataCount = 8; + outMsg.ID = oldID; + outMsg.Info = oldInfo; + isIdle=TRUE; + emit isTxFinished(); + return; + } + } while(MSG_Status); + clearMSG(); + outMsg.DataCount = 8; + outMsg.ID = oldID; + outMsg.Info = oldInfo; + isIdle=TRUE; + emit isTxFinished(); +} + +void UnionCOM::sendCMDHEX_RS() +{ + isIdle=FALSE; + int SizeOfHEXCMD = ui->boxDataCount->currentIndex(); + char tx_data[SizeOfHEXCMD]; + for(int i = 0; i < SizeOfHEXCMD; i++) + { + tx_data[i] = (BYTE)HEXByteField[i]->text().toInt(nullptr, 16); + } + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Начало передачи."); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + if(ui->checkEchoMode->checkState()==Qt::Checked) + { + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[TX][HEX]"); + for(int i = 0; i < SizeOfHEXCMD; i++) + { + msg += QString::number(tx_data[i], 16); + msg += " "; + } + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + } + m_serial->write(tx_data, SizeOfHEXCMD); + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Передача успешно завершена."); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + isIdle=TRUE; + emit isTxFinished(); +} + +////////////////// +//Отправка файла// +////////////////// + +//QT-слот для отправки файла. +void UnionCOM::on_buttonSendFile_clicked() +{ + isTxIdle_FILE(); +} + +void UnionCOM::isTxIdle_FILE() +{ + if(isIdle) + { + //Вызов функции отправки. + startSendFile(); + } + else + { + QDialog *stopCurrentTX = new QDialog; + stopCurrentTX->setWindowTitle("Прервать текущую передачу?"); + stopCurrentTX->setMinimumSize(260, 50); + stopCurrentTX->setMaximumSize(260, 50); + QVBoxLayout *layoutCTX = new QVBoxLayout(stopCurrentTX); + stopCurrentTX->setLayout(layoutCTX); + QDialogButtonBox *yesOrNo = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, stopCurrentTX); + layoutCTX->addWidget(yesOrNo); + connect(yesOrNo, &QDialogButtonBox::accepted, stopCurrentTX, &QDialog::accept); + connect(yesOrNo, &QDialogButtonBox::rejected, stopCurrentTX, &QDialog::reject); + stopCurrentTX->exec(); + if(stopCurrentTX->result()==QDialog::Accepted) + { + connect(this, SIGNAL(isTxFinished()), this, SLOT(stepToStartSendFile)); + userTXInterruption = TRUE; + } + delete stopCurrentTX; + } +} + +void UnionCOM::stepToStartSendFile() +{ + if(userTXInterruption) + { + disconnect(this, SIGNAL(isTxFinished), this, SLOT(stepToStartSendFile)); + userTXInterruption=FALSE; + } + startSendFile(); +} + +void UnionCOM::startSendFile() +{ + isIdle=FALSE; + //Открывается окно выбора файла. + fileName = QFileDialog::getOpenFileName(this, "Open File", "/home/", "Bin Files (*.bin);;All files (*.*)"); + //Если произошла отмена выбора, то срабатывают оповещение и выход из функции. + if(fileName.isEmpty()) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Отмена отправки файла."); + qDebug()<<msg; + isIdle=TRUE; + emit isTxFinished(); + return; + } + switch(ui->cboxTypeConnection->currentIndex()) + { + case 0: + { + QtConcurrent::run(turnOnSendFile); + break; + } + case 1: + { + sendFile_RS(); + break; + } + } +} + +static void turnOnSendFile() +{ + com_target->sendFile_CAN(); +} + +//Функция отправки файла. +void UnionCOM::sendFile_CAN() +{ + isIdle=FALSE; + QFile *file = new QFile(fileName); + fileName.clear(); + //Если открытие успешно: + if(file->open(QIODevice::ReadOnly)) + { + //Уведомление о начале передачи. + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Начало передачи."); + MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + //Считывается файл в массив байтов. + QByteArray data; + data = file->readAll(); + file->close(); + //Отправка байтов в зависимости от выбранного типа подключения. + Counter_of_suc_transmit=0; + TX_error_counter=0; + BYTE MSG_Status; + unsigned short CurrentByte=0; + //Формирование пакета и его отправка. + for(int i=0; i<data.size(); i++) + { + outMsg.Data[CurrentByte]=data[i]; + if(CurrentByte==7) + { + CurrentByte=0; + do { + MSG_Status = writeMSG(); + //Если при передаче произошла неизвестная ошибка - передача прерывается. + if (MSG_Status == 0x07 || userTXInterruption) + { + //Мб нужна какая-то "пустая" передача для завершения? + + clearMSG(); + QThread::usleep(5000); + isIdle=TRUE; + emit isTxFinished(); + return; + } + } while(MSG_Status); + clearMSG(); + } + else + { + CurrentByte++; + } + //Функция для продолжения корректной работы остального + //приложения во время выполнения трудоёмкой операции. + } + //Если после отправок пактов по 8 байт что-то осталось. + if(CurrentByte!=0) + { + outMsg.DataCount=CurrentByte; + do { + MSG_Status = writeMSG(); + if (MSG_Status == 0x07) + { + outMsg.DataCount=8; + clearMSG(); + QThread::usleep(5000); + isIdle=TRUE; + emit isTxFinished(); + return; + } + } while(MSG_Status); + clearMSG(); + } + //Возврат к стандартному количеству байт для отправки. + outMsg.DataCount=8; + //Оповещение об успешной передаче файла. + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Всего пакетов: %1. Успешно передано: %2. Ошибок передачи: %3." + ).arg(div_up(data.size(), 8)).arg(Counter_of_suc_transmit).arg(TX_error_counter); + myEvent->~MyEvent(); + myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + } + else + { + QMessageBox msgBox; + msgBox.setText("Не удалось отправить файл."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Не удалось отправить файл."; + qDebug() << msg; + isIdle=TRUE; + emit isTxFinished(); + return; + } + QThread::usleep(5000); + isIdle=TRUE; + emit isTxFinished(); +} + +void UnionCOM::sendFile_RS() +{ + isIdle=FALSE; + QFile *file = new QFile(fileName); + fileName.clear(); + if(file->open(QIODevice::ReadOnly)) + { + //Уведомление о начале передачи. + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Начало передачи."); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + //Считывается файл в массив байтов. + QByteArray data; + data = file->readAll(); + file->close(); + //Отправка файла с получением кол-ва переданных байт. + int WrittenBytes = m_serial->write(data); + //Если передано не всё, то выводится сообщение об ошибке. + if (WrittenBytes!=data.size()) + { + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Ошибка передачи. Передано: %1. Всего: %2").arg(WrittenBytes).arg(data.size()); + ui->logger->setTextColor(Qt::red); + ui->logger->append(msg); + ui->logger->setTextColor(Qt::black); + qDebug() << msg; + } + //Если всё прошло успешно, то выводится уведомление об отправке. + else + { + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Успешно передано %1 (в байтах).").arg(WrittenBytes); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + } + } + else + { + QMessageBox msgBox; + msgBox.setText("Не удалось отправить файл."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Не удалось отправить файл."; + qDebug() << msg; + delete file; + isIdle=TRUE; + emit isTxFinished(); + return; + } + delete file; + isIdle=TRUE; + emit isTxFinished(); +} + +////////////////////// +//Работа с макросами// +////////////////////// + +//Настройка макросов. +void UnionCOM::on_buttonSetMcrs_clicked() +{ + for(int i = 0; i < 15; i++) + { + MacrosMain[i].Name = McrsButtons[i]->text(); + } + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Открыто окно изменения макросов."); + qDebug()<<msg; + MacrosSetting *mcrs_w = new MacrosSetting(); + Qt::CheckState arrEID[15]; + DWORD arrID[15]; + Qt::CheckState arrRTR[15]; + Qt::CheckState arrIsHEX[15]; + int arrDLC[15]; + QString arrName[15]; + QString arrMcrs[15]; + int arrCount[15]; + Qt::CheckState arrIsPeriod[15]; + int arrPeriod[15]; + //Ввод стартовых значений. + for (int i = 0; i < 15; i++) + { + arrEID[i] = MacrosMain[i].EID; + arrID[i] = MacrosMain[i].ID; + arrRTR[i] = MacrosMain[i].RTR; + arrIsHEX[i] = MacrosMain[i].IsHEX; + arrDLC[i] = MacrosMain[i].DLC; + arrName[i] = MacrosMain[i].Name; + arrMcrs[i] = MacrosMain[i].Mcrs; + arrCount[i] = MacrosMain[i].Count; + arrIsPeriod[i] = MacrosMain[i].IsPeriod; + arrPeriod[i] = MacrosMain[i].Period; + } + mcrs_w->SetStart(arrEID, arrID, arrRTR, arrIsHEX, arrDLC, arrName, arrMcrs, arrCount, arrIsPeriod, arrPeriod); + mcrs_w->exec(); + if(mcrs_w->IsOK) + { + for (int i = 0; i < 15; i++) + { + MacrosMain[i].EID = arrEID[i]; + MacrosMain[i].ID = arrID[i]; + MacrosMain[i].RTR = arrRTR[i]; + MacrosMain[i].IsHEX = arrIsHEX[i]; + MacrosMain[i].DLC = arrDLC[i]; + MacrosMain[i].Name = arrName[i]; + MacrosMain[i].Mcrs = arrMcrs[i]; + MacrosMain[i].Count = arrCount[i]; + MacrosMain[i].IsPeriod = arrIsPeriod[i]; + MacrosMain[i].Period = arrPeriod[i]; + //Смена имени на кнопках. + if(!MacrosMain[i].Name.isEmpty()) + { + McrsButtons[i]->setText(MacrosMain[i].Name); + } + } + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Макросы были изменены."); + qDebug()<<msg; + } + else + { + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Отмена изменений макросов."); + qDebug()<<msg; + } + mcrs_w->~MacrosSetting(); +} + +//Сохранить текущий набор макросов в файл. +void UnionCOM::on_buttonSaveMcrsKit_clicked() +{ + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Сохранение макросов."); + qDebug()<<msg; + fileName = QFileDialog::getSaveFileName(this, "Save File", "/home/", "Bin Files (*.bin);;All files (*.*)"); + if(fileName.isEmpty()) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Отмена сохранения макросов."); + qDebug()<<msg; + return; + } + QFile file(fileName); + fileName.clear(); + QByteArray buffer; + if(file.open(QFile::WriteOnly)) + { + for(int i = 0; i < 15; i++) + { + buffer += MacrosMain[i].EID; + buffer += '\n'; + buffer += QString::number(MacrosMain[i].ID, 16); + buffer += '\n'; + buffer += MacrosMain[i].RTR; + buffer += '\n'; + buffer += MacrosMain[i].IsHEX; + buffer += '\n'; + buffer += QString::number(MacrosMain[i].DLC, 10); + buffer += '\n'; + buffer += MacrosMain[i].Name; + buffer += '\n'; + buffer += MacrosMain[i].Mcrs; + buffer += '\n'; + buffer += QString::number(MacrosMain[i].Count, 10); + buffer += '\n'; + buffer += MacrosMain[i].IsPeriod; + buffer += '\n'; + buffer += QString::number(MacrosMain[i].Period, 10); + buffer += '\n'; + file.write(buffer, buffer.size()); + buffer.clear(); + } + file.close(); + QMessageBox msgBox; + msgBox.setText("Файл сохранён."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Макросы сохранены в файл:"; + qDebug() << msg; + qDebug() << file.fileName(); + } + else + { + QMessageBox msgBox; + msgBox.setText("Нет доступа."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Не удалось сохранить макросы: Нет доступа."; + qDebug() << msg; + return; + } +} + +//Загрузить набор макросов из файла. +void UnionCOM::on_buttonLoadMcrsKit_clicked() +{ + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Загрузка макросов."); + qDebug()<<msg; + fileName = QFileDialog::getOpenFileName(this, "Open File", "/home/", "Bin Files (*.bin);;All files (*.*)"); + if(fileName.isEmpty()) + { + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Отмена загрузки макросов."); + qDebug()<<msg; + return; + } + QFile file(fileName); + fileName.clear(); + char buffer[MAX_MACROS_SIZE+1]; + qint64 StatusOfRead; + mcrs_kit ReadMacrosKit[15]; + if(file.open(QIODevice::ReadOnly)) + { + for(int i = 0; i < 15; i++) + { + //EID Flag + StatusOfRead = file.readLine(buffer, MAX_MACROS_EID_SIZE+2); + if(CheckFile(StatusOfRead, buffer, MAX_MACROS_EID_SIZE)) + { + return; + } + ReadMacrosKit[i].EID = (Qt::CheckState)buffer[0]; + //ID + StatusOfRead = file.readLine(buffer, MAX_MACROS_ID_SIZE+2); + if(CheckFile(StatusOfRead, buffer, MAX_MACROS_ID_SIZE)) + { + return; + } + QString subbuffer; + for(int j = 0; j < StatusOfRead-1; j++) + { + subbuffer += QString(buffer[j]); + } + ReadMacrosKit[i].ID = subbuffer.toInt(nullptr, 16); + subbuffer.clear(); + //RTR Flag + StatusOfRead = file.readLine(buffer, MAX_MACROS_RTR_SIZE+2); + if(CheckFile(StatusOfRead, buffer, MAX_MACROS_RTR_SIZE)) + { + return; + } + ReadMacrosKit[i].RTR = (Qt::CheckState)buffer[0]; + //Считывание значения HEX флага в макросе. + StatusOfRead = file.readLine(buffer, MAX_MACROS_HEX_SIZE+2); + if(CheckFile(StatusOfRead, buffer, MAX_MACROS_HEX_SIZE)) + { + return; + } + ReadMacrosKit[i].IsHEX = (Qt::CheckState)buffer[0]; + //Считывание имени макроса. + StatusOfRead = file.readLine(buffer, MAX_MACROS_NAME_SIZE+2); + if(CheckFile(StatusOfRead, buffer, MAX_MACROS_NAME_SIZE)) + { + return; + } + + StatusOfRead = file.readLine(buffer, MAX_DLC_SIZE+2); + if(CheckFile(StatusOfRead, buffer, MAX_DLC_SIZE)) + { + return; + } + for(int j = 0; j < StatusOfRead-1; j++) + { + subbuffer += QString(buffer[j]); + } + ReadMacrosKit[i].DLC = subbuffer.toInt(nullptr, 10); + subbuffer.clear(); + for(int j = 0; j < StatusOfRead-1; j++) + { + ReadMacrosKit[i].Name += QString(buffer[j]); + } + //Считывание макроса. + StatusOfRead = file.readLine(buffer, MAX_MACROS_SIZE+2); + if(CheckFile(StatusOfRead, buffer, MAX_MACROS_SIZE)) + { + return; + } + for(int j = 0; j < StatusOfRead-1; j++) + { + ReadMacrosKit[i].Mcrs += QString(buffer[j]); + } + //Считывание количества отправок. + StatusOfRead = file.readLine(buffer, MAX_MACROS_SIZE+2); + if(CheckFile(StatusOfRead, buffer, MAX_MACROS_SIZE)) + { + return; + } + for(int j = 0; j < StatusOfRead-1; j++) + { + subbuffer += QString(buffer[j]); + } + ReadMacrosKit[i].Count = subbuffer.toInt(nullptr, 10); + subbuffer.clear(); + //Считывание значение флага периода. + StatusOfRead = file.readLine(buffer, MAX_MACROS_SIZE+2); + if(CheckFile(StatusOfRead, buffer, MAX_MACROS_SIZE)) + { + return; + } + ReadMacrosKit[i].IsPeriod = (Qt::CheckState)buffer[0]; + //Считывание периода. + StatusOfRead = file.readLine(buffer, MAX_MACROS_SIZE+2); + if(CheckFile(StatusOfRead, buffer, MAX_MACROS_SIZE)) + { + return; + } + for(int j = 0; j < StatusOfRead-1; j++) + { + subbuffer += QString(buffer[j]); + } + ReadMacrosKit[i].Period = subbuffer.toInt(nullptr, 10); + subbuffer.clear(); + } + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Загрузка набора макросов из файла:"); + qDebug()<<msg; + qDebug() << file.fileName(); + file.close(); + //Если считывание файла прошло успешно - загрузка сохранённого набора макросов. + for(int i = 0; i < 15; i++) + { + MacrosMain[i].EID = ReadMacrosKit[i].EID; + MacrosMain[i].ID = ReadMacrosKit[i].ID; + MacrosMain[i].RTR = ReadMacrosKit[i].RTR; + MacrosMain[i].IsHEX = ReadMacrosKit[i].IsHEX; + MacrosMain[i].DLC = ReadMacrosKit[i].DLC; + MacrosMain[i].Name = ReadMacrosKit[i].Name; + MacrosMain[i].Mcrs = ReadMacrosKit[i].Mcrs; + MacrosMain[i].Count = ReadMacrosKit[i].Count; + MacrosMain[i].IsPeriod = ReadMacrosKit[i].IsPeriod; + MacrosMain[i].Period = ReadMacrosKit[i].Period; + if(!MacrosMain[i].Name.isEmpty()) + { + McrsButtons[i]->setText(MacrosMain[i].Name); + } + } + } + else + { + QMessageBox msgBox; + msgBox.setText("Нет доступа."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Не удалось загрузить макросы: Нет доступа."; + qDebug() << msg; + return; + } +} + +//Функция для проверки файла сохранения наборов макросов. +bool UnionCOM::CheckFile(qint64 StatusOfRead, char *buffer, qint64 MaxByteToRead) +{ + if(StatusOfRead<=0 || (StatusOfRead==(MaxByteToRead+1) && buffer[MaxByteToRead]!='\n')) + { + QMessageBox msgBox; + msgBox.setText("Файл повреждён."); + msgBox.exec(); + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += "[SYS] Не удалось загрузить макросы: Файл повреждён."; + qDebug() << msg; + return TRUE; + } + return FALSE; +} + +//Макросы. +void UnionCOM::isTxIdle_MCRS(int index) +{ + com_target->notTimeToStopPeriodMcrs[index-1] = TRUE; + if(isIdle) + { + //Вызов функции отправки. + startMCRSTX(index); + } + else + { + //Подключение функции отправки к сигналу о завершении. + QDialog *stopCurrentTX = new QDialog; + stopCurrentTX->setWindowTitle("Прервать текущую передачу?"); + stopCurrentTX->setMinimumSize(260, 50); + stopCurrentTX->setMaximumSize(260, 50); + QVBoxLayout *layoutCTX = new QVBoxLayout(stopCurrentTX); + stopCurrentTX->setLayout(layoutCTX); + QDialogButtonBox *yesOrNo = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, stopCurrentTX); + layoutCTX->addWidget(yesOrNo); + connect(yesOrNo, &QDialogButtonBox::accepted, stopCurrentTX, &QDialog::accept); + connect(yesOrNo, &QDialogButtonBox::rejected, stopCurrentTX, &QDialog::reject); + stopCurrentTX->exec(); + if(stopCurrentTX->result()==QDialog::Accepted) + { + connect(this, &UnionCOM::isTxFinished, funcptr[index]); + userTXInterruption=TRUE; + if(McrsPeriodTransfer[index-1]) + { + stopMcrs(index); + } + } + stopCurrentTX->~QDialog(); + } +} + +void UnionCOM::startMCRSTX(int index) +{ + index--; + if(userTXInterruption) + { + disconnect(this, SIGNAL(isTxFinished), this, (char*)funcptr[index]); + userTXInterruption=FALSE; + } + switch (ui->cboxTypeConnection->currentIndex()) + { + case 0: + { + turnOnMcrsTX(index); + break; + } + case 1: + { + pushMcrs_RS(index); + break; + } + } + //Если макрос имеет свойство периодичности, то запускается таймер, + //который повторит отправку макроса через заданный период. + if(MacrosMain[index].IsPeriod==Qt::Checked && notTimeToStopPeriodMcrs[index]) + { + McrsStopButtons[index]->setEnabled(TRUE); + McrsPeriodTransfer[index]->start(MacrosMain[index].Period); + } +} + +static void turnOnMcrsTX(int index) +{ + com_target->pushMcrs_CAN(index); +} + +static void stepToStartMCRS1() +{ + com_target->startMCRSTX(1); +} +static void stepToStartMCRS2() +{ + com_target->startMCRSTX(2); +} +static void stepToStartMCRS3() +{ + com_target->startMCRSTX(3); +} +static void stepToStartMCRS4() +{ + com_target->startMCRSTX(4); +} +static void stepToStartMCRS5() +{ + com_target->startMCRSTX(5); +} +static void stepToStartMCRS6() +{ + com_target->startMCRSTX(6); +} +static void stepToStartMCRS7() +{ + com_target->startMCRSTX(7); +} +static void stepToStartMCRS8() +{ + com_target->startMCRSTX(8); +} +static void stepToStartMCRS9() +{ + com_target->startMCRSTX(9); +} +static void stepToStartMCRS10() +{ + com_target->startMCRSTX(10); +} +static void stepToStartMCRS11() +{ + com_target->startMCRSTX(11); +} +static void stepToStartMCRS12() +{ + com_target->startMCRSTX(12); +} +static void stepToStartMCRS13() +{ + com_target->startMCRSTX(13); +} +static void stepToStartMCRS14() +{ + com_target->startMCRSTX(14); +} +static void stepToStartMCRS15() +{ + com_target->startMCRSTX(15); +} + +//Отправка макроса. +void UnionCOM::pushMcrs_CAN(int index) +{ + if(!notTimeToStopPeriodMcrs[index]) + { + emit isTxFinished(); + return; + } + isIdle=FALSE; + if(MacrosMain[index].Mcrs.size()==0 && MacrosMain[index].RTR!=Qt::Checked) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Макрос не задан."); + MyEvent* myEvent = new MyEvent(msg, WARNING_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + isIdle=TRUE; + emit isTxFinished(); + return; + } + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Начало передачи."); + MyEvent* myEvent = new MyEvent(msg, NORMAL_MSG_TO_LOGGER); + QCoreApplication::postEvent(this, myEvent); + qDebug() << msg; + BYTE MSG_Status; + DWORD oldID = outMsg.ID; + outMsg.ID = MacrosMain[index].ID; + BYTE oldInfo = outMsg.Info; + if(MacrosMain[index].EID==Qt::Checked) + { + outMsg.Info = oldInfo|0b1; + } + else + { + outMsg.Info = oldInfo&0b11111110; + } + if(MacrosMain[index].RTR==Qt::Checked) + { + outMsg.Info = outMsg.Info|0b10; + short oldDataCount = outMsg.DataCount; + outMsg.DataCount=MacrosMain[index].DLC; + do { + MSG_Status = writeMSG(); + if (MSG_Status == 0x07 || userTXInterruption) + { + if(MacrosMain[index].IsPeriod==Qt::Checked) + stopMcrs(index+1); + clearMSG(); + outMsg.DataCount = oldDataCount; + outMsg.ID = oldID; + outMsg.Info = oldInfo; + isIdle=TRUE; + emit isTxFinished(); + return; + } + } while(MSG_Status); + clearMSG(); + outMsg.DataCount = oldDataCount; + outMsg.ID = oldID; + outMsg.Info = oldInfo; + isIdle=TRUE; + emit isTxFinished(); + return; + } + else + { + outMsg.Info = outMsg.Info&0b11111101; + } + QByteArray buffer; + if(MacrosMain[index].IsHEX) + { + QString oldMcrs = MacrosMain[index].Mcrs; + MacrosMain[index].Mcrs = MacrosMain[index].Mcrs.replace(" ", ""); + if(MacrosMain[index].Mcrs.size()%2) + { + MacrosMain[index].Mcrs = "0" + MacrosMain[index].Mcrs; + } + QString Subbuff; + for(int i = 0; i < MacrosMain[index].Mcrs.size()-1; i+=2) + { + Subbuff = MacrosMain[index].Mcrs[i]; + Subbuff += MacrosMain[index].Mcrs[i+1]; + buffer += Subbuff.toInt(nullptr, 16); + } + MacrosMain[index].Mcrs = oldMcrs; + } + else + { + buffer += MacrosMain[index].Mcrs.toLocal8Bit(); + } + //CAN + for(int TX_Counter = 0; TX_Counter<MacrosMain[index].Count; TX_Counter++) + { + int i; + for(i = 0; i<(buffer.size()/8); i+=8) + { + outMsg.Data[0] = buffer[i]; + outMsg.Data[1] = buffer[i+1]; + outMsg.Data[2] = buffer[i+2]; + outMsg.Data[3] = buffer[i+3]; + outMsg.Data[4] = buffer[i+4]; + outMsg.Data[5] = buffer[i+5]; + outMsg.Data[6] = buffer[i+6]; + outMsg.Data[7] = buffer[i+7]; + do { + MSG_Status = writeMSG(); + if (MSG_Status == 0x07 || userTXInterruption) + { + if(MacrosMain[index].IsPeriod==Qt::Checked) + stopMcrs(index+1); + clearMSG(); + outMsg.ID = oldID; + outMsg.Info = oldInfo; + isIdle=TRUE; + emit isTxFinished(); + return; + } + } while(MSG_Status); + clearMSG(); + } + //Если остались символы, передаём их. + if(i!=buffer.size()) + { + int j; + for(j = 0; (j+i)<buffer.size(); j++) + { + outMsg.Data[j]=buffer[j+i]; + } + outMsg.DataCount = j; + do { + MSG_Status = writeMSG(); + if (MSG_Status == 0x07 || userTXInterruption) + { + if(MacrosMain[index].IsPeriod==Qt::Checked) + stopMcrs(index+1); + clearMSG(); + outMsg.ID = oldID; + outMsg.Info = oldInfo; + isIdle=TRUE; + emit isTxFinished(); + return; + } + } while(MSG_Status); + clearMSG(); + outMsg.DataCount = 8; + } + } + outMsg.ID = oldID; + outMsg.Info = oldInfo; + isIdle=TRUE; + emit isTxFinished(); +} + +void UnionCOM::pushMcrs_RS(int index) +{ + isIdle=FALSE; + if(MacrosMain[index].Mcrs.size()==0) + { + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS] Макрос не задан."); + ui->logger->setTextColor(Qt::red); + ui->logger->append(msg); + ui->logger->setTextColor(Qt::black); + qDebug() << msg; + isIdle=TRUE; + emit isTxFinished(); + return; + } + QString msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Начало передачи."); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + QByteArray buffer; + if(MacrosMain[index].IsHEX) + { + QString Subbuff; + for(int i = 0; i < MacrosMain[index].Mcrs.size()-1; i+=2) + { + Subbuff = MacrosMain[index].Mcrs[i]; + Subbuff += MacrosMain[index].Mcrs[i+1]; + buffer += Subbuff.toInt(nullptr, 16); + } + } + else + { + buffer += MacrosMain[index].Mcrs; + } + for(int TX_Counter = 0; TX_Counter<MacrosMain[index].Count; TX_Counter++) + { + m_serial->write(buffer, buffer.size()); + if(ui->checkEchoMode->checkState()==Qt::Checked) + { + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[TX] "); + msg += buffer; + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + } + } + msg = QTime::currentTime().toString("[hh:mm:ss.zzz]"); + msg += QString("[SYS][TX] Передача успешно завершена."); + ui->logger->setTextColor(Qt::black); + ui->logger->append(msg); + qDebug() << msg; + isIdle=TRUE; + emit isTxFinished(); +} + +//Остановка переодического макроса. +void UnionCOM::stopMcrs(int index) +{ + index--; + McrsPeriodTransfer[index]->stop(); + notTimeToStopPeriodMcrs[index]=FALSE; + McrsStopButtons[index]->setEnabled(FALSE); +} + +void UnionCOM::on_buttonRXErrorCountErase_clicked() +{ + ui->spinRXErrorCount->setValue(0); + rxErrorTimer_clear(); +} + +void UnionCOM::on_buttonTXErrorCountErase_clicked() +{ + ui->spinTXErrorCount->setValue(0); + txErrorTimer_clear(); +} + +void UnionCOM::on_buttonCRC_clicked() +{ + CRC16 *crc_widget = new CRC16(nullptr); + crc_widget->setWindowTitle("CRC Calc"); + crc_widget->show(); +} + +void UnionCOM::on_checkHEXRTR_stateChanged(int arg1) +{ + bool flag; + if(ui->checkHEXRTR->checkState()==Qt::Checked) + { + flag = false; + } + else + { + flag = true; + } + for(int i = 0; i < 8; i++) + { + if(flag && (ui->boxDataCount->currentIndex()>=(i+1))) + { + HEXByteField[i]->setEnabled(flag); + } + else + { + HEXByteField[i]->setEnabled(false); + } + } +} + +void UnionCOM::on_checkHEXEID_stateChanged(int arg1) +{ + if(ui->checkHEXEID->checkState()==Qt::Checked) + { + ui->lineHEXID->setInputMask(">HHHHHHHH"); + } + else + { + ui->lineHEXID->setInputMask(">HHH"); + } +} + +void UnionCOM::on_lineHEXID_textChanged(const QString &arg1) +{ + QString buffer = QString::number(ui->lineHEXID->text().toUInt(nullptr, 16), 10); + int pos = 0; + unsigned long long maxRange; + if(ui->checkHEXEID->checkState()==Qt::Checked) + { + maxRange = 0x1FFFFFFF; + } + else + { + maxRange = 0x7FF; + } + if((unsigned long long)buffer.toUInt(nullptr, 10) > (unsigned long long) maxRange) + { + ui->lineHEXID->setStyleSheet("border: 1px solid red"); + ui->lineHEXID->setToolTip(QString("Valid ID: 0 - 0x%1").arg(QString::number(maxRange, 16).toUpper())); + ui->buttonSendCMDHex->setEnabled(false); + } + else + { + ui->lineHEXID->setStyleSheet(""); + ui->lineHEXID->setToolTip(QString()); + ui->buttonSendCMDHex->setEnabled(true); + } +} +#include "canidcalc.h" + +void UnionCOM::on_pushButton_clicked() +{ + CanIdCalc *CAN_ID_Calc = new CanIdCalc(nullptr); + CAN_ID_Calc->setWindowTitle("CAN ID Calc"); + CAN_ID_Calc->show(); +} + +void UnionCOM::tableInit() +{ + ui->loggertable->setSortingEnabled(true); + + RxCanModel = new QStandardItemModel(0, 9); + { + RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_COUNT_COLUMN, Qt::Horizontal, "Count"); + RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_TIME_COLUMN, Qt::Horizontal, "Time, h:m:s.ms"); + RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_PERIOD_COLUMN, Qt::Horizontal, "Period, h:m:s.ms.us"); + RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_ID_COLUMN, Qt::Horizontal, "ID (hex)"); + RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_E_COLUMN, Qt::Horizontal, "E"); + RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_R_COLUMN, Qt::Horizontal, "R"); + RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_DLC_COLUMN, Qt::Horizontal, "DLC"); + RxCanModel->setHeaderData(RX_CAN_GROUP_TABLE_DATA_COLUMN, Qt::Horizontal, "Data (hex)"); + } + RxCanRequesterModel = new QStandardItemModel(0, 14); + { + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_COUNT_COLUMN, Qt::Horizontal, "Count"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_TIME_COLUMN, Qt::Horizontal, "Time, h:m:s.ms"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_PERIOD_COLUMN, Qt::Horizontal, "Period, h:m:s.ms.us"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_ID_COLUMN, Qt::Horizontal, "ID (hex)"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_ROUTE, Qt::Horizontal, "Route"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_DATATYPE, Qt::Horizontal, "DataType"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_SENSORTYPE, Qt::Horizontal, "SensorType"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_SENSORID, Qt::Horizontal, "SensorID"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_DEVICE, Qt::Horizontal, "Device"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_E_COLUMN, Qt::Horizontal, "E"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_R_COLUMN, Qt::Horizontal, "R"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_DLC_COLUMN, Qt::Horizontal, "DLC"); + RxCanRequesterModel->setHeaderData(RX_CAN_REQUESTER_GROUP_TABLE_DATA_COLUMN, Qt::Horizontal, "Data (hex)"); + } + if(ui->requestBox->checkState()==Qt::Checked) + { + ui->loggertable->setModel(RxCanRequesterModel); + ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, false); + ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, true); + } + else + { + ui->loggertable->setModel(RxCanModel); + ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, true); + ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, false); + } +} + +void UnionCOM::on_requestBox_stateChanged(int arg1) +{ + switch (arg1) { + case Qt::Unchecked: + ui->loggertable->setModel(RxCanModel); + ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, true); + ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, false); + break; + case Qt::Checked: + ui->loggertable->setModel(RxCanRequesterModel); + ui->loggertable->setColumnHidden(RX_CAN_GROUP_TABLE_TMPS, false); + ui->loggertable->setColumnHidden(RX_CAN_REQUESTER_GROUP_TABLE_TMPS, true); + break; + } + ui->loggertable->resizeColumnsToContents(); +} diff --git a/unioncom.h b/unioncom.h new file mode 100644 index 0000000..93bb486 --- /dev/null +++ b/unioncom.h @@ -0,0 +1,316 @@ +#ifndef UNIONCOM_H +#define UNIONCOM_H + +#include <QWidget> +#include <QStandardItemModel> +#include <QTableWidgetItem> + +#include "ProjectSettings.h" +#include "ui_unioncom.h" + +#include <QEvent> + +#define microsecondToMilliseconds(x) x/1000%1000 +#define microsecondToSeconds(x) x/1000/1000%60 +#define microsecondToMinutes(x) x/1000/1000/60%60 +#define microsecondToHours(x) x/1000/1000/60/60 + +extern "C" __declspec(dllexport) QWidget* init(QWidget *parent); + +class MyEvent : public QEvent +{ +public: + MyEvent(const QString& message, const short msgType) : QEvent(QEvent::User) {_message = message; _msgType = msgType;} + ~MyEvent() {} + + QString message() const {return _message;} + short msgType() const {return _msgType;} + +private: + QString _message; + short _msgType; +}; + +namespace Ui { +class UnionCOM; +} + +class RxCanEvent : public QEvent +{ +public: + static const QEvent::Type EventType = static_cast<QEvent::Type>(2000); + RxCanEvent(const SLCAN_MESSAGE& msg, const QTime timeEvent, const unsigned long long time_stamp) : QEvent(RxCanEvent::EventType) {_msg = msg; _time = timeEvent; _time_stamp = time_stamp;} + ~RxCanEvent(){} + + SLCAN_MESSAGE msg() const {return _msg;} + QTime time() const {return _time;} + unsigned long long time_stamp() const {return _time_stamp;} + +private: + SLCAN_MESSAGE _msg; + QTime _time; + unsigned long long _time_stamp; +}; + +class UnionCOM : public QWidget +{ + Q_OBJECT + +public: + struct mcrs_kit{ + Qt::CheckState EID; + DWORD ID; + Qt::CheckState RTR; + Qt::CheckState IsHEX; + byte DLC; + QString Name; + QString Mcrs; + int Count; + Qt::CheckState IsPeriod; + int Period; + } MacrosMain[15]; + bool InitMcrsSetting = TRUE; + DWORD ID; //идентификатор устройства + SLCAN_MESSAGE outMsg; //буфер для отправки сообщения + SLCAN_MESSAGE inputMsg[FRAMES]; //буфер для приёма сообщения + SLCAN_EVENT inputEvents[FRAMES]; + HSLCAN device; + SLCAN_BITRATE br; + DWORD cntrInput; + + SLCAN_STATE DeviceState; + + void Connect_Notification(); + void Disconnect_Notification(); + void Emergency_Disconnect_Notification(); + + void AfterDisconnection(); + void AfterConnection(); + + void pushMcrs_CAN(int index); + + void sendCMD_CAN(); + void sendCMDHEX_CAN(); + void sendFile_CAN(); + + void pushMcrs_RS(int index); + + void sendCMD_RS(); + void sendCMDHEX_RS(); + void sendFile_RS(); + + void TimeToReadEvents(); + + void gotors(); + + explicit UnionCOM(QWidget *parent = nullptr); + ~UnionCOM(); + void startMCRSTX(int index); + + bool TimeToStopCANRead; + bool canReadingInThread; + void stopCANReadThread(); + + bool notTimeToStopPeriodMcrs[15]; +private slots: + void rxErrorTimer_anotherSec(); + void txErrorTimer_anotherSec(); + + void on_cboxTypeConnection_currentIndexChanged(int index); + + void on_buttonConnect_clicked(); + + void on_buttonDisconnect_clicked(); + + void on_buttonSendCMD_clicked(); + + void on_buttonSendCMDHex_clicked(); + + void on_buttonSendFile_clicked(); + +// void on_buttonSDCard_clicked(); + +// void on_buttonReturnToBootloader_clicked(); + + void on_buttonLoadFile_clicked(); + + void on_boxDataCount_currentIndexChanged(int index); + + void on_buttonSetMcrs_clicked(); + + void on_buttonStopMacros_01_clicked() {stopMcrs(1);}; + void on_buttonStopMacros_02_clicked() {stopMcrs(2);}; + void on_buttonStopMacros_03_clicked() {stopMcrs(3);}; + void on_buttonStopMacros_04_clicked() {stopMcrs(4);}; + void on_buttonStopMacros_05_clicked() {stopMcrs(5);}; + void on_buttonStopMacros_06_clicked() {stopMcrs(6);}; + void on_buttonStopMacros_07_clicked() {stopMcrs(7);}; + void on_buttonStopMacros_08_clicked() {stopMcrs(8);}; + void on_buttonStopMacros_09_clicked() {stopMcrs(9);}; + void on_buttonStopMacros_10_clicked() {stopMcrs(10);}; + void on_buttonStopMacros_11_clicked() {stopMcrs(11);}; + void on_buttonStopMacros_12_clicked() {stopMcrs(12);}; + void on_buttonStopMacros_13_clicked() {stopMcrs(13);}; + void on_buttonStopMacros_14_clicked() {stopMcrs(14);}; + void on_buttonStopMacros_15_clicked() {stopMcrs(15);}; + + + void on_buttonMacros_01_clicked() {isTxIdle_MCRS(1);}; + void on_buttonMacros_02_clicked() {isTxIdle_MCRS(2);}; + void on_buttonMacros_03_clicked() {isTxIdle_MCRS(3);}; + void on_buttonMacros_04_clicked() {isTxIdle_MCRS(4);}; + void on_buttonMacros_05_clicked() {isTxIdle_MCRS(5);}; + void on_buttonMacros_06_clicked() {isTxIdle_MCRS(6);}; + void on_buttonMacros_07_clicked() {isTxIdle_MCRS(7);}; + void on_buttonMacros_08_clicked() {isTxIdle_MCRS(8);}; + void on_buttonMacros_09_clicked() {isTxIdle_MCRS(9);}; + void on_buttonMacros_10_clicked() {isTxIdle_MCRS(10);}; + void on_buttonMacros_11_clicked() {isTxIdle_MCRS(11);}; + void on_buttonMacros_12_clicked() {isTxIdle_MCRS(12);}; + void on_buttonMacros_13_clicked() {isTxIdle_MCRS(13);}; + void on_buttonMacros_14_clicked() {isTxIdle_MCRS(14);}; + void on_buttonMacros_15_clicked() {isTxIdle_MCRS(15);}; + + void on_buttonSaveMcrsKit_clicked(); + + void on_buttonLoadMcrsKit_clicked(); + + void on_buttonClearLogger_clicked(); + + + void on_checkModbusEnabled_stateChanged(int arg1); + + void stepToStartCMDTX(); + void stepToStartCMDHEXTX(); + void stepToStartSendFile(); + + void on_buttonRXErrorCountErase_clicked(); + + void on_buttonTXErrorCountErase_clicked(); + + void appendToLogger(QString msgToLogger); + + void on_buttonCRC_clicked(); + + void on_checkHEXRTR_stateChanged(int arg1); + + void on_checkHEXEID_stateChanged(int arg1); + + void on_lineHEXID_textChanged(const QString &arg1); + + void on_pushButton_clicked(); + + void on_requestBox_stateChanged(int arg1); + +signals: + void isTxFinished(); + void notifToLogger(QString msgToLogger); + +private: + QString errors_RS(int ConnectionError); + + bool event(QEvent* event); + + int OldCountOfRXError = 0; + int OldCountOfTXError = 0; + + short counterOfLoggerMSG = 0; + void deleteTopLine(); + + int SLCAN_MODE; + void isTxIdle_MCRS(int index); + void isTxIdle_CMD(); + void isTxIdle_CMDHEX(); + void isTxIdle_FILE(); + + void startSendFile(); + void startCMDTX(); + void startCMDHEXTX(); + + + bool isIdle = TRUE; + bool userTXInterruption = FALSE; + + void stopMcrs(int index); + + + void (UnionCOM::*ptrButtonMcrs[15])(){&UnionCOM::on_buttonMacros_01_clicked, + &UnionCOM::on_buttonMacros_02_clicked, &UnionCOM::on_buttonMacros_03_clicked, + &UnionCOM::on_buttonMacros_04_clicked, &UnionCOM::on_buttonMacros_05_clicked, + &UnionCOM::on_buttonMacros_06_clicked, &UnionCOM::on_buttonMacros_07_clicked, + &UnionCOM::on_buttonMacros_08_clicked, &UnionCOM::on_buttonMacros_09_clicked, + &UnionCOM::on_buttonMacros_10_clicked, &UnionCOM::on_buttonMacros_11_clicked, + &UnionCOM::on_buttonMacros_12_clicked, &UnionCOM::on_buttonMacros_13_clicked, + &UnionCOM::on_buttonMacros_14_clicked, &UnionCOM::on_buttonMacros_15_clicked}; + + bool CheckFile(qint64 StatusOfRead, char *buffer, qint64 MaxByteToRead); + + unsigned int Counter_of_suc_transmit=0; + unsigned int TX_error_counter = 0; + + QLineEdit *HEXByteField[8]; + + QPushButton *McrsButtons[15]; + QPushButton *McrsStopButtons[15]; + + void readData(); + + QTimer *TimerReadEvents; + QTimer *TransferEndTimer; + QTimer *McrsPeriodTransfer[15]; + QTimer *timeFromTXErrorClear; + QTimer *timeFromRXErrorClear; + + void rxErrorTimer_clear(); + void txErrorTimer_clear(); + + BOOL UsartFileLoading = 0; + + QString fileName; + QString BufferForLoadFile; + + void EndOfUSARTLoadFile(); + + + void clearMSG(); + BYTE writeMSG(); + void Device_Error(PSLCAN_STATE DeviceState); + void openCAN(); + + void Init(); + void SettingWidget(); + void openSerialPort(); + + QLabel *m_status = nullptr; + QSerialPort *m_serial = nullptr; + + + void tableInit(); + + QStandardItemModel* RxCanModel; + QStandardItemModel* RxCanRequesterModel; + + union Requester_ID{ + struct RequesterStandardID + { + uint Device:8; + uint SensorID:11; + uint SensorType:5; + uint DataType:4; + uint Route:1; + }Standard; + struct RequesterModbusID + { + uint Device:8; + uint CountReg:8; + uint StrAdr:8; + uint DataType:4; + uint Route:1; + }Modbus; + uint ID_All:29; + }RequesterID; + + Ui::UnionCOM *ui; +}; + +#endif // UNIONCOM_H diff --git a/unioncom.ui b/unioncom.ui new file mode 100644 index 0000000..d291649 --- /dev/null +++ b/unioncom.ui @@ -0,0 +1,3197 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>UnionCOM</class> + <widget class="QWidget" name="UnionCOM"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>1180</width> + <height>865</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>1180</width> + <height>865</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>16777215</height> + </size> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QFrame" name="maingridFrame"> + <layout class="QGridLayout" name="mainLayout"> + <item row="1" column="4"> + <spacer name="horizontalSpacer_8"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="3"> + <widget class="QFrame" name="loggergridFrame"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <layout class="QGridLayout" name="loggerLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="5" column="0"> + <widget class="QFrame" name="TXgridFrame"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>250</width> + <height>300</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>300</height> + </size> + </property> + <layout class="QGridLayout" name="TXLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="1" column="0"> + <spacer name="verticalSpacer_10"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="0"> + <widget class="QGroupBox" name="CMDGroupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>500</width> + <height>130</height> + </size> + </property> + <property name="title"> + <string>TX</string> + </property> + <layout class="QGridLayout" name="SinglCMDLayout"> + <property name="leftMargin"> + <number>3</number> + </property> + <property name="topMargin"> + <number>3</number> + </property> + <property name="rightMargin"> + <number>3</number> + </property> + <property name="bottomMargin"> + <number>3</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="1"> + <widget class="QLineEdit" name="lineMSG"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string/> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QPushButton" name="buttonSendCMD"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Отправить</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <spacer name="horizontalSpacer_17"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="1"> + <spacer name="verticalSpacer_7"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1"> + <widget class="QGroupBox" name="TXButtonsGroupBox"> + <property name="title"> + <string>Macros</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + <layout class="QGridLayout" name="TXButtonsLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="5" column="1"> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1" colspan="3"> + <widget class="QPushButton" name="buttonSetMcrs"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Задать макросы</string> + </property> + </widget> + </item> + <item row="2" column="4"> + <spacer name="horizontalSpacer_29"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="6"> + <spacer name="horizontalSpacer_30"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="9"> + <widget class="QPushButton" name="buttonSaveMcrsKit"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Сохранить</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <spacer name="horizontalSpacer_16"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="7"> + <widget class="QPushButton" name="buttonLoadMcrsKit"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Открыть</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0"> + <spacer name="horizontalSpacer_14"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="10"> + <spacer name="horizontalSpacer_15"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="7" column="1"> + <spacer name="verticalSpacer_4"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="8"> + <spacer name="horizontalSpacer_31"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <spacer name="verticalSpacer_5"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1"> + <layout class="QGridLayout" name="layoutMacros_01"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_01"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M01</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_01"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </item> + <item row="2" column="3"> + <layout class="QGridLayout" name="layoutMacros_02"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_02"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M02</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_02"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="2" column="5"> + <layout class="QGridLayout" name="layoutMacros_03"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_03"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M03</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_03"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="2" column="7"> + <layout class="QGridLayout" name="layoutMacros_04"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_04"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M04</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_04"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="2" column="9"> + <layout class="QGridLayout" name="layoutMacros_05"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_05"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M05</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_05"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="4" column="1"> + <layout class="QGridLayout" name="layoutMacros_06"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_06"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M06</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_06"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="4" column="3"> + <layout class="QGridLayout" name="layoutMacros_07"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_07"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M07</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_07"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="4" column="5"> + <layout class="QGridLayout" name="layoutMacros_08"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_08"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M08</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_08"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="4" column="7"> + <layout class="QGridLayout" name="layoutMacros_09"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_09"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M09</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_09"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="4" column="9"> + <layout class="QGridLayout" name="layoutMacros_10"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_10"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M10</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_10"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="6" column="1"> + <layout class="QGridLayout" name="layoutMacros_11"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_11"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M11</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_11"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="6" column="3"> + <layout class="QGridLayout" name="layoutMacros_12"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_12"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M12</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_12"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="6" column="5"> + <layout class="QGridLayout" name="layoutMacros_13"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_13"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M13</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_13"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="6" column="7"> + <layout class="QGridLayout" name="layoutMacros_14"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_14"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M14</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_14"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="6" column="9"> + <layout class="QGridLayout" name="layoutMacros_15"> + <item row="0" column="0"> + <widget class="QPushButton" name="buttonMacros_15"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>45</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>M15</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonStopMacros_15"> + <property name="minimumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>35</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Стоп</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item row="0" column="3"> + <spacer name="horizontalSpacer_18"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="2"> + <widget class="QPushButton" name="buttonSendCMDHex"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Отправить</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QGroupBox" name="CMDHEXLayout"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>200</width> + <height>80</height> + </size> + </property> + <property name="title"> + <string>HEX</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + <layout class="QGridLayout" name="HEXCMDLayout"> + <property name="spacing"> + <number>0</number> + </property> + <item row="0" column="19"> + <spacer name="horizontalSpacer_23"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="5"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>RTR</string> + </property> + </widget> + </item> + <item row="0" column="7"> + <widget class="QComboBox" name="boxDataCount"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>40</width> + <height>16777215</height> + </size> + </property> + <property name="currentIndex"> + <number>8</number> + </property> + <item> + <property name="text"> + <string>0</string> + </property> + </item> + <item> + <property name="text"> + <string>1</string> + </property> + </item> + <item> + <property name="text"> + <string>2</string> + </property> + </item> + <item> + <property name="text"> + <string>3</string> + </property> + </item> + <item> + <property name="text"> + <string>4</string> + </property> + </item> + <item> + <property name="text"> + <string>5</string> + </property> + </item> + <item> + <property name="text"> + <string>6</string> + </property> + </item> + <item> + <property name="text"> + <string>7</string> + </property> + </item> + <item> + <property name="text"> + <string>8</string> + </property> + </item> + </widget> + </item> + <item row="0" column="13"> + <spacer name="horizontalSpacer_20"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="3"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>ID</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="0" column="25"> + <spacer name="horizontalSpacer_27"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="23"> + <spacer name="horizontalSpacer_25"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="18"> + <widget class="QLineEdit" name="HEXByte_4"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="text"> + <string/> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="1" column="10"> + <widget class="QLabel" name="labelHEX0"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>1</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QCheckBox" name="checkHEXEID"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string/> + </property> + <property name="iconSize"> + <size> + <width>16</width> + <height>16</height> + </size> + </property> + </widget> + </item> + <item row="0" column="12"> + <widget class="QLineEdit" name="HEXByte_1"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="text"> + <string/> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="1" column="16"> + <widget class="QLabel" name="labelHEX3"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>4</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="0" column="0"> + <spacer name="horizontalSpacer_26"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="7"> + <widget class="QLabel" name="labelByteCount"> + <property name="text"> + <string>Count</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="1" column="18"> + <widget class="QLabel" name="labelHEX4"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>5</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>EID</string> + </property> + </widget> + </item> + <item row="0" column="24"> + <widget class="QLineEdit" name="HEXByte_7"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="text"> + <string/> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="14"> + <widget class="QLineEdit" name="HEXByte_2"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="text"> + <string/> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="16"> + <widget class="QLineEdit" name="HEXByte_3"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="text"> + <string/> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <spacer name="horizontalSpacer_40"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="12"> + <widget class="QLabel" name="labelHEX1"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>2</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="1" column="20"> + <widget class="QLabel" name="labelHEX5"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>6</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="0" column="20"> + <widget class="QLineEdit" name="HEXByte_5"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="text"> + <string/> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="15"> + <spacer name="horizontalSpacer_21"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="21"> + <spacer name="horizontalSpacer_24"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="22"> + <widget class="QLabel" name="labelHEX6"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>7</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="0" column="22"> + <widget class="QLineEdit" name="HEXByte_6"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="text"> + <string/> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="5"> + <widget class="QCheckBox" name="checkHEXRTR"> + <property name="styleSheet"> + <string notr="true"/> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="0" column="10"> + <widget class="QLineEdit" name="HEXByte_0"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>hh</string> + </property> + <property name="text"> + <string/> + </property> + <property name="maxLength"> + <number>2</number> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="placeholderText"> + <string>00</string> + </property> + </widget> + </item> + <item row="0" column="4"> + <spacer name="horizontalSpacer_41"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="14"> + <widget class="QLabel" name="labelHEX2"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>3</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLineEdit" name="lineHEXID"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>80</width> + <height>25</height> + </size> + </property> + <property name="inputMask"> + <string>>HHH</string> + </property> + </widget> + </item> + <item row="0" column="8"> + <spacer name="horizontalSpacer_28"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="11"> + <spacer name="horizontalSpacer_19"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="17"> + <spacer name="horizontalSpacer_22"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="24"> + <widget class="QLabel" name="labelHEX7"> + <property name="maximumSize"> + <size> + <width>25</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>8</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="0" column="6"> + <spacer name="horizontalSpacer_42"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="1" column="0"> + <spacer name="horizontalSpacer_32"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="2"> + <layout class="QVBoxLayout" name="layoutFile"> + <item> + <widget class="QGroupBox" name="groupBoxFile"> + <property name="title"> + <string>File</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="1" column="1"> + <widget class="QPushButton" name="buttonSendFile"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Загрузить</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <spacer name="horizontalSpacer_34"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="1"> + <widget class="QPushButton" name="buttonLoadFile"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Выгрузить</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <spacer name="verticalSpacer_12"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0"> + <spacer name="horizontalSpacer_33"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <spacer name="verticalSpacer_14"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1"> + <spacer name="verticalSpacer_15"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer_11"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + <item row="4" column="0"> + <spacer name="verticalSpacer_13"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="0"> + <widget class="QTabWidget" name="tabLog"> + <property name="currentIndex"> + <number>1</number> + </property> + <widget class="QWidget" name="LoggerTab"> + <attribute name="title"> + <string>Events</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_11"> + <item row="0" column="0"> + <widget class="QTextEdit" name="logger"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>100</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>16777215</height> + </size> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + <widget class="QWidget" name="TableTab"> + <attribute name="title"> + <string>Group RX Messages</string> + </attribute> + <layout class="QGridLayout" name="gridLayout_12"> + <item row="1" column="0"> + <widget class="QTableView" name="loggertable"> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAsNeeded</enum> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QCheckBox" name="requestBox"> + <property name="text"> + <string>Requester</string> + </property> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + <item row="1" column="0"> + <widget class="QFrame" name="gridFrame"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>50</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>40</height> + </size> + </property> + <layout class="QGridLayout" name="gridLayout_5"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>9</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="3"> + <widget class="QGroupBox" name="groupTXErrors"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>50</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>50</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>40</height> + </size> + </property> + <property name="title"> + <string>TX Errors</string> + </property> + <layout class="QGridLayout" name="gridLayout_7"> + <property name="leftMargin"> + <number>3</number> + </property> + <property name="topMargin"> + <number>3</number> + </property> + <property name="rightMargin"> + <number>3</number> + </property> + <property name="bottomMargin"> + <number>3</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="2"> + <spacer name="horizontalSpacer_6"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="spinTXErrorCount"> + <property name="frame"> + <bool>true</bool> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + <property name="accelerated"> + <bool>false</bool> + </property> + <property name="keyboardTracking"> + <bool>false</bool> + </property> + <property name="maximum"> + <number>999999</number> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QPushButton" name="buttonTXErrorCountErase"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>50</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Сброс</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QTimeEdit" name="timeEditTX"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + <property name="keyboardTracking"> + <bool>false</bool> + </property> + <property name="displayFormat"> + <string>H:mm:ss</string> + </property> + <property name="calendarPopup"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="0" column="0"> + <widget class="QGroupBox" name="RXSettingsgridGroupBox"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>50</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>50</height> + </size> + </property> + <property name="title"> + <string>RX Mode</string> + </property> + <layout class="QGridLayout" name="RXSettingLayout"> + <property name="leftMargin"> + <number>3</number> + </property> + <property name="topMargin"> + <number>3</number> + </property> + <property name="rightMargin"> + <number>3</number> + </property> + <property name="bottomMargin"> + <number>3</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="4"> + <widget class="QCheckBox" name="checkRXHEX"> + <property name="text"> + <string> HEX</string> + </property> + </widget> + </item> + <item row="0" column="8"> + <widget class="QPushButton" name="buttonClearLogger"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Очистить</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QCheckBox" name="checkEchoMode"> + <property name="text"> + <string>ECHO</string> + </property> + </widget> + </item> + <item row="0" column="3"> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="0"> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <widget class="QCheckBox" name="checkPushMsgToLogger"> + <property name="text"> + <string>OUTPUT</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="0" column="1"> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="2"> + <widget class="QGroupBox" name="groupRXErrors"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>50</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>50</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>40</height> + </size> + </property> + <property name="title"> + <string>RX Errors</string> + </property> + <layout class="QGridLayout" name="gridLayout_8"> + <property name="leftMargin"> + <number>3</number> + </property> + <property name="topMargin"> + <number>3</number> + </property> + <property name="rightMargin"> + <number>3</number> + </property> + <property name="bottomMargin"> + <number>3</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="3"> + <widget class="QPushButton" name="buttonRXErrorCountErase"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>50</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Сброс</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <spacer name="horizontalSpacer_35"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <widget class="QSpinBox" name="spinRXErrorCount"> + <property name="frame"> + <bool>true</bool> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + <property name="accelerated"> + <bool>false</bool> + </property> + <property name="keyboardTracking"> + <bool>false</bool> + </property> + <property name="maximum"> + <number>999999</number> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QTimeEdit" name="timeEditRX"> + <property name="readOnly"> + <bool>true</bool> + </property> + <property name="buttonSymbols"> + <enum>QAbstractSpinBox::NoButtons</enum> + </property> + <property name="keyboardTracking"> + <bool>false</bool> + </property> + <property name="currentSection"> + <enum>QDateTimeEdit::HourSection</enum> + </property> + <property name="displayFormat"> + <string>H:mm:ss</string> + </property> + <property name="time"> + <time> + <hour>0</hour> + <minute>0</minute> + <second>0</second> + </time> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="0"> + <spacer name="verticalSpacer_9"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>10</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="1" column="0"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="2"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QGroupBox" name="SettingsAndSelect"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>450</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>300</height> + </size> + </property> + <property name="title"> + <string>Settings</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="1" column="0"> + <widget class="QFrame" name="SettingsAndTX"> + <layout class="QGridLayout" name="SettingsLayout"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="2" column="2"> + <spacer name="horizontalSpacer_11"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <spacer name="verticalSpacer_8"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="0"> + <spacer name="horizontalSpacer_10"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="1"> + <spacer name="verticalSpacer_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>30</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1"> + <widget class="QWidget" name="widget" native="true"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="minimumSize"> + <size> + <width>400</width> + <height>200</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>400</width> + <height>200</height> + </size> + </property> + </widget> + </item> + <item row="0" column="1"> + <layout class="QGridLayout" name="PortSelectLayout"> + <item row="0" column="1"> + <spacer name="horizontalSpacer_7"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="labelTypeConnection"> + <property name="maximumSize"> + <size> + <width>100</width> + <height>16777215</height> + </size> + </property> + <property name="text"> + <string>Тип подключения:</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QComboBox" name="cboxTypeConnection"> + <item> + <property name="text"> + <string>CAN</string> + </property> + </item> + <item> + <property name="text"> + <string>RS</string> + </property> + </item> + </widget> + </item> + </layout> + </item> + <item row="4" column="1"> + <layout class="QGridLayout" name="ConDisLayout"> + <item row="0" column="1"> + <widget class="QGroupBox" name="gridGroupBox"> + <property name="title"> + <string>Control Panel</string> + </property> + <layout class="QGridLayout" name="gridLayout_9"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="0" column="3"> + <widget class="QPushButton" name="buttonDisconnect"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Отключить</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <spacer name="horizontalSpacer_38"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="2"> + <spacer name="horizontalSpacer_9"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <widget class="QPushButton" name="buttonConnect"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Подключить</string> + </property> + </widget> + </item> + <item row="0" column="4"> + <spacer name="horizontalSpacer_39"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item row="0" column="0"> + <spacer name="horizontalSpacer_12"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>10</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="6"> + <widget class="QGroupBox" name="groupCRC"> + <property name="title"> + <string>CRC Calc</string> + </property> + <layout class="QGridLayout" name="gridLayout_6"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="1" column="0"> + <spacer name="horizontalSpacer_36"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <spacer name="verticalSpacer_17"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1"> + <spacer name="verticalSpacer_18"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="2"> + <spacer name="horizontalSpacer_37"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="buttonCRC"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Рассчитать</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="0" column="5"> + <spacer name="horizontalSpacer_13"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="7"> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>CAN ID Calc</string> + </property> + <layout class="QGridLayout" name="gridLayout_10"> + <property name="leftMargin"> + <number>0</number> + </property> + <property name="topMargin"> + <number>0</number> + </property> + <property name="rightMargin"> + <number>0</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="2" column="1"> + <spacer name="verticalSpacer_20"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="pushButton"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>Рассчитать</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <spacer name="horizontalSpacer_43"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="1"> + <spacer name="verticalSpacer_19"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="2"> + <spacer name="horizontalSpacer_44"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer_16"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>5</width> + <height>5</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QGroupBox" name="gridModbus"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Modbus</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <property name="leftMargin"> + <number>3</number> + </property> + <property name="topMargin"> + <number>3</number> + </property> + <property name="rightMargin"> + <number>3</number> + </property> + <property name="bottomMargin"> + <number>0</number> + </property> + <property name="spacing"> + <number>0</number> + </property> + <item row="0" column="0"> + <widget class="QCheckBox" name="checkModbusEnabled"> + <property name="text"> + <string>Enabled</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <spacer name="verticalSpacerModbus"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0"> + <widget class="QTabWidget" name="widgetsModbus"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="currentIndex"> + <number>-1</number> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/usettingsrs.cpp b/usettingsrs.cpp new file mode 100644 index 0000000..53b2d14 --- /dev/null +++ b/usettingsrs.cpp @@ -0,0 +1,188 @@ +#include "usettingsrs.h" +#include "ui_usettingsrs.h" + +#include <QIntValidator> +#include <QLineEdit> +#include "QtSerialPort/QSerialPortInfo" + + +static const char blankString[] = QT_TRANSLATE_NOOP("SettingsDialog", "N/A"); + +USettingsRS::USettingsRS(QWidget *parent) : + QWidget(parent), + m_ui(new Ui::USettingsRS), + m_intValidator(new QIntValidator(0, 4000000, this)) +{ + m_ui->setupUi(this); + + m_ui->baudRateBox->setInsertPolicy(QComboBox::NoInsert); + + connect(m_ui->serialPortInfoListBox, QOverload<int>::of(&QComboBox::currentIndexChanged), + this, &USettingsRS::showPortInfo); + connect(m_ui->baudRateBox, QOverload<int>::of(&QComboBox::currentIndexChanged), + this, &USettingsRS::checkCustomBaudRatePolicy); + connect(m_ui->serialPortInfoListBox, QOverload<int>::of(&QComboBox::currentIndexChanged), + this, &USettingsRS::checkCustomDevicePathPolicy); + + fillPortsParameters(); + fillPortsInfo(); + + updateSettings(); +} + +USettingsRS::~USettingsRS() +{ + delete m_ui; +} + +void USettingsRS::showPortInfo(int idx) +{ + if (idx == -1) + return; + + const QStringList list = m_ui->serialPortInfoListBox->itemData(idx).toStringList(); + m_ui->descriptionLabel->setText(tr("Description: %1").arg(list.count() > 1 ? list.at(1) : tr(blankString))); + m_ui->descriptionLabel->setToolTip(QString("Description: %1").arg(list.count() > 1 ? list.at(1) : tr(blankString))); + + m_ui->manufacturerLabel->setText(tr("Manufacturer: %1").arg(list.count() > 2 ? list.at(2) : tr(blankString))); + m_ui->manufacturerLabel->setToolTip((QString("Manufacturer: %1").arg(list.count() > 2 ? list.at(2) : tr(blankString)))); + + m_ui->serialNumberLabel->setText(tr("Serial number: %1").arg(list.count() > 3 ? list.at(3) : tr(blankString))); + m_ui->serialNumberLabel->setToolTip(QString("Serial number: %1").arg(list.count() > 3 ? list.at(3) : tr(blankString))); + + m_ui->locationLabel->setText(tr("Location: %1").arg(list.count() > 4 ? list.at(4) : tr(blankString))); + m_ui->locationLabel->setToolTip(QString("Location: %1").arg(list.count() > 4 ? list.at(4) : tr(blankString))); + + m_ui->vidLabel->setText(tr("Vendor Identifier: %1").arg(list.count() > 5 ? list.at(5) : tr(blankString))); + m_ui->vidLabel->setToolTip(QString("Vendor Identifier: %1").arg(list.count() > 5 ? list.at(5) : tr(blankString))); + + m_ui->pidLabel->setText(tr("Product Identifier: %1").arg(list.count() > 6 ? list.at(6) : tr(blankString))); + m_ui->pidLabel->setToolTip(QString("Product Identifier: %1").arg(list.count() > 6 ? list.at(6) : tr(blankString))); +} + +void USettingsRS::apply() +{ + updateSettings(); + hide(); +} + +void USettingsRS::device_connect() +{ + updateSettings(); +} + +void USettingsRS::checkCustomBaudRatePolicy(int idx) +{ + const bool isCustomBaudRate = !m_ui->baudRateBox->itemData(idx).isValid(); + m_ui->baudRateBox->setEditable(isCustomBaudRate); + if (isCustomBaudRate) { + m_ui->baudRateBox->clearEditText(); + QLineEdit *edit = m_ui->baudRateBox->lineEdit(); + edit->setValidator(m_intValidator); + } +} + +void USettingsRS::checkCustomDevicePathPolicy(int idx) +{ + const bool isCustomPath = !m_ui->serialPortInfoListBox->itemData(idx).isValid(); + m_ui->serialPortInfoListBox->setEditable(isCustomPath); + if (isCustomPath) + m_ui->serialPortInfoListBox->clearEditText(); +} + +void USettingsRS::fillPortsParameters() +{ + m_ui->baudRateBox->addItem(QStringLiteral("9600"), QSerialPort::Baud9600); + m_ui->baudRateBox->addItem(QStringLiteral("19200"), QSerialPort::Baud19200); + m_ui->baudRateBox->addItem(QStringLiteral("38400"), QSerialPort::Baud38400); + m_ui->baudRateBox->addItem(QStringLiteral("115200"), QSerialPort::Baud115200); + m_ui->baudRateBox->addItem(tr("Custom")); + + m_ui->dataBitsBox->addItem(QStringLiteral("5"), QSerialPort::Data5); + m_ui->dataBitsBox->addItem(QStringLiteral("6"), QSerialPort::Data6); + m_ui->dataBitsBox->addItem(QStringLiteral("7"), QSerialPort::Data7); + m_ui->dataBitsBox->addItem(QStringLiteral("8"), QSerialPort::Data8); + m_ui->dataBitsBox->setCurrentIndex(3); + + m_ui->parityBox->addItem(tr("None"), QSerialPort::NoParity); + m_ui->parityBox->addItem(tr("Even"), QSerialPort::EvenParity); + m_ui->parityBox->addItem(tr("Odd"), QSerialPort::OddParity); + m_ui->parityBox->addItem(tr("Mark"), QSerialPort::MarkParity); + m_ui->parityBox->addItem(tr("Space"), QSerialPort::SpaceParity); + + m_ui->stopBitsBox->addItem(QStringLiteral("1"), QSerialPort::OneStop); +#ifdef Q_OS_WIN + m_ui->stopBitsBox->addItem(tr("1.5"), QSerialPort::OneAndHalfStop); +#endif + m_ui->stopBitsBox->addItem(QStringLiteral("2"), QSerialPort::TwoStop); + + m_ui->flowControlBox->addItem(tr("None"), QSerialPort::NoFlowControl); + m_ui->flowControlBox->addItem(tr("RTS/CTS"), QSerialPort::HardwareControl); + m_ui->flowControlBox->addItem(tr("XON/XOFF"), QSerialPort::SoftwareControl); +} + +void USettingsRS::fillPortsInfo() +{ + m_ui->serialPortInfoListBox->clear(); + QString description; + QString manufacturer; + QString serialNumber; + const auto infos = QSerialPortInfo::availablePorts(); + for (const QSerialPortInfo &info : infos) { + QStringList list; + description = info.description(); + manufacturer = info.manufacturer(); + serialNumber = info.serialNumber(); + list << info.portName() + << (!description.isEmpty() ? description : blankString) + << (!manufacturer.isEmpty() ? manufacturer : blankString) + << (!serialNumber.isEmpty() ? serialNumber : blankString) + << info.systemLocation() + << (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : blankString) + << (info.productIdentifier() ? QString::number(info.productIdentifier(), 16) : blankString); + + m_ui->serialPortInfoListBox->addItem(list.first(), list); + } + + m_ui->serialPortInfoListBox->addItem(tr("Custom")); +} + +void USettingsRS::updateSettings() +{ + m_currentSettings.name = m_ui->serialPortInfoListBox->currentText(); + + if (m_ui->baudRateBox->currentIndex() == 4) { + m_currentSettings.baudRate = m_ui->baudRateBox->currentText().toInt(); + } else { + m_currentSettings.baudRate = static_cast<QSerialPort::BaudRate>( + m_ui->baudRateBox->itemData(m_ui->baudRateBox->currentIndex()).toInt()); + } + m_currentSettings.stringBaudRate = QString::number(m_currentSettings.baudRate); + + m_currentSettings.dataBits = static_cast<QSerialPort::DataBits>( + m_ui->dataBitsBox->itemData(m_ui->dataBitsBox->currentIndex()).toInt()); + m_currentSettings.stringDataBits = m_ui->dataBitsBox->currentText(); + + m_currentSettings.parity = static_cast<QSerialPort::Parity>( + m_ui->parityBox->itemData(m_ui->parityBox->currentIndex()).toInt()); + m_currentSettings.stringParity = m_ui->parityBox->currentText(); + + m_currentSettings.stopBits = static_cast<QSerialPort::StopBits>( + m_ui->stopBitsBox->itemData(m_ui->stopBitsBox->currentIndex()).toInt()); + m_currentSettings.stringStopBits = m_ui->stopBitsBox->currentText(); + + m_currentSettings.flowControl = static_cast<QSerialPort::FlowControl>( + m_ui->flowControlBox->itemData(m_ui->flowControlBox->currentIndex()).toInt()); + m_currentSettings.stringFlowControl = m_ui->flowControlBox->currentText(); +} +void USettingsRS::AfterConnection() +{ + m_ui->parametersBox->setEnabled(false); + m_ui->selectBox->setEnabled(false); +} + +void USettingsRS::AfterDisconnection() +{ + m_ui->parametersBox->setEnabled(true); + m_ui->selectBox->setEnabled(true); +} diff --git a/usettingsrs.h b/usettingsrs.h new file mode 100644 index 0000000..9c784d1 --- /dev/null +++ b/usettingsrs.h @@ -0,0 +1,58 @@ +#ifndef USETTINGSRS_H +#define USETTINGSRS_H + +#include <QWidget> +#include "QtSerialPort/QSerialPort" + +namespace Ui { +class USettingsRS; +} + +class QIntValidator; + +class USettingsRS : public QWidget +{ + Q_OBJECT + +public: + void AfterDisconnection(); + void AfterConnection(); + + struct Settings { + QString name; + qint32 baudRate; + QString stringBaudRate; + QSerialPort::DataBits dataBits; + QString stringDataBits; + QSerialPort::Parity parity; + QString stringParity; + QSerialPort::StopBits stopBits; + QString stringStopBits; + QSerialPort::FlowControl flowControl; + QString stringFlowControl; + bool localEchoEnabled; + }; + explicit USettingsRS(QWidget *parent = nullptr); + ~USettingsRS(); + + Settings m_currentSettings; + void device_connect(); +private slots: + void showPortInfo(int idx); + void apply(); + void checkCustomBaudRatePolicy(int idx); + void checkCustomDevicePathPolicy(int idx); + +private: + + void fillPortsParameters(); + void fillPortsInfo(); + void updateSettings(); + +private: + Ui::USettingsRS *m_ui = nullptr; + + QIntValidator *m_intValidator = nullptr; +}; + +#endif // USETTINGSRS_H diff --git a/usettingsrs.ui b/usettingsrs.ui new file mode 100644 index 0000000..a52cf30 --- /dev/null +++ b/usettingsrs.ui @@ -0,0 +1,175 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>USettingsRS</class> + <widget class="QWidget" name="USettingsRS"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>400</width> + <height>201</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>200</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>201</height> + </size> + </property> + <property name="windowTitle"> + <string>Form</string> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <widget class="QGroupBox" name="selectBox"> + <property name="title"> + <string>Select Serial Port</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QComboBox" name="serialPortInfoListBox"/> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="descriptionLabel"> + <property name="text"> + <string>Description:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="manufacturerLabel"> + <property name="text"> + <string>Manufacturer:</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="serialNumberLabel"> + <property name="text"> + <string>Serial number:</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="locationLabel"> + <property name="text"> + <string>Location:</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="vidLabel"> + <property name="text"> + <string>Vendor ID:</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="pidLabel"> + <property name="text"> + <string>Product ID:</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="0" column="1"> + <layout class="QVBoxLayout" name="SelectParameters"> + <item> + <widget class="QGroupBox" name="parametersBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Select Parameters</string> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="2" column="0"> + <widget class="QLabel" name="parityLabel"> + <property name="text"> + <string>Parity:</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="stopBitsLabel"> + <property name="text"> + <string>Stop bits:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="stopBitsBox"/> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="dataBitsBox"/> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="flowControlLabel"> + <property name="text"> + <string>Flow control:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="baudRateBox"/> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="baudRateLabel"> + <property name="text"> + <string>BaudRate:</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="dataBitsLabel"> + <property name="text"> + <string>Data bits:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="parityBox"/> + </item> + <item row="4" column="1"> + <widget class="QComboBox" name="flowControlBox"/> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections/> +</ui> diff --git a/writeregistermodel.cpp b/writeregistermodel.cpp new file mode 100644 index 0000000..eaffb80 --- /dev/null +++ b/writeregistermodel.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the QtSerialBus module. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "writeregistermodel.h" + +enum { NumColumn = 0, CoilsColumn = 1, HoldingColumn = 2, ColumnCount = 3, RowCount = 100 }; + +WriteRegisterModel::WriteRegisterModel(QObject *parent) + : QAbstractTableModel(parent), + m_coils(RowCount, false), m_holdingRegisters(RowCount, 0u) +{ +} + +int WriteRegisterModel::rowCount(const QModelIndex &/*parent*/) const +{ + return RowCount; +} + +int WriteRegisterModel::columnCount(const QModelIndex &/*parent*/) const +{ + return ColumnCount; +} + +QVariant WriteRegisterModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) + return QVariant(); + + Q_ASSERT(m_coils.count() == RowCount); + Q_ASSERT(m_holdingRegisters.count() == RowCount); + + if (index.column() == NumColumn && role == Qt::DisplayRole) + return QString::number(index.row()); + + if (index.column() == CoilsColumn && role == Qt::CheckStateRole) // coils + return m_coils.at(index.row()) ? Qt::Checked : Qt::Unchecked; + + if (index.column() == HoldingColumn && role == Qt::DisplayRole) // holding registers + return QString("0x%1").arg(QString::number(m_holdingRegisters.at(index.row()), 16)); + + return QVariant(); + +} + +QVariant WriteRegisterModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) { + switch (section) { + case NumColumn: + return QStringLiteral("#"); + case CoilsColumn: + return QStringLiteral("Coils "); + case HoldingColumn: + return QStringLiteral("Holding Registers"); + default: + break; + } + } + return QVariant(); +} + +bool WriteRegisterModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) + return false; + + Q_ASSERT(m_coils.count() == RowCount); + Q_ASSERT(m_holdingRegisters.count() == RowCount); + + if (index.column() == CoilsColumn && role == Qt::CheckStateRole) { // coils + auto s = static_cast<Qt::CheckState>(value.toUInt()); + s == Qt::Checked ? m_coils.setBit(index.row()) : m_coils.clearBit(index.row()); + emit dataChanged(index, index); + return true; + } + + if (index.column() == HoldingColumn && role == Qt::EditRole) { // holding registers + bool result = false; + quint16 newValue = value.toString().toUShort(&result, 16); + if (result) + m_holdingRegisters[index.row()] = newValue; + + emit dataChanged(index, index); + return result; + } + + return false; +} + +Qt::ItemFlags WriteRegisterModel::flags(const QModelIndex &index) const +{ + if (!index.isValid() || index.row() >= RowCount || index.column() >= ColumnCount) + return QAbstractTableModel::flags(index); + + Qt::ItemFlags flags = QAbstractTableModel::flags(index); + if ((index.row() < m_address) || (index.row() >= (m_address + m_number))) + flags &= ~Qt::ItemIsEnabled; + + if (index.column() == CoilsColumn) // coils + return flags | Qt::ItemIsUserCheckable; + if (index.column() == HoldingColumn) // holding registers + return flags | Qt::ItemIsEditable; + + return flags; +} + +void WriteRegisterModel::setStartAddress(int address) +{ + m_address = address; + emit updateViewport(); +} + +void WriteRegisterModel::setNumberOfValues(const QString &number) +{ + m_number = number.toInt(); + emit updateViewport(); +} diff --git a/writeregistermodel.h b/writeregistermodel.h new file mode 100644 index 0000000..4b0311e --- /dev/null +++ b/writeregistermodel.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the QtSerialBus module. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WRITEREGISTERMODEL_H +#define WRITEREGISTERMODEL_H + +#include <QAbstractItemModel> +#include <QBitArray> +#include <QObject> + +class WriteRegisterModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + WriteRegisterModel(QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + + Qt::ItemFlags flags(const QModelIndex &index) const override; + +public slots: + void setStartAddress(int address); + void setNumberOfValues(const QString &number); + +signals: + void updateViewport(); + +public: + int m_number = 0; + int m_address = 0; + QBitArray m_coils; + QVector<quint16> m_holdingRegisters; +}; + +#endif // WRITEREGISTERMODEL_H