Changeset - 571af19990ed
[Not reviewed]
Hasan Yavuz ÖZDERYA - 10 years ago 2015-10-10 16:03:20
hy@ozderya.net
implemented escaping of LF, CR, TAB characters with \n, \r, \t respectively
3 files changed with 30 insertions and 3 deletions:
0 comments (0 inline, 0 general)
commandedit.cpp
Show inline comments
 
/*
 
  Copyright © 2015 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot is free software: you can redistribute it and/or modify
 
  it under the terms of the GNU General Public License as published by
 
  the Free Software Foundation, either version 3 of the License, or
 
  (at your option) any later version.
 

	
 
  serialplot is distributed in the hope that it will be useful,
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  GNU General Public License for more details.
 

	
 
  You should have received a copy of the GNU General Public License
 
  along with serialplot.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#include <QKeyEvent>
 

	
 
#include <QtDebug>
 

	
 
#include "commandedit.h"
 

	
 
class HexCommandValidator : public QRegExpValidator
 
{
 
public:
 
    explicit HexCommandValidator(QObject* parent = 0);
 
    QValidator::State validate(QString & input, int & pos) const;
 
};
 

	
 
HexCommandValidator::HexCommandValidator(QObject* parent) :
 
    QRegExpValidator(parent)
 
{
 
    QRegExp regExp("^(?:(?:[0-9A-F]{2}[ ])+(?:[0-9A-F]{2}))|(?:[0-9A-F]{2})$");
 
    setRegExp(regExp);
 
}
 

	
 
QValidator::State HexCommandValidator::validate(QString & input, int & pos) const
 
{
 
    input = input.toUpper();
 

	
 
    // don't let pos to be altered at this stage
 
    int orgPos = pos;
 
    auto r = QRegExpValidator::validate(input, pos);
 
    pos = orgPos;
 

	
 
    // try fixing up spaces
 
    if (r != QValidator::Acceptable)
 
    {
 
        input = input.replace(" ", "");
 
        input.replace(QRegExp("([0-9A-F]{2}(?!$))"), "\\1 ");
 
        if (pos == input.size()-1) pos = input.size();
 
        r = QRegExpValidator::validate(input, pos);
 
    }
 

	
 
    return r;
 
}
 

	
 
CommandEdit::CommandEdit(QWidget *parent) :
 
    QLineEdit(parent)
 
{
 
    hexValidator = new HexCommandValidator(this);
 
    asciiValidator = new QRegExpValidator(QRegExp("[\\x0000-\\x007F]+"));
 
    ascii_mode = true;
 
    setValidator(asciiValidator);
 
}
 

	
 
CommandEdit::~CommandEdit()
 
{
 
    delete hexValidator;
 
}
 

	
 
QString unEscape(QString str);
 
QString escape(QString str);
 

	
 
void CommandEdit::setMode(bool ascii)
 
{
 
    ascii_mode = ascii;
 
    if (ascii)
 
    {
 
        setValidator(asciiValidator);
 

	
 
        auto hexText = text().remove(" ");
 
        // try patching HEX string in case of missing nibble so that
 
        // input doesn't turn into gibberish
 
        if (hexText.size() % 2 == 1)
 
        {
 
            hexText.replace(hexText.size()-1, 1, "3F"); // 0x3F = '?'
 
            qWarning() << "Broken byte in hex command is replaced. Check your command!";
 
        }
 
        setText(QByteArray::fromHex(hexText.toLatin1()));
 

	
 
        setText(escape(QByteArray::fromHex(hexText.toLatin1())));
 
    }
 
    else
 
    {
 
        setValidator(hexValidator);
 
        setText(text().toLatin1().toHex());
 
        setText(unEscape(text()).toLatin1().toHex());
 
    }
 
}
 

	
 
void CommandEdit::keyPressEvent(QKeyEvent * event)
 
{
 
    if (ascii_mode)
 
    {
 
        QLineEdit::keyPressEvent(event);
 
        return;
 
    }
 

	
 
    if (event->key() == Qt::Key_Backspace && !hasSelectedText())
 
    {
 
        int cursor = cursorPosition();
 
        if (cursor != 0 && text()[cursor-1] == ' ')
 
        {
 
            setCursorPosition(cursor-1);
 
        }
 
    }
 

	
 
    QLineEdit::keyPressEvent(event);
 
}
 

	
 
QString CommandEdit::unEscapedText()
 
{
 
    return unEscape(text());
 
}
 

	
 
QString unEscape(QString str)
 
{
 
    str.replace("\\n", "\n");
 
    str.replace("\\r", "\r");
 
    str.replace("\\t", "\t");
 
    return str;
 
}
 

	
 
QString escape(QString str)
 
{
 
    str.replace("\n", "\\n");
 
    str.replace("\r", "\\r");
 
    str.replace("\t", "\\t");
 
    return str;
 
}
commandedit.h
Show inline comments
 
/*
 
  Copyright © 2015 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot is free software: you can redistribute it and/or modify
 
  it under the terms of the GNU General Public License as published by
 
  the Free Software Foundation, either version 3 of the License, or
 
  (at your option) any later version.
 

	
 
  serialplot is distributed in the hope that it will be useful,
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  GNU General Public License for more details.
 

	
 
  You should have received a copy of the GNU General Public License
 
  along with serialplot.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#ifndef COMMANDEDIT_H
 
#define COMMANDEDIT_H
 

	
 
#include <QLineEdit>
 
#include <QValidator>
 
#include <QString>
 

	
 
class CommandEdit : public QLineEdit
 
{
 
    Q_OBJECT
 

	
 
public:
 
    explicit CommandEdit(QWidget *parent = 0);
 
    ~CommandEdit();
 
    void setMode(bool ascii); // true = ascii, false = hex
 
    QString unEscapedText(); // return unescaped text(), used in ascii_mode only
 

	
 
private:
 
    bool ascii_mode;
 
    QValidator* hexValidator;
 
    QValidator* asciiValidator;
 

	
 
protected:
 
    void keyPressEvent(QKeyEvent * event) Q_DECL_OVERRIDE;
 
};
 

	
 
#endif // COMMANDEDIT_H
commandwidget.cpp
Show inline comments
 
/*
 
  Copyright © 2015 Hasan Yavuz Özderya
 

	
 
  This file is part of serialplot.
 

	
 
  serialplot is free software: you can redistribute it and/or modify
 
  it under the terms of the GNU General Public License as published by
 
  the Free Software Foundation, either version 3 of the License, or
 
  (at your option) any later version.
 

	
 
  serialplot is distributed in the hope that it will be useful,
 
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  GNU General Public License for more details.
 

	
 
  You should have received a copy of the GNU General Public License
 
  along with serialplot.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#include "commandwidget.h"
 
#include "ui_commandwidget.h"
 

	
 
#include <QRegExp>
 
#include <QRegExpValidator>
 

	
 
#include <QtDebug>
 

	
 
CommandWidget::CommandWidget(QWidget *parent) :
 
    QWidget(parent),
 
    ui(new Ui::CommandWidget)
 
{
 
    ui->setupUi(this);
 

	
 
    connect(ui->pbDelete, &QPushButton::clicked, this, &CommandWidget::onDeleteClicked);
 
    connect(ui->pbSend, &QPushButton::clicked, this, &CommandWidget::onSendClicked);
 
    connect(ui->pbASCII, &QPushButton::toggled, this, &CommandWidget::onASCIIToggled);
 
}
 

	
 
CommandWidget::~CommandWidget()
 
{
 
    delete ui;
 
}
 

	
 
void CommandWidget::onDeleteClicked()
 
{
 
    this->deleteLater();
 
}
 

	
 
void CommandWidget::onSendClicked()
 
{
 
    auto command = ui->leCommand->text();
 

	
 
    if (command.isEmpty())
 
    {
 
        qWarning() << "Enter a command to send!";
 
        ui->leCommand->setFocus(Qt::OtherFocusReason);
 
        return;
 
    }
 

	
 
    if (isASCIIMode())
 
    {
 
        qDebug() << "Sending:" << command;
 
        emit sendCommand(command.toLatin1());
 
        emit sendCommand(ui->leCommand->unEscapedText().toLatin1());
 
    }
 
    else // hex mode
 
    {
 
        command = command.remove(' ');
 
        // check if nibbles are missing
 
        if (command.size() % 2 == 1)
 
        {
 
            qWarning() << "HEX command is missing a nibble at the end!";
 
            ui->leCommand->setFocus(Qt::OtherFocusReason);
 
            // highlight the byte that is missing a nibble (last byte obviously)
 
            int textSize = ui->leCommand->text().size();
 
            ui->leCommand->setSelection(textSize-1, textSize);
 
            return;
 
        }
 
        qDebug() << "Sending HEX:" << command;
 
        emit sendCommand(QByteArray::fromHex(command.toLatin1()));
 
    }
 
}
 

	
 
void CommandWidget::onASCIIToggled(bool checked)
 
{
 
    ui->leCommand->setMode(checked);
 
}
 

	
 
bool CommandWidget::isASCIIMode()
 
{
 
    return ui->pbASCII->isChecked();
 
}
0 comments (0 inline, 0 general)