Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
sanny32 committed Oct 12, 2023
2 parents 431e167 + 18b7dad commit d7a0efc
Show file tree
Hide file tree
Showing 61 changed files with 6,360 additions and 664 deletions.
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Open ModSim
Open ModSim is a free implimentation of modbus slave (server) utility for modbus-tcp and modbus-rtu protocols.

![image](https://github.com/sanny32/OpenModSim/assets/13627951/43d1b90d-b56b-400d-8dca-2903e23e56a9)
![image](https://github.com/sanny32/OpenModSim/assets/13627951/3912005f-df9b-41b4-b6f5-33ebc76a908c)

![image](https://github.com/sanny32/OpenModSim/assets/13627951/e805d429-7657-4355-869b-7559f11ea3d9)

![image](https://github.com/sanny32/OpenModSim/assets/13627951/b40eca28-7a34-46dc-9a50-9b16dc1becf1)


## Features
Expand Down Expand Up @@ -38,7 +38,18 @@ Registers
Random - simulate register randomly
Increment - simulate register from Low Limit to High Limit with a given Step
Decrement - simulate register from High Limit to Low Limit with a given Step


Modbus Logging

![image](https://github.com/sanny32/OpenModSim/assets/13627951/1ebf4973-44a5-4464-aada-26aa751f65da)


## Extended Featues

Modbus Message Parser

![image](https://github.com/sanny32/OpenModScan/assets/13627951/86a82340-015e-4ee9-a483-b5ab83527cc1)

## Scripting
From version 1.2.0 Open ModSim supports scripting. Qt runtime implements the [ECMAScript Language Specification](http://www.ecma-international.org/publications/standards/Ecma-262.htm) standard, so Javascript is used to write code.

Expand Down
283 changes: 283 additions & 0 deletions omodsim/controls/bytelisttextedit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
#include <QRegularExpressionValidator>
#include <QMimeData>
#include "formatutils.h"
#include "bytelisttextedit.h"

///
/// \brief ByteListTextEdit::ByteListTextEdit
/// \param parent
///
ByteListTextEdit::ByteListTextEdit(QWidget* parent)
:QPlainTextEdit(parent)
,_separator(' ')
,_validator(nullptr)
{
setInputMode(DecMode);
connect(this, &QPlainTextEdit::textChanged, this, &ByteListTextEdit::on_textChanged);
}

///
/// \brief ByteListTextEdit::ByteListTextEdit
/// \param mode
/// \param parent
///
ByteListTextEdit::ByteListTextEdit(InputMode mode, QWidget *parent)
:QPlainTextEdit(parent)
,_separator(' ')
,_validator(nullptr)
{
setInputMode(mode);
connect(this, &QPlainTextEdit::textChanged, this, &ByteListTextEdit::on_textChanged);
}

///
/// \brief ByteListTextEdit::value
/// \return
///
QByteArray ByteListTextEdit::value() const
{
return _value;
}

///
/// \brief ByteListTextEdit::setValue
/// \param value
///
void ByteListTextEdit::setValue(const QByteArray& value)
{
switch(_inputMode)
{
case DecMode:
{
const auto text = formatByteArray(DataDisplayMode::Decimal, value);
if(text != toPlainText())
setPlainText(formatByteArray(DataDisplayMode::Decimal, value));
}
break;

case HexMode:
{
const auto text = formatByteArray(DataDisplayMode::Hex, value);
if(text != toPlainText())
setPlainText(formatByteArray(DataDisplayMode::Hex, value));
}
break;
}

if(value != _value)
{
_value = value;
emit valueChanged(_value);
}
}

///
/// \brief ByteListTextEdit::inputMode
/// \return
///
ByteListTextEdit::InputMode ByteListTextEdit::inputMode() const
{
return _inputMode;
}

///
/// \brief ByteListTextEdit::setInputMode
/// \param mode
///
void ByteListTextEdit::setInputMode(InputMode mode)
{
_inputMode = mode;

if(_validator)
{
delete _validator;
_validator = nullptr;
}

const auto sep = (_separator == ' ')? "\\s" : QString(_separator);
switch(_inputMode)
{
case DecMode:
_validator =new QRegularExpressionValidator(QRegularExpression("(?:[0-9]{1,2}[" + sep + "]{0,1})*"), this);
break;

case HexMode:
_validator = new QRegularExpressionValidator(QRegularExpression("(?:[0-9a-fA-F]{1,2}[" + sep + "]{0,1})*"), this);
break;
}

setValue(_value);
}

///
/// \brief ByteListTextEdit::text
/// \return
///
QString ByteListTextEdit::text() const
{
return toPlainText();
}

///
/// \brief ByteListTextEdit::setText
/// \param text
///
void ByteListTextEdit::setText(const QString& text)
{
setPlainText(text);
updateValue();
}

///
/// \brief ByteListTextEdit::focusOutEvent
/// \param event
///
void ByteListTextEdit::focusOutEvent(QFocusEvent* e)
{
updateValue();
QPlainTextEdit::focusOutEvent(e);
}

///
/// \brief ByteListTextEdit::keyPressEvent
/// \param e
///
void ByteListTextEdit::keyPressEvent(QKeyEvent *e)
{
if(!_validator)
{
QPlainTextEdit::keyPressEvent(e);
return;
}

if(e->key() == Qt::Key_Enter ||
e->key() == Qt::Key_Return)
{
return;
}

int pos = 0;
auto text = toPlainText() + e->text();
const auto state = _validator->validate(text, pos);

if(state == QValidator::Acceptable ||
e->key() == Qt::Key_Backspace ||
e->key() == Qt::Key_Delete ||
e->key() == Qt::Key_Space ||
e->matches(QKeySequence::Cut) ||
e->matches(QKeySequence::Copy) ||
e->matches(QKeySequence::Paste) ||
e->matches(QKeySequence::Undo) ||
e->matches(QKeySequence::Redo) ||
e->matches(QKeySequence::SelectAll))
{
QPlainTextEdit::keyPressEvent(e);
}
}

///
/// \brief ByteListTextEdit::canInsertFromMimeData
/// \param source
/// \return
///
bool ByteListTextEdit::canInsertFromMimeData(const QMimeData* source) const
{
int pos = 0;
auto text = source->text().trimmed();
const auto state = _validator->validate(text, pos);

return state == QValidator::Acceptable;
}

///
/// \brief ByteListTextEdit::insertFromMimeData
/// \param source
///
void ByteListTextEdit::insertFromMimeData(const QMimeData* source)
{
int pos = 0;
auto text = source->text().trimmed();
const auto state = _validator->validate(text, pos);

if(state == QValidator::Acceptable)
{
QPlainTextEdit::insertFromMimeData(source);
updateValue();
}
}

///
/// \brief ByteListTextEdit::on_textChanged
///
void ByteListTextEdit::on_textChanged()
{
QByteArray value;
switch(_inputMode)
{
case DecMode:
{
for(auto&& s : text().split(_separator))
{
bool ok;
const quint8 v = s.trimmed().toUInt(&ok);
if(ok) value.push_back(v);
}
}
break;

case HexMode:
{
for(auto&& s : text().split(_separator))
{
bool ok;
const quint8 v = s.trimmed().toUInt(&ok, 16);
if(ok) value.push_back(v);
}
}
break;
}

if(value != _value)
{
_value = value;
emit valueChanged(_value);
}
}

///
/// \brief ByteListTextEdit::updateValue
///
void ByteListTextEdit::updateValue()
{
QByteArray value;
switch(_inputMode)
{
case DecMode:
{
for(auto&& s : text().split(_separator))
{
bool ok;
const quint8 v = s.trimmed().toUInt(&ok);
if(ok) value.push_back(v);
}

if(!value.isEmpty()) setValue(value);
else setValue(_value);
}
break;

case HexMode:
{
for(auto&& s : text().split(_separator))
{
bool ok;
const quint8 v = s.trimmed().toUInt(&ok, 16);
if(ok) value.push_back(v);
}

if(!value.isEmpty()) setValue(value);
else setValue(_value);
}
break;
}
}
59 changes: 59 additions & 0 deletions omodsim/controls/bytelisttextedit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#ifndef BYTELISTTEXTEDIT_H
#define BYTELISTTEXTEDIT_H

#include <QValidator>
#include <QPlainTextEdit>

///
/// \brief The ByteListTextEdit class
///
class ByteListTextEdit : public QPlainTextEdit
{
Q_OBJECT

public:
enum InputMode
{
DecMode = 0,
HexMode
};

explicit ByteListTextEdit(QWidget* parent = nullptr);
explicit ByteListTextEdit(InputMode mode, QWidget *parent = nullptr);

QByteArray value() const;
void setValue(const QByteArray& value);

InputMode inputMode() const;
void setInputMode(InputMode mode);

QString text() const;
void setText(const QString& text);

bool isEmpty() const {
return text().isEmpty();
}

signals:
void valueChanged(const QByteArray& value);

protected:
void focusOutEvent(QFocusEvent* e) override;
void keyPressEvent(QKeyEvent* e) override;
bool canInsertFromMimeData(const QMimeData* source) const override;
void insertFromMimeData(const QMimeData* source) override;

private slots:
void on_textChanged();

private:
void updateValue();

private:
InputMode _inputMode;
QByteArray _value;
QChar _separator;
QValidator* _validator;
};

#endif // BYTELISTTEXTEDIT_H
Loading

0 comments on commit d7a0efc

Please sign in to comment.