Changeset - ecd02467c397
[Not reviewed]
new-reader
0 4 12
Hasan Yavuz ÖZDERYA - 9 years ago 2016-05-23 13:51:36
hy@ozderya.net
preliminary implementation of new reader based design

binary stream and ascii readers added

sps isn't working, demo mode needs some work, code cleanup continues
16 files changed with 991 insertions and 439 deletions:
0 comments (0 inline, 0 general)
CMakeLists.txt
Show inline comments
 
@@ -61,6 +61,10 @@ qt5_wrap_ui(UI_FILES
 
  src/commandwidget.ui
 
  src/dataformatpanel.ui
 
  src/plotcontrolpanel.ui
 
  src/numberformatbox.ui
 
  src/endiannessbox.ui
 
  src/binarystreamreadersettings.ui
 
  src/asciireadersettings.ui
 
  )
 

	
 
if (WIN32)
 
@@ -93,6 +97,13 @@ add_executable(${PROGRAM_NAME} WIN32
 
  src/sneakylineedit.cpp
 
  src/channelmanager.cpp
 
  src/framebufferseries.cpp
 
  src/numberformatbox.cpp
 
  src/endiannessbox.cpp
 
  src/abstractreader.cpp
 
  src/binarystreamreader.cpp
 
  src/binarystreamreadersettings.cpp
 
  src/asciireader.cpp
 
  src/asciireadersettings.cpp
 
  misc/windows_icon.rc
 
  ${UI_FILES}
 
  ${RES_FILES}
src/abstractreader.cpp
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2016 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 "abstractreader.h"
 

	
 
AbstractReader::AbstractReader(QIODevice* device, ChannelManager* channelMan, QObject *parent) :
 
    QObject(parent)
 
{
 
    _device = device;
 
    _channelMan = channelMan;
 
}
src/abstractreader.h
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2016 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 ABSTRACTREADER_H
 
#define ABSTRACTREADER_H
 

	
 
#include <QObject>
 
#include <QIODevice>
 
#include <QWidget>
 

	
 
#include "channelmanager.h"
 

	
 
/**
 
 * All reader classes must inherit this class.
 
 */
 
class AbstractReader : public QObject
 
{
 
    Q_OBJECT
 
public:
 
    explicit AbstractReader(QIODevice* device, ChannelManager* channelMan, QObject *parent = 0);
 

	
 
    /**
 
     * Returns a widget to be shown in data format panel when reader
 
     * is selected.
 
     */
 
    virtual QWidget* settingsWidget() = 0;
 

	
 
    /**
 
     * Number of channels being read.
 
     *
 
     * This number may be user selected or automatically determined
 
     * from incoming stream.
 
     */
 
    virtual unsigned numOfChannels() = 0;
 

	
 
    /// Reader should only read when enabled. Default state should be
 
    /// 'disabled'.
 
    virtual void enable(bool enabled = true) = 0;
 

	
 
signals:
 
    void numOfChannelsChanged(unsigned);
 
    // TODO: this must be signaled by 'channel man' for better abstraction
 
    void dataAdded(); ///< emitted when data added to channel man.
 
    // TODO: this should be a part of 'channel man'
 
    void samplesPerSecondChanged(unsigned);
 

	
 
public slots:
 
    /**
 
     * Pauses the reading.
 
     *
 
     * Reader should actually continue reading to keep the
 
     * synchronization but shouldn't commit data.
 
     */
 
    virtual void pause(bool) = 0;
 

	
 
protected:
 
    QIODevice* _device;
 
    ChannelManager* _channelMan;
 
};
 

	
 
#endif // ABSTRACTREADER_H
src/asciireader.cpp
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2016 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 <QtDebug>
 

	
 
#include "asciireader.h"
 

	
 
AsciiReader::AsciiReader(QIODevice* device, ChannelManager* channelMan, QObject *parent) :
 
    AbstractReader(device, channelMan, parent)
 
{
 
    paused = false;
 
    sampleCount = 0;
 
    // TODO: sps counter
 

	
 
    _numOfChannels = _settingsWidget.numOfChannels();
 
    connect(&_settingsWidget, &AsciiReaderSettings::numOfChannelsChanged,
 
            this, &AsciiReader::numOfChannelsChanged);
 
    connect(&_settingsWidget, &AsciiReaderSettings::numOfChannelsChanged,
 
            [this](unsigned value){_numOfChannels = value;});
 
}
 

	
 
QWidget* AsciiReader::settingsWidget()
 
{
 
    return &_settingsWidget;
 
}
 

	
 
unsigned AsciiReader::numOfChannels()
 
{
 
    return _numOfChannels;
 
}
 

	
 
// TODO: this could be a part of AbstractReader
 
void AsciiReader::enable(bool enabled)
 
{
 
    if (enabled)
 
    {
 
        QObject::connect(_device, &QIODevice::readyRead,
 
                         this, &AsciiReader::onDataReady);
 
    }
 
    else
 
    {
 
        QObject::disconnect(_device, 0, this, 0);
 
    }
 
}
 

	
 
void AsciiReader::pause(bool enabled)
 
{
 
    paused = enabled;
 
}
 

	
 
void AsciiReader::onDataReady()
 
{
 
    while(_device->canReadLine())
 
    {
 
        QByteArray line = _device->readLine();
 

	
 
        // discard data if paused
 
        if (paused)
 
        {
 
            return;
 
        }
 

	
 
        line = line.trimmed();
 
        auto separatedValues = line.split(',');
 

	
 
        int numReadChannels; // effective number of channels to read
 
        if (separatedValues.length() >= int(_numOfChannels))
 
        {
 
            numReadChannels = _numOfChannels;
 
        }
 
        else // there is missing channel data
 
        {
 
            numReadChannels = separatedValues.length();
 
            qWarning() << "Incoming data is missing data for some channels!";
 
        }
 

	
 
        // parse read line
 
        for (int ci = 0; ci < numReadChannels; ci++)
 
        {
 
            bool ok;
 
            double channelSample = separatedValues[ci].toDouble(&ok);
 
            if (ok)
 
            {
 
                _channelMan->addChannelData(ci, &channelSample, 1);
 
                sampleCount++;
 
            }
 
            else
 
            {
 
                qWarning() << "Data parsing error for channel: " << ci;
 
            }
 
        }
 
        emit dataAdded();
 
    }
 
}
src/asciireader.h
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2016 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 ASCIIREADER_H
 
#define ASCIIREADER_H
 

	
 
#include "abstractreader.h"
 
#include "asciireadersettings.h"
 

	
 
class AsciiReader : public AbstractReader
 
{
 
    Q_OBJECT
 

	
 
public:
 
    explicit AsciiReader(QIODevice* device, ChannelManager* channelMan, QObject *parent = 0);
 
    QWidget* settingsWidget();
 
    unsigned numOfChannels();
 
    void enable(bool enabled = true);
 

	
 
public slots:
 
    void pause(bool);
 

	
 
private:
 
    AsciiReaderSettings _settingsWidget;
 
    unsigned _numOfChannels;
 
    bool paused;
 
    unsigned sampleCount; ///< used for sps counter
 

	
 
private slots:
 
    void onDataReady();
 
};
 

	
 
#endif // ASCIIREADER_H
src/asciireadersettings.cpp
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2016 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 "utils.h"
 

	
 
#include "asciireadersettings.h"
 
#include "ui_asciireadersettings.h"
 

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

	
 
    // Note: if directly connected we get a runtime warning on incompatible signal arguments
 
    connect(ui->spNumOfChannels, SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged),
 
            [this](int value)
 
            {
 
                emit numOfChannelsChanged(value);
 
            });
 
}
 

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

	
 
unsigned AsciiReaderSettings::numOfChannels()
 
{
 
    return ui->spNumOfChannels->value();
 
}
src/asciireadersettings.h
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2016 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 ASCIIREADERSETTINGS_H
 
#define ASCIIREADERSETTINGS_H
 

	
 
#include <QWidget>
 

	
 
namespace Ui {
 
class AsciiReaderSettings;
 
}
 

	
 
class AsciiReaderSettings : public QWidget
 
{
 
    Q_OBJECT
 

	
 
public:
 
    explicit AsciiReaderSettings(QWidget *parent = 0);
 
    ~AsciiReaderSettings();
 

	
 
    unsigned numOfChannels();
 

	
 
signals:
 
    void numOfChannelsChanged(unsigned);
 

	
 
private:
 
    Ui::AsciiReaderSettings *ui;
 
};
 

	
 
#endif // ASCIIREADERSETTINGS_H
src/asciireadersettings.ui
Show inline comments
 
new file 100644
 
<?xml version="1.0" encoding="UTF-8"?>
 
<ui version="4.0">
 
 <class>AsciiReaderSettings</class>
 
 <widget class="QWidget" name="AsciiReaderSettings">
 
  <property name="geometry">
 
   <rect>
 
    <x>0</x>
 
    <y>0</y>
 
    <width>414</width>
 
    <height>171</height>
 
   </rect>
 
  </property>
 
  <property name="windowTitle">
 
   <string>Form</string>
 
  </property>
 
  <widget class="QSpinBox" name="spNumOfChannels">
 
   <property name="geometry">
 
    <rect>
 
     <x>153</x>
 
     <y>10</y>
 
     <width>60</width>
 
     <height>27</height>
 
    </rect>
 
   </property>
 
   <property name="minimumSize">
 
    <size>
 
     <width>60</width>
 
     <height>0</height>
 
    </size>
 
   </property>
 
   <property name="keyboardTracking">
 
    <bool>false</bool>
 
   </property>
 
   <property name="minimum">
 
    <number>1</number>
 
   </property>
 
   <property name="maximum">
 
    <number>32</number>
 
   </property>
 
  </widget>
 
  <widget class="QLabel" name="label_4">
 
   <property name="geometry">
 
    <rect>
 
     <x>20</x>
 
     <y>10</y>
 
     <width>127</width>
 
     <height>27</height>
 
    </rect>
 
   </property>
 
   <property name="text">
 
    <string>Number Of Channels:</string>
 
   </property>
 
  </widget>
 
 </widget>
 
 <resources/>
 
 <connections/>
 
</ui>
src/binarystreamreader.cpp
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2016 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 <QtEndian>
 
#include <QtDebug>
 

	
 
#include "binarystreamreader.h"
 
#include "floatswap.h"
 

	
 
BinaryStreamReader::BinaryStreamReader(QIODevice* device, ChannelManager* channelMan, QObject *parent) :
 
    AbstractReader(device, channelMan, parent)
 
{
 
    paused = false;
 
    skipByteRequested = false;
 
    sampleCount = 0;
 

	
 
    _numOfChannels = _settingsWidget.numOfChannels();
 
    connect(&_settingsWidget, &BinaryStreamReaderSettings::numOfChannelsChanged,
 
            this, &BinaryStreamReader::numOfChannelsChanged);
 
    connect(&_settingsWidget, &BinaryStreamReaderSettings::numOfChannelsChanged,
 
            this, &BinaryStreamReader::onNumOfChannelsChanged);
 

	
 
    // initial number format selection
 
    onNumberFormatChanged(_settingsWidget.numberFormat());
 
    connect(&_settingsWidget, &BinaryStreamReaderSettings::numberFormatChanged,
 
            this, &BinaryStreamReader::onNumberFormatChanged);
 

	
 
    // enable skip byte button
 
    connect(&_settingsWidget, &BinaryStreamReaderSettings::skipByteRequested,
 
            [this]()
 
            {
 
                skipByteRequested = true;
 
            });
 

	
 
    // TODO sps counter
 
}
 

	
 
QWidget* BinaryStreamReader::settingsWidget()
 
{
 
    return &_settingsWidget;
 
}
 

	
 
unsigned BinaryStreamReader::numOfChannels()
 
{
 
    return _numOfChannels;
 
}
 

	
 
void BinaryStreamReader::enable(bool enabled)
 
{
 
    if (enabled)
 
    {
 
        QObject::connect(_device, &QIODevice::readyRead,
 
                         this, &BinaryStreamReader::onDataReady);
 
    }
 
    else
 
    {
 
        QObject::disconnect(_device, 0, this, 0);
 
    }
 
}
 

	
 
void BinaryStreamReader::pause(bool enabled)
 
{
 
    paused = enabled;
 
}
 

	
 
void BinaryStreamReader::onNumberFormatChanged(NumberFormat numberFormat)
 
{
 
    switch(numberFormat)
 
    {
 
        case NumberFormat_uint8:
 
            sampleSize = 1;
 
            readSample = &BinaryStreamReader::readSampleAs<quint8>;
 
            break;
 
        case NumberFormat_int8:
 
            sampleSize = 1;
 
            readSample = &BinaryStreamReader::readSampleAs<qint8>;
 
            break;
 
        case NumberFormat_uint16:
 
            sampleSize = 2;
 
            readSample = &BinaryStreamReader::readSampleAs<quint16>;
 
            break;
 
        case NumberFormat_int16:
 
            sampleSize = 2;
 
            readSample = &BinaryStreamReader::readSampleAs<qint16>;
 
            break;
 
        case NumberFormat_uint32:
 
            sampleSize = 4;
 
            readSample = &BinaryStreamReader::readSampleAs<quint32>;
 
            break;
 
        case NumberFormat_int32:
 
            sampleSize = 4;
 
            readSample = &BinaryStreamReader::readSampleAs<qint32>;
 
            break;
 
        case NumberFormat_float:
 
            sampleSize = 4;
 
            readSample = &BinaryStreamReader::readSampleAs<float>;
 
            break;
 
    }
 
}
 

	
 
void BinaryStreamReader::onNumOfChannelsChanged(unsigned value)
 
{
 
    _numOfChannels = value;
 
}
 

	
 
void BinaryStreamReader::onDataReady()
 
{
 
    // a package is a set of channel data like {CHAN0_SAMPLE, CHAN1_SAMPLE...}
 
    int packageSize = sampleSize * _numOfChannels;
 
    int bytesAvailable = _device->bytesAvailable();
 
    int numOfPackagesToRead =
 
        (bytesAvailable - (bytesAvailable % packageSize)) / packageSize;
 

	
 
    if (paused)
 
    {
 
        // read and discard data
 
        _device->read(numOfPackagesToRead*packageSize);
 
        return;
 
    }
 

	
 
    if (bytesAvailable > 0 && skipByteRequested)
 
    {
 
        _device->read(1);
 
        skipByteRequested = false;
 
        bytesAvailable--;
 
    }
 

	
 
    if (bytesAvailable < packageSize) return;
 

	
 
    double* channelSamples = new double[numOfPackagesToRead*_numOfChannels];
 

	
 
    for (int i = 0; i < numOfPackagesToRead; i++)
 
    {
 
        for (unsigned int ci = 0; ci < _numOfChannels; ci++)
 
        {
 
            // channelSamples[ci].replace(i, (this->*readSample)());
 
            channelSamples[ci*numOfPackagesToRead+i] = (this->*readSample)();
 
        }
 
    }
 

	
 
    for (unsigned int ci = 0; ci < _numOfChannels; ci++)
 
    {
 
        addChannelData(ci,
 
                       channelSamples + ci*numOfPackagesToRead,
 
                       numOfPackagesToRead);
 
    }
 
    emit dataAdded();
 

	
 
    delete channelSamples;
 
}
 

	
 

	
 
template<typename T> double BinaryStreamReader::readSampleAs()
 
{
 
    T data;
 

	
 
    _device->read((char*) &data, sizeof(data));
 

	
 
    if (_settingsWidget.endianness() == LittleEndian)
 
    {
 
        data = qFromLittleEndian(data);
 
    }
 
    else
 
    {
 
        data = qFromBigEndian(data);
 
    }
 

	
 
    return double(data);
 
}
 

	
 
void BinaryStreamReader::addChannelData(unsigned int channel,
 
                                        double* data, unsigned size)
 
{
 
    _channelMan->addChannelData(channel, data, size);
 
    sampleCount += size;
 
}
src/binarystreamreader.h
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2016 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 BINARYSTREAMREADER_H
 
#define BINARYSTREAMREADER_H
 

	
 
#include "abstractreader.h"
 
#include "binarystreamreadersettings.h"
 

	
 
/**
 
 * Reads a simple stream of samples in binary form from the
 
 * device. There is no means of synchronization other than a button
 
 * that should be manually triggered by user.
 
 */
 
class BinaryStreamReader : public AbstractReader
 
{
 
    Q_OBJECT
 
public:
 
    explicit BinaryStreamReader(QIODevice* device, ChannelManager* channelMan, QObject *parent = 0);
 
    QWidget* settingsWidget();
 
    unsigned numOfChannels();
 
    void enable(bool enabled = true);
 

	
 
public slots:
 
    void pause(bool);
 

	
 
private:
 
    BinaryStreamReaderSettings _settingsWidget;
 
    unsigned _numOfChannels;
 
    unsigned sampleSize;
 
    bool paused;
 
    bool skipByteRequested;
 
    unsigned sampleCount; ///< used for sps counter
 

	
 
    /// points to the readSampleAs function for currently selected number format
 
    double (BinaryStreamReader::*readSample)();
 

	
 
    /**
 
     * Reads 1 sample from the device in given format.
 
     *
 
     * @note Device should already have enough bytes present before
 
     * calling this function.
 
     */
 
    template<typename T> double readSampleAs();
 

	
 
    // `data` contains i th channels data
 
    void addChannelData(unsigned int channel, double* data, unsigned size);
 

	
 
private slots:
 
    void onNumberFormatChanged(NumberFormat numberFormat);
 
    void onNumOfChannelsChanged(unsigned value);
 
    void onDataReady();
 
};
 

	
 
#endif // BINARYSTREAMREADER_H
src/binarystreamreadersettings.cpp
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2016 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 "binarystreamreadersettings.h"
 
#include "ui_binarystreamreadersettings.h"
 

	
 
#include "utils.h"
 

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

	
 
    // Note: if directly connected we get a runtime warning on incompatible signal arguments
 
    connect(ui->spNumOfChannels, SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged),
 
            [this](int value)
 
            {
 
                emit numOfChannelsChanged(value);
 
            });
 

	
 
    connect(ui->nfBox, SIGNAL(selectionChanged(NumberFormat)),
 
            this, SIGNAL(numberFormatChanged(NumberFormat)));
 

	
 
    connect(ui->pbSkipByte, SIGNAL(clicked()), this, SIGNAL(skipByteRequested()));
 
}
 

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

	
 
unsigned BinaryStreamReaderSettings::numOfChannels()
 
{
 
    return ui->spNumOfChannels->value();
 
}
 

	
 
NumberFormat BinaryStreamReaderSettings::numberFormat()
 
{
 
    return ui->nfBox->currentSelection();
 
}
 

	
 
Endianness BinaryStreamReaderSettings::endianness()
 
{
 
    return ui->endiBox->currentSelection();
 
}
src/binarystreamreadersettings.h
Show inline comments
 
new file 100644
 
/*
 
  Copyright © 2016 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 BINARYSTREAMREADERSETTINGS_H
 
#define BINARYSTREAMREADERSETTINGS_H
 

	
 
#include <QWidget>
 
#include "numberformatbox.h"
 
#include "endiannessbox.h"
 

	
 
namespace Ui {
 
class BinaryStreamReaderSettings;
 
}
 

	
 
class BinaryStreamReaderSettings : public QWidget
 
{
 
    Q_OBJECT
 

	
 
public:
 
    explicit BinaryStreamReaderSettings(QWidget *parent = 0);
 
    ~BinaryStreamReaderSettings();
 

	
 
    unsigned numOfChannels();
 
    NumberFormat numberFormat();
 
    Endianness endianness();
 

	
 
signals:
 
    void numOfChannelsChanged(unsigned);
 
    void numberFormatChanged(NumberFormat);
 
    void skipByteRequested();
 

	
 
private:
 
    Ui::BinaryStreamReaderSettings *ui;
 
};
 

	
 
#endif // BINARYSTREAMREADERSETTINGS_H
src/binarystreamreadersettings.ui
Show inline comments
 
new file 100644
 
<?xml version="1.0" encoding="UTF-8"?>
 
<ui version="4.0">
 
 <class>BinaryStreamReaderSettings</class>
 
 <widget class="QWidget" name="BinaryStreamReaderSettings">
 
  <property name="geometry">
 
   <rect>
 
    <x>0</x>
 
    <y>0</y>
 
    <width>432</width>
 
    <height>203</height>
 
   </rect>
 
  </property>
 
  <property name="windowTitle">
 
   <string>Form</string>
 
  </property>
 
  <widget class="QLabel" name="label_4">
 
   <property name="geometry">
 
    <rect>
 
     <x>17</x>
 
     <y>10</y>
 
     <width>127</width>
 
     <height>27</height>
 
    </rect>
 
   </property>
 
   <property name="text">
 
    <string>Number Of Channels:</string>
 
   </property>
 
  </widget>
 
  <widget class="QSpinBox" name="spNumOfChannels">
 
   <property name="geometry">
 
    <rect>
 
     <x>150</x>
 
     <y>10</y>
 
     <width>60</width>
 
     <height>27</height>
 
    </rect>
 
   </property>
 
   <property name="minimumSize">
 
    <size>
 
     <width>60</width>
 
     <height>0</height>
 
    </size>
 
   </property>
 
   <property name="keyboardTracking">
 
    <bool>false</bool>
 
   </property>
 
   <property name="minimum">
 
    <number>1</number>
 
   </property>
 
   <property name="maximum">
 
    <number>32</number>
 
   </property>
 
  </widget>
 
  <widget class="NumberFormatBox" name="nfBox" native="true">
 
   <property name="geometry">
 
    <rect>
 
     <x>20</x>
 
     <y>50</y>
 
     <width>161</width>
 
     <height>141</height>
 
    </rect>
 
   </property>
 
  </widget>
 
  <widget class="EndiannessBox" name="endiBox" native="true">
 
   <property name="geometry">
 
    <rect>
 
     <x>190</x>
 
     <y>50</y>
 
     <width>120</width>
 
     <height>80</height>
 
    </rect>
 
   </property>
 
  </widget>
 
  <widget class="QPushButton" name="pbSkipByte">
 
   <property name="geometry">
 
    <rect>
 
     <x>220</x>
 
     <y>10</y>
 
     <width>85</width>
 
     <height>27</height>
 
    </rect>
 
   </property>
 
   <property name="toolTip">
 
    <string>Skip reading 1 byte to correct the alignment</string>
 
   </property>
 
   <property name="text">
 
    <string>Skip Byte</string>
 
   </property>
 
  </widget>
 
 </widget>
 
 <customwidgets>
 
  <customwidget>
 
   <class>NumberFormatBox</class>
 
   <extends>QWidget</extends>
 
   <header>numberformatbox.h</header>
 
   <container>1</container>
 
  </customwidget>
 
  <customwidget>
 
   <class>EndiannessBox</class>
 
   <extends>QWidget</extends>
 
   <header>endiannessbox.h</header>
 
   <container>1</container>
 
  </customwidget>
 
 </customwidgets>
 
 <resources/>
 
 <connections/>
 
</ui>
src/dataformatpanel.cpp
Show inline comments
 
@@ -20,6 +20,7 @@
 
#include "dataformatpanel.h"
 
#include "ui_dataformatpanel.h"
 

	
 
#include <QRadioButton>
 
#include <QtEndian>
 
#include <QtDebug>
 

	
 
@@ -30,7 +31,9 @@ DataFormatPanel::DataFormatPanel(QSerial
 
                                 ChannelManager* channelMan,
 
                                 QWidget *parent) :
 
    QWidget(parent),
 
    ui(new Ui::DataFormatPanel)
 
    ui(new Ui::DataFormatPanel),
 
    bsReader(port, channelMan),
 
    asciiReader(port, channelMan)
 
{
 
    ui->setupUi(this);
 

	
 
@@ -38,35 +41,31 @@ DataFormatPanel::DataFormatPanel(QSerial
 
    _channelMan = channelMan;
 
    paused = false;
 

	
 
    // setup number format buttons
 
    numberFormatButtons.addButton(ui->rbUint8,  NumberFormat_uint8);
 
    numberFormatButtons.addButton(ui->rbUint16, NumberFormat_uint16);
 
    numberFormatButtons.addButton(ui->rbUint32, NumberFormat_uint32);
 
    numberFormatButtons.addButton(ui->rbInt8,   NumberFormat_int8);
 
    numberFormatButtons.addButton(ui->rbInt16,  NumberFormat_int16);
 
    numberFormatButtons.addButton(ui->rbInt32,  NumberFormat_int32);
 
    numberFormatButtons.addButton(ui->rbFloat,  NumberFormat_float);
 
    numberFormatButtons.addButton(ui->rbASCII,  NumberFormat_ASCII);
 
    // initalize default reader
 
    currentReader = &bsReader;
 
    bsReader.enable();
 
    ui->rbBinary->setChecked(true);
 
    ui->horizontalLayout->addWidget(bsReader.settingsWidget(), 1);
 
    connect(&bsReader, SIGNAL(dataAdded()), this, SIGNAL(dataAdded()));
 
    connect(&bsReader, SIGNAL(numOfChannelsChanged(unsigned)),
 
            this, SIGNAL(numOfChannelsChanged(unsigned)));
 

	
 
    QObject::connect(
 
        &numberFormatButtons, SIGNAL(buttonToggled(int, bool)),
 
        this, SLOT(onNumberFormatButtonToggled(int, bool)));
 

	
 
    // init number format
 
    selectNumberFormat((NumberFormat) numberFormatButtons.checkedId());
 
    // initalize reader selection buttons
 
    connect(ui->rbBinary, &QRadioButton::toggled, [this](bool checked)
 
            {
 
                if (checked) selectReader(&bsReader);
 
            });
 

	
 
    // setup number of channels spinbox
 
    QObject::connect(ui->spNumOfChannels,
 
                     SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged),
 
                     this, &DataFormatPanel::onNumOfChannelsSP);
 

	
 
    _numOfChannels = ui->spNumOfChannels->value();
 
    connect(ui->rbAscii, &QRadioButton::toggled, [this](bool checked)
 
            {
 
                if (checked) selectReader(&asciiReader);
 
            });
 

	
 
    // Init sps (sample per second) counter
 
    sampleCount = 0;
 
    QObject::connect(&spsTimer, &QTimer::timeout,
 
                     this, &DataFormatPanel::spsTimerTimeout);
 
    spsTimer.start(SPS_UPDATE_TIMEOUT * 1000);
 
    // sampleCount = 0;
 
    // QObject::connect(&spsTimer, &QTimer::timeout,
 
    //                  this, &DataFormatPanel::spsTimerTimeout);
 
    // spsTimer.start(SPS_UPDATE_TIMEOUT * 1000);
 

	
 
    // Init demo mode
 
    demoCount = 0;
 
@@ -80,84 +79,18 @@ DataFormatPanel::~DataFormatPanel()
 
    delete ui;
 
}
 

	
 
void DataFormatPanel::onNumberFormatButtonToggled(int numberFormatId,
 
                                                  bool checked)
 
{
 
    if (checked) selectNumberFormat((NumberFormat) numberFormatId);
 
}
 

	
 
void DataFormatPanel::selectNumberFormat(NumberFormat numberFormatId)
 
{
 
    numberFormat = numberFormatId;
 

	
 
    switch(numberFormat)
 
    {
 
        case NumberFormat_uint8:
 
            sampleSize = 1;
 
            readSample = &DataFormatPanel::readSampleAs<quint8>;
 
            break;
 
        case NumberFormat_int8:
 
            sampleSize = 1;
 
            readSample = &DataFormatPanel::readSampleAs<qint8>;
 
            break;
 
        case NumberFormat_uint16:
 
            sampleSize = 2;
 
            readSample = &DataFormatPanel::readSampleAs<quint16>;
 
            break;
 
        case NumberFormat_int16:
 
            sampleSize = 2;
 
            readSample = &DataFormatPanel::readSampleAs<qint16>;
 
            break;
 
        case NumberFormat_uint32:
 
            sampleSize = 4;
 
            readSample = &DataFormatPanel::readSampleAs<quint32>;
 
            break;
 
        case NumberFormat_int32:
 
            sampleSize = 4;
 
            readSample = &DataFormatPanel::readSampleAs<qint32>;
 
            break;
 
        case NumberFormat_float:
 
            sampleSize = 4;
 
            readSample = &DataFormatPanel::readSampleAs<float>;
 
            break;
 
        case NumberFormat_ASCII:
 
            sampleSize = 0;    // these two members should not be used
 
            readSample = NULL; // in this mode
 
            break;
 
    }
 

	
 
    if (numberFormat == NumberFormat_ASCII)
 
    {
 
        QObject::disconnect(serialPort, &QSerialPort::readyRead, 0, 0);
 
        QObject::connect(this->serialPort, &QSerialPort::readyRead,
 
                         this, &DataFormatPanel::onDataReadyASCII);
 
    }
 
    else
 
    {
 
        QObject::disconnect(serialPort, &QSerialPort::readyRead, 0, 0);
 
        QObject::connect(serialPort, &QSerialPort::readyRead,
 
                         this, &DataFormatPanel::onDataReady);
 
    }
 

	
 
    emit skipByteEnabledChanged(skipByteEnabled());
 
}
 

	
 
// TODO: remove
 
bool DataFormatPanel::skipByteEnabled()
 
{
 
    return numberFormat != NumberFormat_ASCII;
 
    return false;
 
}
 

	
 
unsigned DataFormatPanel::numOfChannels()
 
{
 
    return _numOfChannels;
 
    return currentReader->numOfChannels();
 
}
 

	
 
void DataFormatPanel::onNumOfChannelsSP(int value)
 
{
 
    _numOfChannels = value;
 
    emit numOfChannelsChanged(value);
 
}
 

	
 
// TODO: remove
 
void DataFormatPanel::requestSkipByte()
 
{
 
    skipByteRequested = true;
 
@@ -165,7 +98,7 @@ void DataFormatPanel::requestSkipByte()
 

	
 
void DataFormatPanel::pause(bool enabled)
 
{
 
    paused = enabled;
 
    currentReader->pause(enabled);
 
}
 

	
 
void DataFormatPanel::enableDemo(bool enabled)
 
@@ -182,16 +115,15 @@ void DataFormatPanel::enableDemo(bool en
 

	
 
void DataFormatPanel::spsTimerTimeout()
 
{
 
    unsigned currentSps = _samplesPerSecond;
 
    _samplesPerSecond = (sampleCount/_numOfChannels)/SPS_UPDATE_TIMEOUT;
 
    if (currentSps != _samplesPerSecond)
 
    {
 
        emit samplesPerSecondChanged(_samplesPerSecond);
 
    }
 
    sampleCount = 0;
 
    // unsigned currentSps = _samplesPerSecond;
 
    // _samplesPerSecond = (sampleCount/_numOfChannels)/SPS_UPDATE_TIMEOUT;
 
    // if (currentSps != _samplesPerSecond)
 
    // {
 
    //     emit samplesPerSecondChanged(_samplesPerSecond);
 
    // }
 
    // sampleCount = 0;
 
}
 

	
 

	
 
void DataFormatPanel::demoTimerTimeout()
 
{
 
    const double period = 100;
 
@@ -200,7 +132,7 @@ void DataFormatPanel::demoTimerTimeout()
 

	
 
    if (!paused)
 
    {
 
        for (unsigned ci = 0; ci < _numOfChannels; ci++)
 
        for (unsigned ci = 0; ci < currentReader->numOfChannels(); ci++)
 
        {
 
            // we are calculating the fourier components of square wave
 
            double value = 4*sin(2*M_PI*double((ci+1)*demoCount)/period)/((2*(ci+1))*M_PI);
 
@@ -210,116 +142,29 @@ void DataFormatPanel::demoTimerTimeout()
 
    }
 
}
 

	
 
void DataFormatPanel::onDataReady()
 
{
 
    // a package is a set of channel data like {CHAN0_SAMPLE, CHAN1_SAMPLE...}
 
    int packageSize = sampleSize * _numOfChannels;
 
    int bytesAvailable = serialPort->bytesAvailable();
 
    int numOfPackagesToRead =
 
        (bytesAvailable - (bytesAvailable % packageSize)) / packageSize;
 

	
 
    if (paused)
 
    {
 
        // read and discard data
 
        serialPort->read(numOfPackagesToRead*packageSize);
 
        return;
 
    }
 

	
 
    if (bytesAvailable > 0 && skipByteRequested)
 
    {
 
        serialPort->read(1);
 
        skipByteRequested = false;
 
        bytesAvailable--;
 
    }
 

	
 
    if (bytesAvailable < packageSize) return;
 

	
 
    double* channelSamples = new double[numOfPackagesToRead*_numOfChannels];
 

	
 
    for (int i = 0; i < numOfPackagesToRead; i++)
 
    {
 
        for (unsigned int ci = 0; ci < _numOfChannels; ci++)
 
        {
 
            // channelSamples[ci].replace(i, (this->*readSample)());
 
            channelSamples[ci*numOfPackagesToRead+i] = (this->*readSample)();
 
        }
 
    }
 

	
 
    for (unsigned int ci = 0; ci < _numOfChannels; ci++)
 
    {
 
        addChannelData(ci,
 
                       channelSamples + ci*numOfPackagesToRead,
 
                       numOfPackagesToRead);
 
    }
 
    emit dataAdded();
 

	
 
    delete channelSamples;
 
}
 

	
 
void DataFormatPanel::onDataReadyASCII()
 
{
 
    while(serialPort->canReadLine())
 
    {
 
        QByteArray line = serialPort->readLine();
 

	
 
        // discard data if paused
 
        if (paused)
 
        {
 
            return;
 
        }
 

	
 
        line = line.trimmed();
 
        auto separatedValues = line.split(',');
 

	
 
        int numReadChannels; // effective number of channels to read
 
        if (separatedValues.length() >= int(_numOfChannels))
 
        {
 
            numReadChannels = _numOfChannels;
 
        }
 
        else // there is missing channel data
 
        {
 
            numReadChannels = separatedValues.length();
 
            qWarning() << "Incoming data is missing data for some channels!";
 
        }
 

	
 
        // parse read line
 
        for (int ci = 0; ci < numReadChannels; ci++)
 
        {
 
            bool ok;
 
            double channelSample = separatedValues[ci].toDouble(&ok);
 
            if (ok)
 
            {
 
                addChannelData(ci, &channelSample, 1);
 
            }
 
            else
 
            {
 
                qWarning() << "Data parsing error for channel: " << ci;
 
            }
 
        }
 
        emit dataAdded();
 
    }
 
}
 

	
 
template<typename T> double DataFormatPanel::readSampleAs()
 
{
 
    T data;
 
    serialPort->read((char*) &data, sizeof(data));
 

	
 
    if (ui->rbLittleE->isChecked())
 
    {
 
        data = qFromLittleEndian(data);
 
    }
 
    else
 
    {
 
        data = qFromBigEndian(data);
 
    }
 

	
 
    return double(data);
 
}
 

	
 
void DataFormatPanel::addChannelData(unsigned int channel,
 
                                     double* data, unsigned size)
 
{
 
    _channelMan->addChannelData(channel, data, size);
 
    sampleCount += size;
 
}
 

	
 
void DataFormatPanel::selectReader(AbstractReader* reader)
 
{
 
    currentReader->enable(false);
 
    reader->enable();
 

	
 
    // re-connect signals
 
    disconnect(currentReader, 0, this, 0);
 
    connect(reader, SIGNAL(dataAdded()), this, SIGNAL(dataAdded()));
 
    connect(reader, SIGNAL(numOfChannelsChanged(unsigned)),
 
            this, SIGNAL(numOfChannelsChanged(unsigned)));
 

	
 
    // switch the settings widget
 
    ui->horizontalLayout->removeWidget(currentReader->settingsWidget());
 
    currentReader->settingsWidget()->hide();
 
    ui->horizontalLayout->addWidget(reader->settingsWidget(), 1);
 
    reader->settingsWidget()->show();
 

	
 
    currentReader = reader;
 
}
src/dataformatpanel.h
Show inline comments
 
@@ -29,6 +29,8 @@
 

	
 
#include "framebuffer.h"
 
#include "channelmanager.h"
 
#include "binarystreamreader.h"
 
#include "asciireader.h"
 

	
 
namespace Ui {
 
class DataFormatPanel;
 
@@ -58,33 +60,24 @@ public slots:
 
signals:
 
    void numOfChannelsChanged(unsigned);
 
    void samplesPerSecondChanged(unsigned);
 
    void skipByteEnabledChanged(bool);
 
    void skipByteEnabledChanged(bool); // remove
 
    void dataAdded();
 

	
 
private:
 
    enum NumberFormat
 
    {
 
        NumberFormat_uint8,
 
        NumberFormat_uint16,
 
        NumberFormat_uint32,
 
        NumberFormat_int8,
 
        NumberFormat_int16,
 
        NumberFormat_int32,
 
        NumberFormat_float,
 
        NumberFormat_ASCII
 
    };
 

	
 
    Ui::DataFormatPanel *ui;
 
    QButtonGroup numberFormatButtons;
 

	
 
    QSerialPort* serialPort;
 
    ChannelManager* _channelMan;
 

	
 
    unsigned int _numOfChannels;
 
    NumberFormat numberFormat;
 
    unsigned int sampleSize; // number of bytes in the selected number format
 
    bool skipByteRequested;
 
    bool paused;
 
    BinaryStreamReader bsReader;
 
    AsciiReader asciiReader;
 
    /// Currently selected reader
 
    AbstractReader* currentReader;
 
    /// Disable current reader and enable a another one
 
    void selectReader(AbstractReader* reader);
 

	
 
    bool skipByteRequested; // remove
 
    bool paused; // remove
 

	
 
    const int SPS_UPDATE_TIMEOUT = 1;  // second
 
    unsigned _samplesPerSecond;
 
@@ -95,22 +88,10 @@ private:
 
    QTimer demoTimer;
 
    int demoCount;
 

	
 
    void selectNumberFormat(NumberFormat numberFormatId);
 

	
 
    // points to the readSampleAs function for currently selected number format
 
    double (DataFormatPanel::*readSample)();
 

	
 
    // note that serialPort should already have enough bytes present
 
    template<typename T> double readSampleAs();
 

	
 
    // `data` contains i th channels data
 
    void addChannelData(unsigned int channel, double* data, unsigned size);
 

	
 
private slots:
 
    void onDataReady();      // used with binary number formats
 
    void onDataReadyASCII(); // used with ASCII number format
 
    void onNumberFormatButtonToggled(int numberFormatId, bool checked);
 
    void onNumOfChannelsSP(int value);
 
    void spsTimerTimeout();
 
    void demoTimerTimeout();
 
};
src/dataformatpanel.ui
Show inline comments
 
@@ -15,195 +15,22 @@
 
  </property>
 
  <layout class="QHBoxLayout" name="horizontalLayout">
 
   <item>
 
    <layout class="QFormLayout" name="formLayout_3">
 
     <item row="0" column="0">
 
      <widget class="QLabel" name="label_4">
 
    <layout class="QVBoxLayout" name="vlRadioButtons">
 
     <item>
 
      <widget class="QRadioButton" name="rbBinary">
 
       <property name="text">
 
        <string>Number Of Channels:</string>
 
        <string>Simple Binary</string>
 
       </property>
 
      </widget>
 
     </item>
 
     <item row="0" column="1">
 
      <widget class="QSpinBox" name="spNumOfChannels">
 
       <property name="minimumSize">
 
        <size>
 
         <width>60</width>
 
         <height>0</height>
 
        </size>
 
       </property>
 
       <property name="keyboardTracking">
 
        <bool>false</bool>
 
       </property>
 
       <property name="minimum">
 
        <number>1</number>
 
       </property>
 
       <property name="maximum">
 
        <number>32</number>
 
       <property name="checked">
 
        <bool>true</bool>
 
       </property>
 
      </widget>
 
     </item>
 
    </layout>
 
   </item>
 
   <item>
 
    <widget class="Line" name="line_2">
 
     <property name="orientation">
 
      <enum>Qt::Vertical</enum>
 
     </property>
 
    </widget>
 
   </item>
 
   <item>
 
    <layout class="QVBoxLayout" name="verticalLayout_5">
 
     <property name="leftMargin">
 
      <number>0</number>
 
     </property>
 
     <item>
 
      <widget class="QGroupBox" name="groupBox">
 
       <property name="title">
 
        <string>Number Format:</string>
 
      <widget class="QRadioButton" name="rbAscii">
 
       <property name="text">
 
        <string>ASCII</string>
 
       </property>
 
       <layout class="QGridLayout" name="gridLayout_2">
 
        <item row="2" column="0">
 
         <widget class="QRadioButton" name="rbUint32">
 
          <property name="toolTip">
 
           <string>unsigned 4 bytes integer</string>
 
          </property>
 
          <property name="text">
 
           <string>uint32</string>
 
          </property>
 
         </widget>
 
        </item>
 
        <item row="0" column="1">
 
         <widget class="QRadioButton" name="rbInt8">
 
          <property name="toolTip">
 
           <string>signed 1 byte integer</string>
 
          </property>
 
          <property name="text">
 
           <string>int8</string>
 
          </property>
 
         </widget>
 
        </item>
 
        <item row="0" column="0">
 
         <widget class="QRadioButton" name="rbUint8">
 
          <property name="toolTip">
 
           <string>unsigned 1 byte integer</string>
 
          </property>
 
          <property name="text">
 
           <string>uint8</string>
 
          </property>
 
          <property name="checked">
 
           <bool>true</bool>
 
          </property>
 
         </widget>
 
        </item>
 
        <item row="3" column="1">
 
         <widget class="QRadioButton" name="rbASCII">
 
          <property name="toolTip">
 
           <string>Comma Separated Values</string>
 
          </property>
 
          <property name="text">
 
           <string>ASCII(CSV)</string>
 
          </property>
 
         </widget>
 
        </item>
 
        <item row="1" column="1">
 
         <widget class="QRadioButton" name="rbInt16">
 
          <property name="toolTip">
 
           <string>signed 2 bytes integer</string>
 
          </property>
 
          <property name="text">
 
           <string>int16</string>
 
          </property>
 
         </widget>
 
        </item>
 
        <item row="2" column="1">
 
         <widget class="QRadioButton" name="rbInt32">
 
          <property name="toolTip">
 
           <string>signed 4 bytes integer</string>
 
          </property>
 
          <property name="text">
 
           <string>int32</string>
 
          </property>
 
         </widget>
 
        </item>
 
        <item row="3" column="0">
 
         <widget class="QRadioButton" name="rbFloat">
 
          <property name="toolTip">
 
           <string>4 bytes floating point number</string>
 
          </property>
 
          <property name="text">
 
           <string>float</string>
 
          </property>
 
         </widget>
 
        </item>
 
        <item row="1" column="0">
 
         <widget class="QRadioButton" name="rbUint16">
 
          <property name="toolTip">
 
           <string>unsigned 2 bytes integer</string>
 
          </property>
 
          <property name="text">
 
           <string>uint16</string>
 
          </property>
 
         </widget>
 
        </item>
 
       </layout>
 
      </widget>
 
     </item>
 
     <item>
 
      <spacer name="verticalSpacer_2">
 
       <property name="orientation">
 
        <enum>Qt::Vertical</enum>
 
       </property>
 
       <property name="sizeHint" stdset="0">
 
        <size>
 
         <width>20</width>
 
         <height>1</height>
 
        </size>
 
       </property>
 
      </spacer>
 
     </item>
 
    </layout>
 
   </item>
 
   <item>
 
    <layout class="QVBoxLayout" name="verticalLayout_4">
 
     <property name="leftMargin">
 
      <number>0</number>
 
     </property>
 
     <item>
 
      <widget class="QGroupBox" name="groupBox_2">
 
       <property name="sizePolicy">
 
        <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
 
         <horstretch>0</horstretch>
 
         <verstretch>0</verstretch>
 
        </sizepolicy>
 
       </property>
 
       <property name="title">
 
        <string>Byte Order:</string>
 
       </property>
 
       <layout class="QVBoxLayout" name="verticalLayout">
 
        <item>
 
         <widget class="QRadioButton" name="rbLittleE">
 
          <property name="toolTip">
 
           <string>least significant byte first</string>
 
          </property>
 
          <property name="text">
 
           <string>Little Endian</string>
 
          </property>
 
          <property name="checked">
 
           <bool>true</bool>
 
          </property>
 
         </widget>
 
        </item>
 
        <item>
 
         <widget class="QRadioButton" name="rbBigE">
 
          <property name="toolTip">
 
           <string>most significant byte first</string>
 
          </property>
 
          <property name="text">
 
           <string>Big Endian</string>
 
          </property>
 
         </widget>
 
        </item>
 
       </layout>
 
      </widget>
 
     </item>
 
     <item>
 
@@ -214,7 +41,7 @@
 
       <property name="sizeHint" stdset="0">
 
        <size>
 
         <width>20</width>
 
         <height>1</height>
 
         <height>40</height>
 
        </size>
 
       </property>
 
      </spacer>
 
@@ -222,20 +49,11 @@
 
    </layout>
 
   </item>
 
   <item>
 
    <spacer name="horizontalSpacer_3">
 
    <widget class="Line" name="line">
 
     <property name="orientation">
 
      <enum>Qt::Horizontal</enum>
 
     </property>
 
     <property name="sizeType">
 
      <enum>QSizePolicy::MinimumExpanding</enum>
 
      <enum>Qt::Vertical</enum>
 
     </property>
 
     <property name="sizeHint" stdset="0">
 
      <size>
 
       <width>37</width>
 
       <height>20</height>
 
      </size>
 
     </property>
 
    </spacer>
 
    </widget>
 
   </item>
 
  </layout>
 
 </widget>
0 comments (0 inline, 0 general)