diff options
Diffstat (limited to 'examples/serialbus/can/sendframebox.cpp')
-rw-r--r-- | examples/serialbus/can/sendframebox.cpp | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/examples/serialbus/can/sendframebox.cpp b/examples/serialbus/can/sendframebox.cpp new file mode 100644 index 0000000..a84222d --- /dev/null +++ b/examples/serialbus/can/sendframebox.cpp @@ -0,0 +1,182 @@ +/**************************************************************************** +** +** Copyright (C) 2017 Andre Hartmann <aha_1980@gmx.de> +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the QtSerialBus module. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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 "sendframebox.h" +#include "ui_sendframebox.h" + +enum { + MaxStandardId = 0x7FF, + MaxExtendedId = 0x10000000 +}; + +enum { + MaxPayload = 8, + MaxPayloadFd = 64 +}; + +HexIntegerValidator::HexIntegerValidator(QObject *parent) : + QValidator(parent), + m_maximum(MaxStandardId) +{ +} + +QValidator::State HexIntegerValidator::validate(QString &input, int &) const +{ + bool ok; + uint value = input.toUInt(&ok, 16); + + if (!value) + return Intermediate; + + if (!ok || value > m_maximum) + return Invalid; + + return Acceptable; +} + +void HexIntegerValidator::setMaximum(uint maximum) +{ + m_maximum = maximum; +} + +HexStringValidator::HexStringValidator(QObject *parent) : + QValidator(parent), + m_maxLength(MaxPayload) +{ +} + +QValidator::State HexStringValidator::validate(QString &input, int &pos) const +{ + const int maxSize = 2 * m_maxLength; + const QChar space = QLatin1Char(' '); + QString data = input; + data.remove(space); + + if (data.isEmpty()) + return Intermediate; + + // limit maximum size and forbid trailing spaces + if ((data.size() > maxSize) || (data.size() == maxSize && input.endsWith(space))) + return Invalid; + + // check if all input is valid + const QRegularExpression re(QStringLiteral("^[[:xdigit:]]*$")); + if (!re.match(data).hasMatch()) + return Invalid; + + // insert a space after every two hex nibbles + const QRegularExpression insertSpace(QStringLiteral("(?:[[:xdigit:]]{2} )*[[:xdigit:]]{3}")); + if (insertSpace.match(input).hasMatch()) { + input.insert(input.size() - 1, space); + pos = input.size(); + } + + return Acceptable; +} + +void HexStringValidator::setMaxLength(int maxLength) +{ + m_maxLength = maxLength; +} + +SendFrameBox::SendFrameBox(QWidget *parent) : + QGroupBox(parent), + m_ui(new Ui::SendFrameBox) +{ + m_ui->setupUi(this); + + m_hexIntegerValidator = new HexIntegerValidator(this); + m_ui->frameIdEdit->setValidator(m_hexIntegerValidator); + m_hexStringValidator = new HexStringValidator(this); + m_ui->payloadEdit->setValidator(m_hexStringValidator); + + connect(m_ui->dataFrame, &QRadioButton::toggled, [this](bool set) { + if (set) + m_ui->flexibleDataRateBox->setEnabled(true); + }); + + connect(m_ui->remoteFrame, &QRadioButton::toggled, [this](bool set) { + if (set) { + m_ui->flexibleDataRateBox->setEnabled(false); + m_ui->flexibleDataRateBox->setChecked(false); + } + }); + + connect(m_ui->errorFrame, &QRadioButton::toggled, [this](bool set) { + if (set) { + m_ui->flexibleDataRateBox->setEnabled(false); + m_ui->flexibleDataRateBox->setChecked(false); + } + }); + + connect(m_ui->extendedFormatBox, &QCheckBox::toggled, [this](bool set) { + m_hexIntegerValidator->setMaximum(set ? MaxExtendedId : MaxStandardId); + }); + + connect(m_ui->flexibleDataRateBox, &QCheckBox::toggled, [this](bool set) { + m_hexStringValidator->setMaxLength(set ? MaxPayloadFd : MaxPayload); + m_ui->bitrateSwitchBox->setEnabled(set); + if (!set) + m_ui->bitrateSwitchBox->setChecked(false); + }); + + connect(m_ui->sendButton, &QPushButton::clicked, [this]() { + const uint frameId = m_ui->frameIdEdit->text().toUInt(nullptr, 16); + QString data = m_ui->payloadEdit->text(); + const QByteArray payload = QByteArray::fromHex(data.remove(QLatin1Char(' ')).toLatin1()); + + QCanBusFrame frame = QCanBusFrame(frameId, payload); + frame.setExtendedFrameFormat(m_ui->extendedFormatBox->isChecked()); + frame.setFlexibleDataRateFormat(m_ui->flexibleDataRateBox->isChecked()); + frame.setBitrateSwitch(m_ui->bitrateSwitchBox->isChecked()); + + if (m_ui->errorFrame->isChecked()) + frame.setFrameType(QCanBusFrame::ErrorFrame); + else if (m_ui->remoteFrame->isChecked()) + frame.setFrameType(QCanBusFrame::RemoteRequestFrame); + + emit sendFrame(frame); + }); +} + +SendFrameBox::~SendFrameBox() +{ + delete m_ui; +} |