Changeset - 1a05d0ad46b0
[Not reviewed]
Hasan Yavuz ÖZDERYA - 10 years ago 2016-03-21 18:28:28
hy@ozderya.net
integrated preliminary implementation of channelmanager

channel name list is a loose widget, code is still a mess
10 files changed with 293 insertions and 43 deletions:
0 comments (0 inline, 0 general)
CMakeLists.txt
Show inline comments
 
@@ -89,6 +89,7 @@ add_executable(${PROGRAM_NAME} WIN32
 
  src/dataformatpanel.cpp
 
  src/tooltipfilter.cpp
 
  src/sneakylineedit.cpp
 
  src/channelmanager.cpp
 
  misc/windows_icon.rc
 
  ${UI_FILES}
 
  ${RES_FILES}
serialplot.pro
Show inline comments
 
@@ -52,7 +52,8 @@ SOURCES += \
 
    src/commandedit.cpp \
 
    src/dataformatpanel.cpp \
 
    src/tooltipfilter.cpp \
 
    src/sneakylineedit.cpp
 
    src/sneakylineedit.cpp \
 
    src/channelmanager.cpp
 

	
 
HEADERS += \
 
    src/mainwindow.h \
 
@@ -75,7 +76,8 @@ HEADERS += \
 
    src/commandedit.h \
 
    src/dataformatpanel.h \
 
    src/tooltipfilter.h \
 
    src/sneakylineedit.h
 
    src/sneakylineedit.h \
 
    src/channelmanager.h
 

	
 
FORMS += \
 
    src/mainwindow.ui \
src/channelmanager.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 "channelmanager.h"
 

	
 
#include <QStringList>
 
#include <QModelIndex>
 

	
 
ChannelManager::ChannelManager(unsigned numberOfChannels, unsigned numberOfSamples, QObject *parent) :
 
    QObject(parent)
 
{
 
    _numOfChannels = numberOfChannels;
 
    _numOfSamples = numberOfSamples;
 

	
 
    QStringList channelNamesList;
 

	
 
    for (unsigned int i = 0; i < numberOfChannels; i++)
 
    {
 
        channelBuffers.append(new FrameBuffer(numberOfSamples));
 
        channelNamesList << QString("Channel %1").arg(i+1);
 

	
 
        // curves.append(new QwtPlotCurve(QString("Channel %1").arg(i+1)));
 
        // curves[i]->setSamples(channelBuffers[i]);
 
        // curves[i]->setPen(Plot::makeColor(i));
 
        // curves[i]->attach(ui->plot);
 
    }
 

	
 
    _channelNames.setStringList(channelNamesList);
 

	
 
    connect(&_channelNames, &QStringListModel::dataChanged,
 
            this, &ChannelManager::onChannelNameDataChange);
 
}
 

	
 
ChannelManager::~ChannelManager()
 
{
 
    // TODO: remove all channelBuffers
 
}
 

	
 
unsigned ChannelManager::numOfChannels()
 
{
 
    return channelBuffers.size();
 
}
 

	
 
unsigned ChannelManager::numOfSamples()
 
{
 
    return _numOfSamples;
 
}
 

	
 
void ChannelManager::setNumOfChannels(unsigned number)
 
{
 
    unsigned int oldNum = channelBuffers.size();
 

	
 
    if (number > oldNum)
 
    {
 
        // add new channels
 
        for (unsigned int i = 0; i < number - oldNum; i++)
 
        {
 
            channelBuffers.append(new FrameBuffer(_numOfSamples));
 
            addChannelName(QString("Channel %1").arg(oldNum+i+1));
 
        }
 
    }
 
    else if(number < oldNum)
 
    {
 
        // remove channels
 
        for (unsigned int i = 0; i < oldNum - number; i++)
 
        {
 
            // also deletes owned FrameBuffer
 
            // delete curves.takeLast();
 
            // TODO: important, remove channelBuffer
 
            channelBuffers.removeLast();
 
        }
 
    }
 

	
 
    emit numOfChannelsChanged(number);
 
}
 

	
 
void ChannelManager::setNumOfSamples(unsigned number)
 
{
 
    _numOfSamples = number;
 

	
 
    for (int ci = 0; ci < channelBuffers.size(); ci++)
 
    {
 
        channelBuffers[ci]->resize(_numOfSamples);
 
    }
 

	
 
    emit numOfSamplesChanged(number);
 
}
 

	
 
FrameBuffer* ChannelManager::channelBuffer(unsigned channel)
 
{
 
    return channelBuffers[channel];
 
}
 

	
 
QStringListModel* ChannelManager::channelNames()
 
{
 
    return &_channelNames;
 
}
 

	
 
QString ChannelManager::channelName(unsigned channel)
 
{
 
    return _channelNames.data(_channelNames.index(channel, 0), Qt::DisplayRole).toString();
 
}
 

	
 
void ChannelManager::setChannelName(unsigned channel, QString name)
 
{
 
    _channelNames.setData(_channelNames.index(channel, 0), QVariant(name), Qt::DisplayRole);
 
}
 

	
 
void ChannelManager::addChannelName(QString name)
 
{
 
    _channelNames.insertRow(_channelNames.rowCount());
 
    setChannelName(_channelNames.rowCount()-1, name);
 
}
 

	
 
void ChannelManager::onChannelNameDataChange(const QModelIndex & topLeft,
 
                                             const QModelIndex & bottomRight,
 
                                             const QVector<int> & roles)
 
{
 
    int start = topLeft.row();
 
    int end = bottomRight.row();
 

	
 
    // TODO: maybe check `roles` parameter, can't think of a reason for current use case
 
    for (int i = start; i <= end; i++)
 
    {
 
        emit channelNameChanged(i, channelName(i));
 
    }
 
}
 

	
 
void ChannelManager::addChannelData(unsigned channel, double* data, unsigned size)
 
{
 
    channelBuffer(channel)->addSamples(data, size);
 
}
src/channelmanager.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 CHANNELMANAGER_H
 
#define CHANNELMANAGER_H
 

	
 
#include <QObject>
 
#include <QStringListModel>
 
#include <QModelIndex>
 
#include <QVector>
 

	
 
#include "framebuffer.h"
 

	
 
class ChannelManager : public QObject
 
{
 
    Q_OBJECT
 
public:
 
    explicit ChannelManager(unsigned numberOfChannels, unsigned numberOfSamples, QObject *parent = 0);
 
    ~ChannelManager();
 

	
 
    unsigned numOfChannels();
 
    unsigned numOfSamples();
 
    FrameBuffer* channelBuffer(unsigned channel);
 
    QStringListModel* channelNames();
 
    QString channelName(unsigned channel);
 

	
 
signals:
 
    void numOfChannelsChanged(unsigned value);
 
    void numOfSamplesChanged(unsigned value);
 
    void channelNameChanged(unsigned channel, QString name);
 

	
 
public slots:
 
    void setNumOfChannels(unsigned number);
 
    void setNumOfSamples(unsigned number);
 
    void setChannelName(unsigned channel, QString name);
 
    void addChannelData(unsigned channel, double* data, unsigned size);
 

	
 
private:
 
    unsigned _numOfChannels;
 
    unsigned _numOfSamples;
 
    QList<FrameBuffer*> channelBuffers;
 
    QStringListModel _channelNames;
 

	
 
    void addChannelName(QString name); /// appends a new channel name at the end of list
 

	
 
private slots:
 
    void onChannelNameDataChange(const QModelIndex & topLeft,
 
                                 const QModelIndex & bottomRight,
 
                                 const QVector<int> & roles = QVector<int> ());
 
};
 

	
 
#endif // CHANNELMANAGER_H
src/dataformatpanel.cpp
Show inline comments
 
@@ -26,7 +26,7 @@
 
#include "floatswap.h"
 

	
 
DataFormatPanel::DataFormatPanel(QSerialPort* port,
 
                                 QList<FrameBuffer*>* channelBuffers,
 
                                 ChannelManager* channelMan,
 
                                 QWidget *parent) :
 
    QWidget(parent),
 
    ui(new Ui::DataFormatPanel)
 
@@ -34,7 +34,7 @@ DataFormatPanel::DataFormatPanel(QSerial
 
    ui->setupUi(this);
 

	
 
    serialPort = port;
 
    _channelBuffers = channelBuffers;
 
    _channelMan = channelMan;
 
    paused = false;
 

	
 
    // setup number format buttons
 
@@ -319,6 +319,6 @@ template<typename T> double DataFormatPa
 
void DataFormatPanel::addChannelData(unsigned int channel,
 
                                     double* data, unsigned size)
 
{
 
    (*_channelBuffers)[channel]->addSamples(data, size);
 
    _channelMan->addChannelData(channel, data, size);
 
    sampleCount += size;
 
}
src/dataformatpanel.h
Show inline comments
 
@@ -28,6 +28,7 @@
 
#include <QtGlobal>
 

	
 
#include "framebuffer.h"
 
#include "channelmanager.h"
 

	
 
namespace Ui {
 
class DataFormatPanel;
 
@@ -39,7 +40,7 @@ class DataFormatPanel : public QWidget
 

	
 
public:
 
    explicit DataFormatPanel(QSerialPort* port,
 
                             QList<FrameBuffer*>* channelBuffers,
 
                             ChannelManager* channelMan,
 
                             QWidget *parent = 0);
 
    ~DataFormatPanel();
 

	
 
@@ -77,7 +78,7 @@ private:
 
    QButtonGroup numberFormatButtons;
 

	
 
    QSerialPort* serialPort;
 
    QList<FrameBuffer*>* _channelBuffers;
 
    ChannelManager* _channelMan;
 

	
 
    unsigned int _numOfChannels;
 
    NumberFormat numberFormat;
src/mainwindow.cpp
Show inline comments
 
@@ -31,6 +31,9 @@
 
#include <cmath>
 
#include <iostream>
 

	
 
// test code
 
#include <QListView>
 

	
 
#include <plot.h>
 

	
 
#include "utils.h"
 
@@ -54,9 +57,10 @@ MainWindow::MainWindow(QWidget *parent) 
 
    ui(new Ui::MainWindow),
 
    aboutDialog(this),
 
    portControl(&serialPort),
 
    channelMan(1, 1, this),
 
    commandPanel(&serialPort),
 
    dataFormatPanel(&serialPort, &channelBuffers),
 
    snapshotMan(this, &channelBuffers)
 
    dataFormatPanel(&serialPort, &channelMan),
 
    snapshotMan(this, &channelMan)
 
{
 
    ui->setupUi(this);
 
    ui->tabWidget->insertTab(0, &portControl, "Port");
 
@@ -148,17 +152,28 @@ MainWindow::MainWindow(QWidget *parent) 
 
    numOfSamples = ui->spNumOfSamples->value();
 
    unsigned numOfChannels = dataFormatPanel.numOfChannels();
 

	
 
    QObject::connect(&dataFormatPanel,
 
                     &DataFormatPanel::numOfChannelsChanged,
 
                     this,
 
                     &MainWindow::onNumOfChannelsChanged);
 
    channelMan.setNumOfSamples(ui->spNumOfSamples->value());
 
    channelMan.setNumOfChannels(dataFormatPanel.numOfChannels());
 

	
 
    connect(&dataFormatPanel, &DataFormatPanel::numOfChannelsChanged,
 
            &channelMan, &ChannelManager::setNumOfChannels);
 

	
 
    connect(&channelMan, &ChannelManager::numOfChannelsChanged,
 
            this, &MainWindow::onNumOfChannelsChanged);
 

	
 
    connect(&channelMan, &ChannelManager::channelNameChanged,
 
            this, &MainWindow::onChannelNameChanged);
 

	
 
    // TODO: move this into the plot tab
 
    QListView* channelNamesView = new QListView();
 
    channelNamesView->setModel(channelMan.channelNames());
 
    channelNamesView->show();
 

	
 
    // init channel data and curve list
 
    for (unsigned int i = 0; i < numOfChannels; i++)
 
    {
 
        channelBuffers.append(new FrameBuffer(numOfSamples));
 
        curves.append(new QwtPlotCurve(QString("Channel %1").arg(i+1)));
 
        curves[i]->setSamples(channelBuffers[i]);
 
        curves.append(new QwtPlotCurve(channelMan.channelName(i)));
 
        curves[i]->setSamples(channelMan.channelBuffer(i));
 
        curves[i]->setPen(Plot::makeColor(i));
 
        curves[i]->attach(ui->plot);
 
    }
 
@@ -314,9 +329,9 @@ required privileges or device is already
 

	
 
void MainWindow::clearPlot()
 
{
 
    for (int ci = 0; ci < channelBuffers.size(); ci++)
 
    for (unsigned ci = 0; ci < channelMan.numOfChannels(); ci++)
 
    {
 
        channelBuffers[ci]->clear();
 
        channelMan.channelBuffer(ci)->clear();
 
    }
 
    ui->plot->replot();
 
}
 
@@ -324,30 +339,28 @@ void MainWindow::clearPlot()
 
void MainWindow::onNumOfSamplesChanged(int value)
 
{
 
    numOfSamples = value;
 

	
 
    for (int ci = 0; ci < channelBuffers.size(); ci++)
 
    {
 
        channelBuffers[ci]->resize(numOfSamples);
 
    }
 

	
 
    channelMan.setNumOfSamples(value);
 
    ui->plot->replot();
 
}
 

	
 
void MainWindow::onNumOfChannelsChanged(unsigned value)
 
{
 
    unsigned int oldNum = channelBuffers.size();
 
    unsigned int oldNum = curves.size();
 
    unsigned numOfChannels = value;
 

	
 
    if (numOfChannels > oldNum)
 
    {
 
        // add new channels
 
        for (unsigned int i = 0; i < numOfChannels - oldNum; i++)
 
        for (unsigned int i = oldNum; i < numOfChannels; i++)
 
        {
 
            channelBuffers.append(new FrameBuffer(numOfSamples));
 
            curves.append(new QwtPlotCurve(QString("Channel %1").arg(oldNum+i+1)));
 
            curves.last()->setSamples(channelBuffers.last());
 
            curves.last()->setPen(Plot::makeColor(curves.length()-1));
 
            curves.last()->attach(ui->plot);
 
            QwtPlotCurve* curve = new QwtPlotCurve(channelMan.channelName(i));
 
            // TODO: create a wrapper around FrameBuffer that holds a
 
            // pointer to it and provides the QwtDataSeries interface,
 
            // that wrapper should be created for and owned by 'curve'
 
            curve->setSamples(channelMan.channelBuffer(i));
 
            curve->setPen(Plot::makeColor(i));
 
            curve->attach(ui->plot);
 
            curves.append(curve);
 
        }
 
    }
 
    else if(numOfChannels < oldNum)
 
@@ -355,11 +368,24 @@ void MainWindow::onNumOfChannelsChanged(
 
        // remove channels
 
        for (unsigned int i = 0; i < oldNum - numOfChannels; i++)
 
        {
 
            // also deletes owned FrameBuffer
 
            // also deletes owned FrameBuffer TODO: which souldn't happen
 
            delete curves.takeLast();
 
            channelBuffers.removeLast();
 
        }
 
    }
 

	
 
    ui->plot->replot();
 
}
 

	
 
void MainWindow::onChannelNameChanged(unsigned channel, QString name)
 
{
 
    // This slot is triggered also when a new channel is added, in
 
    // this case curve list doesn't contain said channel. No worries,
 
    // since `onNumOfChannelsChanged` slot will update curve list.
 
    if (channel < curves.size()) // check if channel exists in curve list
 
    {
 
        curves[channel]->setTitle(name);
 
        ui->plot->replot();
 
    }
 
}
 

	
 
void MainWindow::onAutoScaleChecked(bool checked)
 
@@ -449,7 +475,7 @@ void MainWindow::onExportCsv()
 
        {
 
            QTextStream fileStream(&file);
 

	
 
            unsigned numOfChannels = channelBuffers.size();
 
            unsigned numOfChannels = channelMan.numOfChannels();
 
            for (unsigned int ci = 0; ci < numOfChannels; ci++)
 
            {
 
                fileStream << "Channel " << ci;
 
@@ -461,7 +487,7 @@ void MainWindow::onExportCsv()
 
            {
 
                for (unsigned int ci = 0; ci < numOfChannels; ci++)
 
                {
 
                    fileStream << channelBuffers[ci]->sample(i).y();
 
                    fileStream << channelMan.channelBuffer(ci)->sample(i).y();
 
                    if (ci != numOfChannels-1) fileStream << ",";
 
                }
 
                fileStream << '\n';
src/mainwindow.h
Show inline comments
 
@@ -39,6 +39,7 @@
 
#include "dataformatpanel.h"
 
#include "ui_about_dialog.h"
 
#include "framebuffer.h"
 
#include "channelmanager.h"
 
#include "snapshotmanager.h"
 

	
 
namespace Ui {
 
@@ -69,7 +70,8 @@ private:
 

	
 
    QList<QwtPlotCurve*> curves;
 
    // Note: FrameBuffer s are owned by their respective QwtPlotCurve s.
 
    QList<FrameBuffer*> channelBuffers;
 
    // QList<FrameBuffer*> channelBuffers;
 
    ChannelManager channelMan;
 

	
 
    QLabel spsLabel;
 

	
 
@@ -90,6 +92,7 @@ private slots:
 
    void onYScaleChanged();
 
    void onRangeSelected();
 
    void onNumOfChannelsChanged(unsigned value);
 
    void onChannelNameChanged(unsigned channel, QString name);
 

	
 
    void clearPlot();
 

	
src/snapshotmanager.cpp
Show inline comments
 
@@ -28,14 +28,14 @@
 
#include "snapshotmanager.h"
 

	
 
SnapshotManager::SnapshotManager(QMainWindow* mainWindow,
 
                                 QList<FrameBuffer*>* channelBuffers) :
 
                                 ChannelManager* channelMan) :
 
    _menu("Snapshots"),
 
    _takeSnapshotAction("Take Snapshot", this),
 
    loadSnapshotAction("Load Snapshots", this),
 
    clearAction("Clear Snapshots", this)
 
{
 
    _mainWindow = mainWindow;
 
    _channelBuffers = channelBuffers;
 
    _channelMan = channelMan;
 

	
 
    _takeSnapshotAction.setToolTip("Take a snapshot of current plot");
 
    _takeSnapshotAction.setShortcut(QKeySequence("F5"));
 
@@ -64,15 +64,15 @@ void SnapshotManager::takeSnapshot()
 
    QString name = QTime::currentTime().toString("'Snapshot ['HH:mm:ss']'");
 
    auto snapshot = new Snapshot(_mainWindow, name);
 

	
 
    unsigned numOfChannels = _channelBuffers->size();
 
    unsigned numOfSamples = _channelBuffers->at(0)->size();
 
    unsigned numOfChannels = _channelMan->numOfChannels();
 
    unsigned numOfSamples = _channelMan->numOfSamples();
 

	
 
    for (unsigned ci = 0; ci < numOfChannels; ci++)
 
    {
 
        snapshot->data.append(QVector<QPointF>(numOfSamples));
 
        for (unsigned i = 0; i < numOfSamples; i++)
 
        {
 
            snapshot->data[ci][i] = _channelBuffers->at(ci)->sample(i);
 
            snapshot->data[ci][i] = _channelMan->channelBuffer(ci)->sample(i);
 
        }
 
    }
 

	
src/snapshotmanager.h
Show inline comments
 
@@ -25,6 +25,7 @@
 
#include <QMenu>
 

	
 
#include "framebuffer.h"
 
#include "channelmanager.h"
 
#include "snapshot.h"
 

	
 
class SnapshotManager : public QObject
 
@@ -32,7 +33,7 @@ class SnapshotManager : public QObject
 
    Q_OBJECT
 

	
 
public:
 
    SnapshotManager(QMainWindow* mainWindow, QList<FrameBuffer*>* channelBuffers);
 
    SnapshotManager(QMainWindow* mainWindow, ChannelManager* channelMan);
 
    ~SnapshotManager();
 

	
 
    QMenu* menu();
 
@@ -40,7 +41,7 @@ public:
 

	
 
private:
 
    QMainWindow* _mainWindow;
 
    QList<FrameBuffer*>* _channelBuffers;
 
    ChannelManager* _channelMan;
 

	
 
    QList<Snapshot*> snapshots;
 

	
0 comments (0 inline, 0 general)