├── .gitignore ├── LICENSE.md ├── README.md └── omodsim ├── byteorderutils.h ├── cmdlineparser.cpp ├── cmdlineparser.h ├── connectiondetails.h ├── controls ├── addressbasecombobox.cpp ├── addressbasecombobox.h ├── booleancombobox.cpp ├── booleancombobox.h ├── bytelisttextedit.cpp ├── bytelisttextedit.h ├── clickablelabel.cpp ├── clickablelabel.h ├── consoleoutput.cpp ├── consoleoutput.h ├── customframe.cpp ├── customframe.h ├── customlineedit.cpp ├── customlineedit.h ├── flowcontroltypecombobox.cpp ├── flowcontroltypecombobox.h ├── helpwidget.cpp ├── helpwidget.h ├── jscodeeditor.cpp ├── jscodeeditor.h ├── mainstatusbar.cpp ├── mainstatusbar.h ├── modbuslogwidget.cpp ├── modbuslogwidget.h ├── modbusmessagewidget.cpp ├── modbusmessagewidget.h ├── numericcombobox.cpp ├── numericcombobox.h ├── numericlineedit.cpp ├── numericlineedit.h ├── outputwidget.cpp ├── outputwidget.h ├── outputwidget.ui ├── paritytypecombobox.cpp ├── paritytypecombobox.h ├── pointtypecombobox.cpp ├── pointtypecombobox.h ├── runmodecombobox.cpp ├── runmodecombobox.h ├── scriptcontrol.cpp ├── scriptcontrol.h ├── scriptcontrol.ui ├── searchlineedit.cpp ├── searchlineedit.h ├── simulationmodecombobox.cpp └── simulationmodecombobox.h ├── datasimulator.cpp ├── datasimulator.h ├── dialogs ├── dialogabout.cpp ├── dialogabout.h ├── dialogabout.ui ├── dialogautosimulation.cpp ├── dialogautosimulation.h ├── dialogautosimulation.ui ├── dialogcoilsimulation.cpp ├── dialogcoilsimulation.h ├── dialogcoilsimulation.ui ├── dialogdisplaydefinition.cpp ├── dialogdisplaydefinition.h ├── dialogdisplaydefinition.ui ├── dialogforcemultiplecoils.cpp ├── dialogforcemultiplecoils.h ├── dialogforcemultiplecoils.ui ├── dialogforcemultipleregisters.cpp ├── dialogforcemultipleregisters.h ├── dialogforcemultipleregisters.ui ├── dialogmsgparser.cpp ├── dialogmsgparser.h ├── dialogmsgparser.ui ├── dialogprintsettings.cpp ├── dialogprintsettings.h ├── dialogprintsettings.ui ├── dialogscriptsettings.cpp ├── dialogscriptsettings.h ├── dialogscriptsettings.ui ├── dialogselectserviceport.cpp ├── dialogselectserviceport.h ├── dialogselectserviceport.ui ├── dialogsetuppresetdata.cpp ├── dialogsetuppresetdata.h ├── dialogsetuppresetdata.ui ├── dialogsetupserialport.cpp ├── dialogsetupserialport.h ├── dialogsetupserialport.ui ├── dialogwindowsmanager.cpp ├── dialogwindowsmanager.h ├── dialogwindowsmanager.ui ├── dialogwritecoilregister.cpp ├── dialogwritecoilregister.h ├── dialogwritecoilregister.ui ├── dialogwriteholdingregister.cpp ├── dialogwriteholdingregister.h ├── dialogwriteholdingregister.ui ├── dialogwriteholdingregisterbits.cpp ├── dialogwriteholdingregisterbits.h └── dialogwriteholdingregisterbits.ui ├── displaydefinition.h ├── docs ├── assets │ └── css │ │ ├── reset.css │ │ └── style.css ├── index.html ├── index_ru.html ├── jshelp.qhcp └── jshelp.qhp ├── enums.h ├── fonts └── firacode.ttf ├── formatutils.h ├── formmodsim.cpp ├── formmodsim.h ├── formmodsim.ui ├── htmldelegate.cpp ├── htmldelegate.h ├── jscompleter.cpp ├── jscompleter.h ├── jshighlighter.cpp ├── jshighlighter.h ├── jsobjects ├── console.cpp ├── console.h ├── script.cpp ├── script.h ├── server.cpp ├── server.h ├── storage.cpp └── storage.h ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── menuconnect.cpp ├── menuconnect.h ├── modbusdataunitmap.cpp ├── modbusdataunitmap.h ├── modbusexception.h ├── modbusfunction.h ├── modbuslimits.h ├── modbusmessages ├── diagnostics.h ├── getcommeventcounter.h ├── getcommeventlog.h ├── maskwriteregister.h ├── modbusmessage.cpp ├── modbusmessage.h ├── modbusmessages.h ├── readcoils.h ├── readdiscreteinputs.h ├── readexceptionstatus.h ├── readfifoqueue.h ├── readfilerecord.h ├── readholdingregisters.h ├── readinputregisters.h ├── readwritemultipleregisters.h ├── reportserverid.h ├── writefilerecord.h ├── writemultiplecoils.h ├── writemultipleregisters.h ├── writesinglecoil.h └── writesingleregister.h ├── modbusmultiserver.cpp ├── modbusmultiserver.h ├── modbussimulationparams.h ├── modbuswriteparams.h ├── numericutils.h ├── omodsim.pro ├── qfixedsizedialog.cpp ├── qfixedsizedialog.h ├── qhexvalidator.cpp ├── qhexvalidator.h ├── qint64validator.cpp ├── qint64validator.h ├── qmodbusadu.h ├── qmodbusadurtu.h ├── qmodbusadutcp.h ├── qrange.h ├── quintvalidator.cpp ├── quintvalidator.h ├── recentfileactionlist.cpp ├── recentfileactionlist.h ├── res ├── actionAbout.png ├── actionBigEndian.png ├── actionBinary.png ├── actionConnect.png ├── actionCopy.png ├── actionCut.png ├── actionDblFloat.png ├── actionDefineData.png ├── actionDisconnect.png ├── actionFind.png ├── actionFloatingPt.png ├── actionHex.png ├── actionInt16.png ├── actionInt32.png ├── actionInt64.png ├── actionLittleEndian.png ├── actionNew.png ├── actionOpen.png ├── actionPaste.png ├── actionPrint.png ├── actionRedo.png ├── actionRunScript.png ├── actionSave.png ├── actionScriptSettings.png ├── actionShowData.png ├── actionShowScript.png ├── actionShowTraffic.png ├── actionStopScript.png ├── actionSwappedDbl.png ├── actionSwappedFP.png ├── actionSwappedInt32.png ├── actionSwappedInt64.png ├── actionSwappedUInt32.png ├── actionSwappedUInt64.png ├── actionUInt16.png ├── actionUInt32.png ├── actionUInt64.png ├── actionUndo.png ├── iconAbout.png ├── iconEnum.png ├── iconFunc.png ├── iconLandscape.png ├── iconPortrait.png ├── iconProp.png ├── license.txt ├── omodsim.ico ├── omodsim.png ├── pointEmpty.png └── pointGreen.png ├── resources.qrc ├── scriptsettings.h ├── serialportutils.h ├── translations ├── omodsim_ru.qm └── omodsim_ru.ts ├── windowactionlist.cpp └── windowactionlist.h /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.dll 10 | *.lib 11 | *.exe 12 | 13 | # Qt-es 14 | object_script.*.Release 15 | object_script.*.Debug 16 | *_plugin_import.cpp 17 | /.qmake.cache 18 | /.qmake.stash 19 | /.qtc_clangd 20 | *.pro.user 21 | *.pro.user.* 22 | *.qbs.user 23 | *.qbs.user.* 24 | *.moc 25 | moc_*.cpp 26 | moc_*.h 27 | qrc_*.cpp 28 | ui_*.h 29 | *.qmlc 30 | *.jsc 31 | *.qch 32 | *.qhc 33 | Makefile* 34 | *build-* 35 | debug 36 | release 37 | 38 | # Qt unit tests 39 | target_wrapper.* 40 | 41 | # QtCreator 42 | *.autosave 43 | .qtc_clangd 44 | 45 | # QtCreator Qml 46 | *.qmlproject.user 47 | *.qmlproject.user.* 48 | 49 | # QtCreator CMake 50 | CMakeLists.txt.user* 51 | 52 | .directory 53 | *.bat 54 | *.qmake.stash 55 | *.idx 56 | *.rc 57 | *.qtds 58 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Alexandr Ananev [mail@ananev.org] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /omodsim/byteorderutils.h: -------------------------------------------------------------------------------- 1 | #ifndef BYTEORDERUTILS_H 2 | #define BYTEORDERUTILS_H 3 | 4 | #include 5 | #include "enums.h" 6 | 7 | /// 8 | /// \brief toByteOrderValue 9 | /// \param value 10 | /// \param order 11 | /// \return 12 | /// 13 | inline quint16 toByteOrderValue(quint16 value, ByteOrder order) 14 | { 15 | switch(order) 16 | { 17 | case ByteOrder::BigEndian: 18 | return qToBigEndian(value); 19 | 20 | case ByteOrder::LittleEndian: 21 | return qToLittleEndian(value); 22 | } 23 | 24 | return value; 25 | } 26 | 27 | #endif // BYTEORDERUTILS_H 28 | -------------------------------------------------------------------------------- /omodsim/cmdlineparser.cpp: -------------------------------------------------------------------------------- 1 | #include "cmdlineparser.h" 2 | 3 | /// 4 | /// \brief CmdLineParser::CmdLineParser 5 | /// 6 | CmdLineParser::CmdLineParser() 7 | { 8 | QCommandLineOption helpOption(QStringList() << _help, tr("Displays this help.")); 9 | addOption(helpOption); 10 | 11 | QCommandLineOption versionOption(QStringList() << _version, tr("Displays version information.")); 12 | addOption(versionOption); 13 | 14 | QCommandLineOption configOption(QStringList() << _config, tr("Setup test config file."), tr("file path")); 15 | addOption(configOption); 16 | } 17 | -------------------------------------------------------------------------------- /omodsim/cmdlineparser.h: -------------------------------------------------------------------------------- 1 | #ifndef CMDLINEPARSER_H 2 | #define CMDLINEPARSER_H 3 | 4 | #include 5 | 6 | class CmdLineParser : public QCommandLineParser 7 | { 8 | public: 9 | explicit CmdLineParser(); 10 | 11 | public: 12 | static constexpr const char* _help = "help"; 13 | static constexpr const char* _version = "version"; 14 | static constexpr const char* _config = "config"; 15 | }; 16 | 17 | #endif // CMDLINEPARSER_H 18 | -------------------------------------------------------------------------------- /omodsim/controls/addressbasecombobox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "addressbasecombobox.h" 3 | 4 | /// 5 | /// \brief AddressBaseComboBox::AddressBaseComboBox 6 | /// \param parent 7 | /// 8 | AddressBaseComboBox::AddressBaseComboBox(QWidget* parent) 9 | : QComboBox(parent) 10 | { 11 | addItem(tr("0-based"), QVariant::fromValue(AddressBase::Base0)); 12 | addItem(tr("1-based"), QVariant::fromValue(AddressBase::Base1)); 13 | 14 | connect(this, static_cast(&QComboBox::currentIndexChanged), this, &AddressBaseComboBox::on_currentIndexChanged); 15 | } 16 | 17 | /// 18 | /// \brief AddressBaseComboBox::changeEvent 19 | /// \param event 20 | /// 21 | void AddressBaseComboBox::changeEvent(QEvent* event) 22 | { 23 | if (event->type() == QEvent::LanguageChange) 24 | { 25 | for(int i = 0; i < count(); i++) 26 | { 27 | switch(itemData(i).value()) 28 | { 29 | case AddressBase::Base0: 30 | setItemText(i, tr("0-based")); 31 | break; 32 | 33 | case AddressBase::Base1: 34 | setItemText(i, tr("1-based")); 35 | break; 36 | } 37 | } 38 | } 39 | 40 | QComboBox::changeEvent(event); 41 | } 42 | 43 | /// 44 | /// \brief AddressBaseComboBox::currentAddressBase 45 | /// \return 46 | /// 47 | AddressBase AddressBaseComboBox::currentAddressBase() const 48 | { 49 | return currentData().value(); 50 | } 51 | 52 | /// 53 | /// \brief AddressBaseComboBox::setCurrentAddressBase 54 | /// \param pointType 55 | /// 56 | void AddressBaseComboBox::setCurrentAddressBase(AddressBase base) 57 | { 58 | const auto idx = findData(QVariant::fromValue(base)); 59 | if(idx == currentIndex()) 60 | { 61 | emit currentIndexChanged(idx); 62 | } 63 | else if(idx != -1) 64 | { 65 | setCurrentIndex(idx); 66 | } 67 | } 68 | 69 | /// 70 | /// \brief AddressBaseComboBox::on_currentIndexChanged 71 | /// \param index 72 | /// 73 | void AddressBaseComboBox::on_currentIndexChanged(int index) 74 | { 75 | emit addressBaseChanged(itemData(index).value()); 76 | } 77 | -------------------------------------------------------------------------------- /omodsim/controls/addressbasecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef ADDRESSBASECOMBOBOX_H 2 | #define ADDRESSBASECOMBOBOX_H 3 | 4 | #include 5 | #include "enums.h" 6 | 7 | /// 8 | /// \brief The AddressBaseComboBox class 9 | /// 10 | class AddressBaseComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit AddressBaseComboBox(QWidget *parent = nullptr); 15 | 16 | AddressBase currentAddressBase() const; 17 | void setCurrentAddressBase(AddressBase base); 18 | 19 | signals: 20 | void addressBaseChanged(AddressBase base); 21 | 22 | protected: 23 | void changeEvent(QEvent* event) override; 24 | 25 | private slots: 26 | void on_currentIndexChanged(int); 27 | }; 28 | 29 | #endif // ADDRESSBASECOMBOBOX_H 30 | -------------------------------------------------------------------------------- /omodsim/controls/booleancombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "booleancombobox.h" 2 | 3 | /// 4 | /// \brief BooleanComboBox::BooleanComboBox 5 | /// \param parent 6 | /// 7 | BooleanComboBox::BooleanComboBox(QWidget* parent) 8 | :QComboBox(parent) 9 | { 10 | addItem(tr("Disable"), false); 11 | addItem(tr("Enable"), true); 12 | } 13 | 14 | /// 15 | /// \brief BooleanComboBox::currentValue 16 | /// \return 17 | /// 18 | bool BooleanComboBox::currentValue() const 19 | { 20 | return currentData().value(); 21 | } 22 | 23 | /// 24 | /// \brief BooleanComboBox::setCurrentValue 25 | /// \param value 26 | /// 27 | void BooleanComboBox::setCurrentValue(bool value) 28 | { 29 | const auto idx = findData(value); 30 | setCurrentIndex(idx); 31 | } 32 | -------------------------------------------------------------------------------- /omodsim/controls/booleancombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOLEANCOMBOBOX_H 2 | #define BOOLEANCOMBOBOX_H 3 | 4 | #include 5 | 6 | class BooleanComboBox: public QComboBox 7 | { 8 | Q_OBJECT 9 | public: 10 | BooleanComboBox(QWidget* parent = nullptr); 11 | 12 | bool currentValue() const; 13 | void setCurrentValue(bool value); 14 | }; 15 | 16 | #endif // BOOLEANCOMBOBOX_H 17 | -------------------------------------------------------------------------------- /omodsim/controls/bytelisttextedit.h: -------------------------------------------------------------------------------- 1 | #ifndef BYTELISTTEXTEDIT_H 2 | #define BYTELISTTEXTEDIT_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The ByteListTextEdit class 9 | /// 10 | class ByteListTextEdit : public QPlainTextEdit 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | enum InputMode 16 | { 17 | DecMode = 0, 18 | HexMode 19 | }; 20 | 21 | explicit ByteListTextEdit(QWidget* parent = nullptr); 22 | explicit ByteListTextEdit(InputMode mode, QWidget *parent = nullptr); 23 | 24 | QByteArray value() const; 25 | void setValue(const QByteArray& value); 26 | 27 | InputMode inputMode() const; 28 | void setInputMode(InputMode mode); 29 | 30 | QString text() const; 31 | void setText(const QString& text); 32 | 33 | bool isEmpty() const { 34 | return text().isEmpty(); 35 | } 36 | 37 | signals: 38 | void valueChanged(const QByteArray& value); 39 | 40 | protected: 41 | void focusOutEvent(QFocusEvent* e) override; 42 | void keyPressEvent(QKeyEvent* e) override; 43 | bool canInsertFromMimeData(const QMimeData* source) const override; 44 | void insertFromMimeData(const QMimeData* source) override; 45 | 46 | private slots: 47 | void on_textChanged(); 48 | 49 | private: 50 | void updateValue(); 51 | 52 | private: 53 | InputMode _inputMode; 54 | QByteArray _value; 55 | QChar _separator; 56 | QValidator* _validator; 57 | }; 58 | 59 | #endif // BYTELISTTEXTEDIT_H 60 | -------------------------------------------------------------------------------- /omodsim/controls/clickablelabel.cpp: -------------------------------------------------------------------------------- 1 | #include "clickablelabel.h" 2 | 3 | /// 4 | /// \brief ClickableLabel::ClickableLabel 5 | /// \param parent 6 | /// \param f 7 | /// 8 | ClickableLabel::ClickableLabel(QWidget* parent, Qt::WindowFlags f) 9 | : QLabel(parent, f) 10 | { 11 | } 12 | 13 | /// 14 | /// \brief ClickableLabel::mouseReleaseEvent 15 | /// \param event 16 | /// 17 | void ClickableLabel::mouseReleaseEvent(QMouseEvent* event) 18 | { 19 | emit clicked(); 20 | QLabel::mouseReleaseEvent(event); 21 | } 22 | -------------------------------------------------------------------------------- /omodsim/controls/clickablelabel.h: -------------------------------------------------------------------------------- 1 | #ifndef CLICKABLELABEL_H 2 | #define CLICKABLELABEL_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The ClickableLabel class 8 | /// 9 | class ClickableLabel : public QLabel 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit ClickableLabel(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); 15 | 16 | signals: 17 | void clicked(); 18 | 19 | protected: 20 | void mouseReleaseEvent(QMouseEvent* event); 21 | 22 | }; 23 | 24 | #endif // CLICKABLELABEL_H 25 | -------------------------------------------------------------------------------- /omodsim/controls/consoleoutput.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "consoleoutput.h" 3 | 4 | /// 5 | /// \brief ConsoleOutput::ConsoleOutput 6 | /// \param parent 7 | /// 8 | ConsoleOutput::ConsoleOutput(QWidget* parent) 9 | : QPlainTextEdit(parent) 10 | { 11 | setReadOnly(true); 12 | setUndoRedoEnabled(false); 13 | } 14 | 15 | /// 16 | /// \brief ConsoleOutput::contextMenuEvent 17 | /// \param event 18 | /// 19 | void ConsoleOutput::contextMenuEvent(QContextMenuEvent* event) 20 | { 21 | auto menu = new QMenu(this); 22 | auto action = menu->addAction(tr("Clear"), this, [this]() 23 | { 24 | setPlainText(QString()); 25 | }); 26 | action->setEnabled(!toPlainText().isEmpty()); 27 | menu->exec(event->globalPos()); 28 | delete menu; 29 | } 30 | -------------------------------------------------------------------------------- /omodsim/controls/consoleoutput.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSOLEOUTPUT_H 2 | #define CONSOLEOUTPUT_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The ConsoleOutput class 8 | /// 9 | class ConsoleOutput : public QPlainTextEdit 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit ConsoleOutput(QWidget* parent = nullptr); 14 | 15 | protected: 16 | void contextMenuEvent(QContextMenuEvent* event); 17 | }; 18 | 19 | #endif // CONSOLEOUTPUT_H 20 | -------------------------------------------------------------------------------- /omodsim/controls/customframe.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "customframe.h" 3 | 4 | /// 5 | /// \brief CustomFrame::CustomFrame 6 | /// \param parent 7 | /// \param f 8 | /// 9 | CustomFrame::CustomFrame(QWidget* parent, Qt::WindowFlags f) 10 | :QFrame(parent, f) 11 | { 12 | } 13 | 14 | /// 15 | /// \brief CustomFrame::paintEvent 16 | /// \param e 17 | /// 18 | void CustomFrame::paintEvent(QPaintEvent* e) 19 | { 20 | QPainter painter(this); 21 | 22 | QPen pen; 23 | pen.setColor(palette().dark().color()); 24 | pen.setWidthF(0.5); 25 | 26 | auto oldPen = painter.pen(); 27 | painter.setPen(pen); 28 | painter.setRenderHint(QPainter::Antialiasing); 29 | painter.drawRect(rect().adjusted(1, 1, -1, -1)); 30 | painter.setPen(oldPen); 31 | 32 | QFrame::paintEvent(e); 33 | } 34 | -------------------------------------------------------------------------------- /omodsim/controls/customframe.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMFRAME_H 2 | #define CUSTOMFRAME_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The CustomFrame class 8 | /// 9 | class CustomFrame : public QFrame 10 | { 11 | Q_OBJECT 12 | public: 13 | CustomFrame(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); 14 | 15 | protected: 16 | void paintEvent(QPaintEvent *) override; 17 | }; 18 | 19 | #endif // CUSTOMFRAME_H 20 | -------------------------------------------------------------------------------- /omodsim/controls/customlineedit.cpp: -------------------------------------------------------------------------------- 1 | #include "customlineedit.h" 2 | 3 | /// 4 | /// \brief CustomLineEdit::CustomLineEdit 5 | /// \param parent 6 | /// 7 | CustomLineEdit::CustomLineEdit(QWidget *parent) 8 | :QLineEdit(parent) 9 | { 10 | } 11 | 12 | /// 13 | /// \brief CustomLineEdit::setText 14 | /// \param text 15 | /// 16 | void CustomLineEdit::setText(const QString& text) 17 | { 18 | QLineEdit::setText(text); 19 | emit textChanged(text); 20 | } 21 | -------------------------------------------------------------------------------- /omodsim/controls/customlineedit.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMLINEEDIT_H 2 | #define CUSTOMLINEEDIT_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The CustomLineEdit class 8 | /// 9 | class CustomLineEdit : public QLineEdit 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | CustomLineEdit(QWidget *parent = nullptr); 15 | void setText(const QString& text); 16 | }; 17 | 18 | #endif // CUSTOMLINEEDIT_H 19 | -------------------------------------------------------------------------------- /omodsim/controls/flowcontroltypecombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "flowcontroltypecombobox.h" 2 | 3 | /// 4 | /// \brief FlowControlTypeComboBox::FlowControlTypeComboBox 5 | /// \param parent 6 | /// 7 | FlowControlTypeComboBox::FlowControlTypeComboBox(QWidget* parent) 8 | :QComboBox(parent) 9 | { 10 | addItem(tr("NO CONTROL"), QSerialPort::NoFlowControl); 11 | addItem(tr("HARDWARE (RTS/CTS)"), QSerialPort::HardwareControl); 12 | addItem(tr("SOFTWARE (XON/XOFF)"), QSerialPort::SoftwareControl); 13 | } 14 | 15 | /// 16 | /// \brief FlowControlTypeComboBox::currentFlowControl 17 | /// \return 18 | /// 19 | QSerialPort::FlowControl FlowControlTypeComboBox::currentFlowControl() const 20 | { 21 | return currentData().value(); 22 | } 23 | 24 | /// 25 | /// \brief FlowControlTypeComboBox::setCurrentFlowControl 26 | /// \param fctrl 27 | /// 28 | void FlowControlTypeComboBox::setCurrentFlowControl(QSerialPort::FlowControl fctrl) 29 | { 30 | const auto idx = findData(fctrl); 31 | setCurrentIndex(idx); 32 | } 33 | -------------------------------------------------------------------------------- /omodsim/controls/flowcontroltypecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef FLOWCONTROLTYPECOMBOBOX_H 2 | #define FLOWCONTROLTYPECOMBOBOX_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The FlowControlTypeComboBox class 9 | /// 10 | class FlowControlTypeComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | FlowControlTypeComboBox(QWidget *parent = nullptr); 16 | 17 | QSerialPort::FlowControl currentFlowControl() const; 18 | void setCurrentFlowControl(QSerialPort::FlowControl fctrl); 19 | }; 20 | 21 | #endif // FLOWCONTROLTYPECOMBOBOX_H 22 | -------------------------------------------------------------------------------- /omodsim/controls/helpwidget.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "helpwidget.h" 4 | 5 | /// 6 | /// \brief HelpWidget::HelpWidget 7 | /// \param parent 8 | /// 9 | HelpWidget::HelpWidget(QWidget *parent) 10 | : QTextBrowser(parent) 11 | ,_helpEngine(nullptr) 12 | { 13 | } 14 | 15 | /// 16 | /// \brief HelpWidget::~HelpWidget 17 | /// 18 | HelpWidget::~HelpWidget() 19 | { 20 | } 21 | 22 | /// 23 | /// \brief SearchLineEdit::changeEvent 24 | /// \param event 25 | /// 26 | void HelpWidget::changeEvent(QEvent* event) 27 | { 28 | if (event->type() == QEvent::LanguageChange) 29 | { 30 | setSource(QUrl(tr("qthelp://omodsim/doc/index.html"))); 31 | } 32 | 33 | QTextBrowser::changeEvent(event); 34 | } 35 | 36 | /// 37 | /// \brief HelpWidget::loadResource 38 | /// \param type 39 | /// \param name 40 | /// \return 41 | /// 42 | QVariant HelpWidget::loadResource (int type, const QUrl& name) 43 | { 44 | if (name.scheme() == "qthelp" && _helpEngine) 45 | return QVariant(_helpEngine->fileData(name)); 46 | else 47 | return QTextBrowser::loadResource(type, name); 48 | } 49 | 50 | /// 51 | /// \brief HelpWidget::setHelp 52 | /// \param helpFile 53 | /// 54 | void HelpWidget::setHelp(const QString& helpFile) 55 | { 56 | _helpEngine = QSharedPointer(new QHelpEngine(helpFile, this)); 57 | _helpEngine->setupData(); 58 | 59 | setSource(QUrl(tr("qthelp://omodsim/doc/index.html"))); 60 | } 61 | 62 | /// 63 | /// \brief HelpWidget::showHelp 64 | /// \param helpKey 65 | /// 66 | void HelpWidget::showHelp(const QString& helpKey) 67 | { 68 | const auto url = QString(tr("qthelp://omodsim/doc/index.html#%1")).arg(helpKey.toLower()); 69 | setSource(QUrl(url)); 70 | } 71 | -------------------------------------------------------------------------------- /omodsim/controls/helpwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef HELPWIDGET_H 2 | #define HELPWIDGET_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The HelpWidget class 9 | /// 10 | class HelpWidget : public QTextBrowser 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit HelpWidget(QWidget *parent = nullptr); 16 | ~HelpWidget(); 17 | 18 | void setHelp(const QString& helpFile); 19 | QVariant loadResource (int type, const QUrl& name) override; 20 | 21 | void showHelp(const QString& helpKey); 22 | 23 | protected: 24 | void changeEvent(QEvent* event) override; 25 | 26 | private: 27 | QSharedPointer _helpEngine; 28 | }; 29 | 30 | #endif // HELPWIDGET_H 31 | -------------------------------------------------------------------------------- /omodsim/controls/jscodeeditor.h: -------------------------------------------------------------------------------- 1 | #ifndef JSCODEEDITOR_H 2 | #define JSCODEEDITOR_H 3 | 4 | #include 5 | #include 6 | #include "jscompleter.h" 7 | #include "jshighlighter.h" 8 | 9 | /// 10 | /// \brief The JSCodeEditor class 11 | /// 12 | class JSCodeEditor : public QPlainTextEdit 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit JSCodeEditor(QWidget *parent = nullptr); 18 | ~JSCodeEditor() override; 19 | 20 | void lineNumberAreaPaintEvent(QPaintEvent *event); 21 | int lineNumberAreaWidth(); 22 | 23 | void setForegroundColor(const QColor& clr); 24 | void setBackgroundColor(const QColor& clr); 25 | 26 | bool isAutoCompleteEnabled() const; 27 | void enableAutoComplete(bool enable); 28 | 29 | void search(const QString& text); 30 | 31 | signals: 32 | void helpContext(const QString& key); 33 | 34 | protected: 35 | void resizeEvent(QResizeEvent *event) override; 36 | void keyPressEvent(QKeyEvent *e) override; 37 | 38 | private slots: 39 | void updateLineNumberAreaWidth(int newBlockCount); 40 | void highlightCurrentLine(); 41 | void updateLineNumberArea(const QRect& rect, int dy); 42 | void insertCompletion(const QString& completion); 43 | 44 | private: 45 | QString textUnderCursor() const; 46 | 47 | private: 48 | QColor _lineColor; 49 | QWidget* _lineNumberArea; 50 | JSHighlighter* _highlighter; 51 | JSCompleter* _compliter; 52 | }; 53 | 54 | /// 55 | /// \brief The LineNumberArea class 56 | /// 57 | class LineNumberArea : public QWidget 58 | { 59 | public: 60 | LineNumberArea(JSCodeEditor *editor) 61 | : QWidget(editor) 62 | ,_codeEditor(editor) 63 | { 64 | } 65 | 66 | QSize sizeHint() const override 67 | { 68 | return QSize(_codeEditor->lineNumberAreaWidth(), 0); 69 | } 70 | 71 | protected: 72 | void paintEvent(QPaintEvent *event) override 73 | { 74 | _codeEditor->lineNumberAreaPaintEvent(event); 75 | } 76 | 77 | private: 78 | JSCodeEditor* _codeEditor; 79 | }; 80 | 81 | #endif // JSCODEEDITOR_H 82 | -------------------------------------------------------------------------------- /omodsim/controls/mainstatusbar.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "mainstatusbar.h" 4 | 5 | /// 6 | /// \brief Parity_toString 7 | /// \param parity 8 | /// \return 9 | /// 10 | QString Parity_toString(QSerialPort::Parity parity) 11 | { 12 | switch(parity) 13 | { 14 | case QSerialPort::NoParity: 15 | return MainStatusBar::tr("NONE"); 16 | 17 | case QSerialPort::EvenParity: 18 | return MainStatusBar::tr("EVEN"); 19 | 20 | case QSerialPort::OddParity: 21 | return MainStatusBar::tr("ODD"); 22 | 23 | case QSerialPort::SpaceParity: 24 | return MainStatusBar::tr("SPACE"); 25 | 26 | case QSerialPort::MarkParity: 27 | return MainStatusBar::tr("MARK"); 28 | 29 | default: 30 | break; 31 | } 32 | 33 | return QString(); 34 | } 35 | 36 | /// 37 | /// \brief MainStatusBar::MainStatusBar 38 | /// \param parent 39 | /// 40 | MainStatusBar::MainStatusBar(const ModbusMultiServer& server, QWidget* parent) 41 | : QStatusBar(parent) 42 | { 43 | connect(&server, &ModbusMultiServer::connected, this, [&](const ConnectionDetails& cd) 44 | { 45 | auto label = new QLabel(this); 46 | label->setFrameShadow(QFrame::Sunken); 47 | label->setFrameShape(QFrame::Panel); 48 | label->setMinimumWidth(80); 49 | label->setProperty("ConnectionDetails", QVariant::fromValue(cd)); 50 | 51 | updateConnectionInfo(label, cd); 52 | 53 | _labels.append(label); 54 | addPermanentWidget(label); 55 | }); 56 | 57 | connect(&server, &ModbusMultiServer::disconnected, this, [&](const ConnectionDetails& cd) 58 | { 59 | for(auto&& label : _labels) 60 | { 61 | if(cd == label->property("ConnectionDetails").value()) 62 | { 63 | removeWidget(label); 64 | _labels.removeOne(label); 65 | 66 | break; 67 | } 68 | } 69 | }); 70 | } 71 | 72 | /// 73 | /// \brief MainStatusBar::~MainStatusBar 74 | /// 75 | MainStatusBar::~MainStatusBar() 76 | { 77 | for(auto&& label : _labels) 78 | delete label; 79 | } 80 | 81 | /// 82 | /// \brief MainStatusBar::changeEvent 83 | /// \param event 84 | /// 85 | void MainStatusBar::changeEvent(QEvent* event) 86 | { 87 | if (event->type() == QEvent::LanguageChange) 88 | { 89 | for(auto&& label : _labels) 90 | { 91 | const auto cd = label->property("ConnectionDetails").value(); 92 | updateConnectionInfo(label, cd); 93 | } 94 | } 95 | 96 | QStatusBar::changeEvent(event); 97 | } 98 | 99 | /// 100 | /// \brief MainStatusBar::updateConnectionInfo 101 | /// \param label 102 | /// \param cd 103 | /// 104 | void MainStatusBar::updateConnectionInfo(QLabel* label, const ConnectionDetails& cd) 105 | { 106 | switch(cd.Type) 107 | { 108 | case ConnectionType::Tcp: 109 | label->setText(QString(tr("Modbus/TCP Srv %1:%2")).arg(cd.TcpParams.IPAddress, QString::number(cd.TcpParams.ServicePort))); 110 | break; 111 | 112 | case ConnectionType::Serial: 113 | label->setText(QString(tr("Port %1:%2:%3:%4:%5")).arg(cd.SerialParams.PortName, 114 | QString::number(cd.SerialParams.BaudRate), 115 | QString::number(cd.SerialParams.WordLength), 116 | Parity_toString(cd.SerialParams.Parity), 117 | QString::number(cd.SerialParams.StopBits))); 118 | break; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /omodsim/controls/mainstatusbar.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINSTATUSBAR_H 2 | #define MAINSTATUSBAR_H 3 | 4 | #include 5 | #include 6 | #include "modbusmultiserver.h" 7 | 8 | /// 9 | /// \brief The MainStatusBar class 10 | /// 11 | class MainStatusBar : public QStatusBar 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit MainStatusBar(const ModbusMultiServer& server, QWidget* parent = nullptr); 16 | ~MainStatusBar(); 17 | 18 | protected: 19 | void changeEvent(QEvent* event) override; 20 | 21 | private: 22 | void updateConnectionInfo(QLabel* label, const ConnectionDetails& cd); 23 | 24 | private: 25 | QList _labels; 26 | }; 27 | 28 | #endif // MAINSTATUSBAR_H 29 | -------------------------------------------------------------------------------- /omodsim/controls/modbuslogwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSLOGWIDGET_H 2 | #define MODBUSLOGWIDGET_H 3 | 4 | #include 5 | #include 6 | #include "modbusmessage.h" 7 | 8 | class ModbusLogWidget; 9 | 10 | /// 11 | /// \brief The ModbusLogModel class 12 | /// 13 | class ModbusLogModel : public QAbstractListModel 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit ModbusLogModel(ModbusLogWidget* parent); 19 | ~ModbusLogModel(); 20 | 21 | int rowCount(const QModelIndex& parent = QModelIndex()) const override; 22 | QVariant data(const QModelIndex& index, int role) const override; 23 | 24 | void clear(); 25 | void append(const ModbusMessage* data); 26 | void update(){ 27 | emit dataChanged(index(0), index(_items.size() - 1)); 28 | } 29 | 30 | int rowLimit() const; 31 | void setRowLimit(int val); 32 | 33 | private: 34 | void deleteItems(); 35 | 36 | private: 37 | int _rowLimit = 30; 38 | ModbusLogWidget* _parentWidget; 39 | QQueue _items; 40 | }; 41 | 42 | /// 43 | /// \brief The ModbusLogWidget class 44 | /// 45 | class ModbusLogWidget : public QListView 46 | { 47 | Q_OBJECT 48 | public: 49 | explicit ModbusLogWidget(QWidget* parent = nullptr); 50 | 51 | void clear(); 52 | 53 | int rowCount() const; 54 | QModelIndex index(int row); 55 | 56 | const ModbusMessage* addItem(const QModbusPdu& pdu, ModbusMessage::ProtocolType protocol, int deviceId, int transactionId, const QDateTime& timestamp, bool request); 57 | const ModbusMessage* itemAt(const QModelIndex& index); 58 | 59 | DataDisplayMode dataDisplayMode() const; 60 | void setDataDisplayMode(DataDisplayMode mode); 61 | 62 | int rowLimit() const; 63 | void setRowLimit(int val); 64 | 65 | bool autoscroll() const; 66 | void setAutoscroll(bool on); 67 | 68 | protected: 69 | void changeEvent(QEvent* event) override; 70 | 71 | private: 72 | bool _autoscroll; 73 | DataDisplayMode _dataDisplayMode; 74 | }; 75 | 76 | #endif // MODBUSLOGWIDGET_H 77 | -------------------------------------------------------------------------------- /omodsim/controls/modbusmessagewidget.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSMESSAGEWIDGET_H 2 | #define MODBUSMESSAGEWIDGET_H 3 | 4 | #include 5 | #include "modbusmessage.h" 6 | 7 | /// 8 | /// \brief The ModbusMessageWidget class 9 | /// 10 | class ModbusMessageWidget : public QListWidget 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit ModbusMessageWidget(QWidget *parent = nullptr); 15 | 16 | void clear(); 17 | 18 | DataDisplayMode dataDisplayMode() const; 19 | void setDataDisplayMode(DataDisplayMode mode); 20 | 21 | ByteOrder byteOrder() const; 22 | void setByteOrder(ByteOrder order); 23 | 24 | const ModbusMessage* modbusMessage() const; 25 | void setModbusMessage(const ModbusMessage* msg); 26 | 27 | bool showTimestamp() const; 28 | void setShowTimestamp(bool on); 29 | 30 | void setStatusColor(const QColor& clr); 31 | 32 | protected: 33 | void changeEvent(QEvent* event) override; 34 | 35 | private: 36 | void update(); 37 | 38 | private: 39 | QColor _statusClr; 40 | ByteOrder _byteOrder; 41 | DataDisplayMode _dataDisplayMode; 42 | bool _showTimestamp; 43 | const ModbusMessage* _mm; 44 | }; 45 | 46 | #endif // MODBUSMESSAGEWIDGET_H 47 | -------------------------------------------------------------------------------- /omodsim/controls/numericcombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "numericcombobox.h" 2 | 3 | /// 4 | /// \brief NumericComboBox::NumericComboBox 5 | /// \param parent 6 | /// 7 | NumericComboBox::NumericComboBox(QWidget* parent) 8 | :QComboBox(parent) 9 | { 10 | } 11 | 12 | /// 13 | /// \brief NumericComboBox::addValue 14 | /// \param value 15 | /// 16 | void NumericComboBox::addValue(int value) 17 | { 18 | addItem(QString::number(value)); 19 | } 20 | 21 | /// 22 | /// \brief NumericComboBox::currentValue 23 | /// \return 24 | /// 25 | int NumericComboBox::currentValue() const 26 | { 27 | return currentText().toInt(); 28 | } 29 | 30 | /// 31 | /// \brief NumericComboBox::setCurrentValue 32 | /// \param value 33 | /// 34 | void NumericComboBox::setCurrentValue(int value) 35 | { 36 | const auto idx = findText(QString::number(value)); 37 | setCurrentIndex(idx); 38 | } 39 | -------------------------------------------------------------------------------- /omodsim/controls/numericcombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef NUMERICCOMBOBOX_H 2 | #define NUMERICCOMBOBOX_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The NumericComboBox class 8 | /// 9 | class NumericComboBox : public QComboBox 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit NumericComboBox(QWidget *parent = nullptr); 14 | 15 | void addValue(int value); 16 | int currentValue() const; 17 | void setCurrentValue(int value); 18 | }; 19 | 20 | #endif // NUMERICCOMBOBOX_H 21 | -------------------------------------------------------------------------------- /omodsim/controls/numericlineedit.h: -------------------------------------------------------------------------------- 1 | #ifndef NUMERICLINEEDIT_H 2 | #define NUMERICLINEEDIT_H 3 | 4 | #include 5 | #include "qrange.h" 6 | 7 | class NumericLineEdit : public QLineEdit 8 | { 9 | Q_OBJECT 10 | Q_PROPERTY(InputMode inputMode READ inputMode WRITE setInputMode) 11 | Q_PROPERTY(bool paddingZeroes READ paddingZeroes WRITE setPaddingZeroes) 12 | 13 | public: 14 | enum InputMode 15 | { 16 | Int32Mode = 0, 17 | UInt32Mode, 18 | HexMode, 19 | FloatMode, 20 | DoubleMode, 21 | Int64Mode, 22 | UInt64Mode 23 | }; 24 | 25 | explicit NumericLineEdit(QWidget* parent = nullptr); 26 | explicit NumericLineEdit(InputMode mode, QWidget *parent = nullptr); 27 | 28 | template 29 | T value() const { return _value.value(); } 30 | 31 | template 32 | void setValue(T value) 33 | { internalSetValue(value); } 34 | 35 | bool paddingZeroes() const; 36 | void setPaddingZeroes(bool on); 37 | 38 | template 39 | QRange range() const 40 | { return { _minValue.value(), _maxValue.value() }; } 41 | 42 | template 43 | void setInputRange(QRange range) 44 | { setInputRange(range.from(), range.to()); } 45 | 46 | template 47 | void setInputRange(T bottom, T top) 48 | { 49 | _minValue = QVariant::fromValue(bottom); 50 | _maxValue = QVariant::fromValue(top); 51 | emit rangeChanged(_minValue, _maxValue); 52 | } 53 | 54 | InputMode inputMode() const; 55 | void setInputMode(InputMode mode); 56 | 57 | void setText(const QString& text); 58 | 59 | signals: 60 | void valueChanged(const QVariant& value); 61 | void rangeChanged(const QVariant& bottom, const QVariant& top); 62 | 63 | protected: 64 | void focusInEvent(QFocusEvent*) override; 65 | void focusOutEvent(QFocusEvent*) override; 66 | void keyPressEvent(QKeyEvent*) override; 67 | 68 | private slots: 69 | void on_editingFinished(); 70 | void on_textChanged(const QString& text); 71 | void on_rangeChanged(const QVariant& bottom, const QVariant& top); 72 | 73 | private: 74 | void updateValue(); 75 | void internalSetValue(QVariant value); 76 | 77 | private: 78 | QVariant _value; 79 | QVariant _minValue; 80 | QVariant _maxValue; 81 | InputMode _inputMode; 82 | bool _paddingZeroes; 83 | int _paddingZeroWidth; 84 | }; 85 | 86 | #endif // NUMERICLINEEDIT_H 87 | -------------------------------------------------------------------------------- /omodsim/controls/paritytypecombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "paritytypecombobox.h" 2 | 3 | /// 4 | /// \brief ParityTypeComboBox::ParityTypeComboBox 5 | /// \param parent 6 | /// 7 | ParityTypeComboBox::ParityTypeComboBox(QWidget* parent) 8 | :QComboBox(parent) 9 | { 10 | addItem(tr("ODD"), QSerialPort::OddParity); 11 | addItem(tr("EVEN"), QSerialPort::EvenParity); 12 | addItem(tr("NONE"), QSerialPort::NoParity); 13 | } 14 | 15 | /// 16 | /// \brief ParityTypeComboBox::currentParity 17 | /// \return 18 | /// 19 | QSerialPort::Parity ParityTypeComboBox::currentParity() const 20 | { 21 | return currentData().value(); 22 | } 23 | 24 | /// 25 | /// \brief ParityTypeComboBox::setCurrentParity 26 | /// \param parity 27 | /// 28 | void ParityTypeComboBox::setCurrentParity(QSerialPort::Parity parity) 29 | { 30 | const auto idx = findData(parity); 31 | setCurrentIndex(idx); 32 | } 33 | -------------------------------------------------------------------------------- /omodsim/controls/paritytypecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef PARITYTYPECOMBOBOX_H 2 | #define PARITYTYPECOMBOBOX_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The ParityTypeComboBox class 9 | /// 10 | class ParityTypeComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | public: 14 | ParityTypeComboBox(QWidget *parent = nullptr); 15 | 16 | QSerialPort::Parity currentParity() const; 17 | void setCurrentParity(QSerialPort::Parity parity); 18 | }; 19 | 20 | #endif // PARITYTYPECOMBOBOX_H 21 | -------------------------------------------------------------------------------- /omodsim/controls/pointtypecombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "pointtypecombobox.h" 2 | 3 | 4 | /// 5 | /// \brief PointTypeComboBox::PointTypeComboBox 6 | /// \param parent 7 | /// 8 | PointTypeComboBox::PointTypeComboBox(QWidget *parent) 9 | : QComboBox(parent) 10 | { 11 | addItem("01: COIL STATUS", QModbusDataUnit::Coils); 12 | addItem("02: INPUT STATUS", QModbusDataUnit::DiscreteInputs); 13 | addItem("03: HOLDING REGISTER", QModbusDataUnit::HoldingRegisters); 14 | addItem("04: INPUT REGISTER", QModbusDataUnit::InputRegisters); 15 | 16 | connect(this, QOverload::of(&QComboBox::currentIndexChanged), this, &PointTypeComboBox::on_currentIndexChanged); 17 | } 18 | 19 | /// 20 | /// \brief PointTypeComboBox::currentPointType 21 | /// \return 22 | /// 23 | QModbusDataUnit::RegisterType PointTypeComboBox::currentPointType() const 24 | { 25 | return currentData().value(); 26 | } 27 | 28 | /// 29 | /// \brief PointTypeComboBox::setCurrentPointType 30 | /// \param pointType 31 | /// 32 | void PointTypeComboBox::setCurrentPointType(QModbusDataUnit::RegisterType pointType) 33 | { 34 | const auto idx = findData(pointType); 35 | setCurrentIndex(idx); 36 | } 37 | 38 | /// 39 | /// \brief PointTypeComboBox::on_currentIndexChanged 40 | /// \param index 41 | /// 42 | void PointTypeComboBox::on_currentIndexChanged(int index) 43 | { 44 | emit pointTypeChanged(itemData(index).value()); 45 | } 46 | -------------------------------------------------------------------------------- /omodsim/controls/pointtypecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef POINTTYPECOMBOBOX_H 2 | #define POINTTYPECOMBOBOX_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The PointTypeComboBox class 9 | /// 10 | class PointTypeComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | public: 14 | PointTypeComboBox(QWidget *parent = nullptr); 15 | 16 | QModbusDataUnit::RegisterType currentPointType() const; 17 | void setCurrentPointType(QModbusDataUnit::RegisterType pointType); 18 | 19 | signals: 20 | void pointTypeChanged(QModbusDataUnit::RegisterType value); 21 | 22 | private slots: 23 | void on_currentIndexChanged(int); 24 | }; 25 | 26 | #endif // POINTTYPECOMBOBOX_H 27 | -------------------------------------------------------------------------------- /omodsim/controls/runmodecombobox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "runmodecombobox.h" 3 | 4 | /// 5 | /// \brief RunModeComboBox::RunModeComboBox 6 | /// \param parent 7 | /// 8 | RunModeComboBox::RunModeComboBox(QWidget* parent) 9 | : QComboBox(parent) 10 | { 11 | addItem(tr("Once"), QVariant::fromValue(RunMode::Once)); 12 | addItem(tr("Periodically"), QVariant::fromValue(RunMode::Periodically)); 13 | 14 | setSizeAdjustPolicy(SizeAdjustPolicy::AdjustToContents); 15 | connect(this, QOverload::of(&QComboBox::currentIndexChanged), this, &RunModeComboBox::on_currentIndexChanged); 16 | } 17 | 18 | /// 19 | /// \brief RunModeComboBox::changeEvent 20 | /// \param event 21 | /// 22 | void RunModeComboBox::changeEvent(QEvent* event) 23 | { 24 | if (event->type() == QEvent::LanguageChange) 25 | { 26 | for(int i = 0; i < count(); i++) 27 | { 28 | switch(itemData(i).value()) 29 | { 30 | case RunMode::Once: 31 | setItemText(i, tr("Once")); 32 | break; 33 | 34 | case RunMode::Periodically: 35 | setItemText(i, tr("Periodically")); 36 | break; 37 | } 38 | } 39 | } 40 | 41 | QComboBox::changeEvent(event); 42 | } 43 | 44 | /// 45 | /// \brief RunModeComboBox::currentRunMode 46 | /// \return 47 | /// 48 | RunMode RunModeComboBox::currentRunMode() const 49 | { 50 | return currentData().value(); 51 | } 52 | 53 | /// 54 | /// \brief RunModeComboBox::setCurrentRunMode 55 | /// \param mode 56 | /// 57 | void RunModeComboBox::setCurrentRunMode(RunMode mode) 58 | { 59 | const auto idx = findData(QVariant::fromValue(mode)); 60 | setCurrentIndex(idx); 61 | } 62 | 63 | /// 64 | /// \brief RunModeComboBox::on_currentIndexChanged 65 | /// \param index 66 | /// 67 | void RunModeComboBox::on_currentIndexChanged(int index) 68 | { 69 | emit runModeChanged(itemData(index).value()); 70 | } 71 | -------------------------------------------------------------------------------- /omodsim/controls/runmodecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNMODECOMBOBOX_H 2 | #define RUNMODECOMBOBOX_H 3 | 4 | #include 5 | #include "enums.h" 6 | 7 | /// 8 | /// \brief The RunModeComboBox class 9 | /// 10 | class RunModeComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit RunModeComboBox(QWidget *parent = nullptr); 15 | 16 | RunMode currentRunMode() const; 17 | void setCurrentRunMode(RunMode mode); 18 | 19 | protected: 20 | void changeEvent(QEvent* event) override; 21 | 22 | signals: 23 | void runModeChanged(RunMode value); 24 | 25 | private slots: 26 | void on_currentIndexChanged(int); 27 | }; 28 | 29 | #endif // RUNMODECOMBOBOX_H 30 | -------------------------------------------------------------------------------- /omodsim/controls/scriptcontrol.h: -------------------------------------------------------------------------------- 1 | #ifndef SCRIPTCONTROL_H 2 | #define SCRIPTCONTROL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "console.h" 8 | #include "script.h" 9 | #include "storage.h" 10 | #include "server.h" 11 | 12 | namespace Ui { 13 | class ScriptControl; 14 | } 15 | 16 | /// 17 | /// \brief The ScriptControl class 18 | /// 19 | class ScriptControl : public QWidget 20 | { 21 | Q_OBJECT 22 | 23 | friend QSettings& operator <<(QSettings& out, const ScriptControl* ctrl); 24 | friend QSettings& operator >>(QSettings& in, ScriptControl* ctrl); 25 | friend QDataStream& operator <<(QDataStream& out, const ScriptControl* ctrl); 26 | friend QDataStream& operator >>(QDataStream& in, ScriptControl* ctrl); 27 | 28 | public: 29 | explicit ScriptControl(QWidget *parent = nullptr); 30 | ~ScriptControl(); 31 | 32 | void setModbusMultiServer(ModbusMultiServer* server); 33 | void setByteOrder(const ByteOrder* order); 34 | void setAddressBase(AddressBase base); 35 | 36 | bool isAutoCompleteEnabled() const; 37 | void enableAutoComplete(bool enable); 38 | 39 | QString script() const; 40 | void setScript(const QString& text); 41 | 42 | QString searchText() const; 43 | 44 | bool isRunning() const; 45 | 46 | void setFocus(); 47 | 48 | bool canUndo() const; 49 | bool canRedo() const; 50 | bool canPaste() const; 51 | 52 | public slots: 53 | void undo(); 54 | void redo(); 55 | void cut(); 56 | void copy(); 57 | void paste(); 58 | void selectAll(); 59 | void search(const QString& text); 60 | void runScript(RunMode mode, int interval = 0); 61 | void stopScript(); 62 | void showHelp(const QString& helpKey); 63 | 64 | private slots: 65 | bool executeScript(); 66 | 67 | private: 68 | Ui::ScriptControl *ui; 69 | 70 | QTimer _timer; 71 | QJSEngine _jsEngine; 72 | QString _scriptCode; 73 | QString _searchText; 74 | 75 | QSharedPointer