Added: Connection Config, Chart, Improved: Connection Handling, Controller

This commit is contained in:
Sally Marcher 2025-04-16 16:23:14 +02:00
parent c48b714490
commit 470511ceab
16 changed files with 979 additions and 25 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
build/
CMakeLists.txt.user

6
.gitmodules vendored Normal file
View file

@ -0,0 +1,6 @@
[submodule "qt_zoomable_chart_widget"]
path = qt_zoomable_chart_widget
url = https://github.com/martonmiklos/qt_zoomable_chart_widget.git
[submodule "QtWaitingSpinner"]
path = QtWaitingSpinner
url = https://github.com/snowwlex/QtWaitingSpinner.git

View file

@ -10,8 +10,10 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Widgets Network Core5Compat)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Network Core5Compat)
find_package(QT NAMES Qt6 REQUIRED COMPONENTS Widgets Network Core5Compat Charts)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Network Core5Compat Charts)
add_subdirectory(qt_zoomable_chart_widget/)
set(PROJECT_SOURCES
main.cpp
@ -20,12 +22,21 @@ set(PROJECT_SOURCES
mainwindow.ui
shimlccontroller.cpp
shimlccontroller.h
connectionconfiguration.cpp
connectionconfiguration.h
qt_zoomable_chart_widget/res/zoomable_chart_widget_resources.qrc
QtWaitingSpinner/waitingspinnerwidget.cpp
QtWaitingSpinner/waitingspinnerwidget.h
)
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
qt_add_executable(QtChroma
MANUAL_FINALIZATION
${PROJECT_SOURCES}
systemconfiguration.h systemconfiguration.cpp systemconfiguration.ui
connectionconfiguration.h connectionconfiguration.cpp connectionconfiguration.ui
)
# Define target properties for Android with Qt 6 as:
# set_property(TARGET QtChroma APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
@ -46,7 +57,7 @@ else()
endif()
endif()
target_link_libraries(QtChroma PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Core5Compat)
target_link_libraries(QtChroma PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Core5Compat Qt${QT_VERSION_MAJOR}::Charts zoomablechart)
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
@ -63,6 +74,8 @@ set_target_properties(QtChroma PROPERTIES
)
include(GNUInstallDirs)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
install(TARGETS QtChroma
BUNDLE DESTINATION .
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}

1
QtWaitingSpinner Submodule

@ -0,0 +1 @@
Subproject commit a1325a2ef1bac0ce37e9fe05d7be26554e33bba5

View file

@ -0,0 +1,40 @@
#include "connectionconfiguration.h"
#include "ui_connectionconfiguration.h"
ConnectionConfiguration::ConnectionConfiguration(QSettings *settings, ShimLCController *ctrl, QWidget *parent)
: QDialog(parent), settings(settings), ctrl(ctrl)
, ui(new Ui::ConnectionConfiguration)
{
ui->setupUi(this);
ui->addrEntry->setText(settings->value("connection/addr", "localhost").toString());
ui->portEntry->setValue(settings->value("connection/port", 5001).toInt());
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &ConnectionConfiguration::apply);
}
ConnectionConfiguration::~ConnectionConfiguration()
{
delete ui;
}
void ConnectionConfiguration::apply()
{
settings->setValue("connection/addr", ui->addrEntry->text());
settings->setValue("connection/port", ui->portEntry->value());
ctrl->reconnect(settings);
if(settings->value("connection/showInfo").toBool() == 0)
switch( QMessageBox::information(
this,
tr("QtChroma"),
tr("Connection settings changed!\r\nWill try to reconnect with new settings.\r\nShow this message again?"),
QMessageBox::Yes |
QMessageBox::No,
QMessageBox::Yes ) )
{
case QMessageBox::No:
settings->setValue("connection/showInfo", true);
break;
}
}

30
connectionconfiguration.h Normal file
View file

@ -0,0 +1,30 @@
#ifndef CONNECTIONCONFIGURATION_H
#define CONNECTIONCONFIGURATION_H
#include <QDialog>
#include <QSettings>
#include <QMessageBox>
#include "shimlccontroller.h"
namespace Ui {
class ConnectionConfiguration;
}
class ConnectionConfiguration : public QDialog
{
Q_OBJECT
public:
explicit ConnectionConfiguration(QSettings *settings, ShimLCController *ctrl, QWidget *parent);
~ConnectionConfiguration();
private:
Ui::ConnectionConfiguration *ui;
void apply();
QSettings *settings = nullptr;
ShimLCController *ctrl = nullptr;
void test();
};
#endif // CONNECTIONCONFIGURATION_H

View file

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConnectionConfiguration</class>
<widget class="QDialog" name="ConnectionConfiguration">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Address</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="addrEntry"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Port</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="portEntry">
<property name="maximum">
<number>10000</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ConnectionConfiguration</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ConnectionConfiguration</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -6,9 +6,62 @@ MainWindow::MainWindow(QWidget *parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
mainChart = ui->chartWidget->chart();
spinner = ui->spinner;
connect(ui->actionConfiguration, SIGNAL(triggered()), &systemConfigWindow, SLOT(show()));
connect(ui->actionConnConfiguration, SIGNAL(triggered()), &connConf, SLOT(show()));
connect(&ctrl, &ShimLCController::connectionStateChanged, this, &MainWindow::updateConnectionState);
spinner->setRoundness(70.0);
spinner->setMinimumTrailOpacity(15.0);
spinner->setTrailFadePercentage(70.0);
spinner->setNumberOfLines(12);
spinner->setLineLength(10);
spinner->setLineWidth(5);
spinner->setInnerRadius(10);
spinner->setRevolutionsPerSecond(1);
spinner->setColor(QColor(81, 4, 71));
// Try to auto connect
ui->frame->setEnabled(false);
ctrl.reconnect(&settings);
mainChart->setTitle("Detector Data");
//mainChart->setAnimationOptions(QChart::SeriesAnimations);
// Example...
auto series = new QLineSeries;
for (int i = 0; i < 500; i++) {
QPointF p((qreal) i, qSin(M_PI / 50 * i) * 100);
p.ry() += QRandomGenerator::global()->bounded(20);
*series << p;
}
mainChart->addSeries(series);
mainChart->createDefaultAxes();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::updateConnectionState(QAbstractSocket::SocketState state)
{
const QMetaObject & mo = QAbstractSocket::staticMetaObject;
QMetaEnum me = mo.enumerator(mo.indexOfEnumerator("SocketState"));
QString connectionString(me.valueToKey(state));
ui->connState->setText("COM: "+connectionString);
if(state == QAbstractSocket::ConnectingState)
spinner->start();
else
spinner->stop();
if(state == QAbstractSocket::ConnectedState)
ui->frame->setEnabled(true);
else
ui->frame->setEnabled(false);
}
void MainWindow::initConnection()
{
}

View file

@ -2,7 +2,13 @@
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSettings>
#include "shimlccontroller.h"
#include "systemconfiguration.h"
#include "connectionconfiguration.h"
#include "zoomablechart.h"
#include "zoomablechartview.h"
#include "QtWaitingSpinner/waitingspinnerwidget.h"
QT_BEGIN_NAMESPACE
namespace Ui {
@ -19,7 +25,16 @@ public:
~MainWindow();
private:
QSettings settings{"Greyhash", "QtChroma"};
Ui::MainWindow *ui;
ShimLCController foo{};
ShimLCController ctrl{this};
SystemConfiguration systemConfigWindow{&ctrl, this};
ConnectionConfiguration connConf{&settings, &ctrl, this};
ZoomableChart* mainChart = nullptr;
WaitingSpinnerWidget* spinner = nullptr;
private slots:
void updateConnectionState(QAbstractSocket::SocketState state);
void initConnection();
};
#endif // MAINWINDOW_H

View file

@ -13,7 +13,401 @@
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget"/>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QFrame" name="frame">
<property name="minimumSize">
<size>
<width>446</width>
<height>170</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>800000</width>
<height>170</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<widget class="QComboBox" name="pumpsSelectorBox">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>25</height>
</size>
</property>
</widget>
</item>
<item row="3" column="0">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QDoubleSpinBox" name="pumpFlow"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_4">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>26</height>
</size>
</property>
<property name="text">
<string>ml/min</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_2">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>MPa</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLCDNumber" name="pumpPercent"/>
</item>
<item row="1" column="0">
<widget class="QLCDNumber" name="pumpPress"/>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_3">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>23</height>
</size>
</property>
<property name="text">
<string>%</string>
</property>
</widget>
</item>
<item row="3" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
<width>130</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>22</height>
</size>
</property>
<property name="font">
<font>
<family>Hack</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Pumps</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_5">
<property name="minimumSize">
<size>
<width>130</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<family>Hack</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Autosampler</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="autoSamplerStatus">
<property name="text">
<string>None</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="1">
<widget class="QLabel" name="label_7">
<property name="text">
<string>°C</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLCDNumber" name="lcdNumber"/>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</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">
<item>
<widget class="QLabel" name="label_6">
<property name="minimumSize">
<size>
<width>130</width>
<height>0</height>
</size>
</property>
<property name="font">
<font>
<family>Hack</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>Detector</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="pumpsSelectorBox_2"/>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_7">
<item row="1" column="1">
<widget class="QLabel" name="label_9">
<property name="text">
<string>mAU</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLCDNumber" name="lcdNumber_2"/>
</item>
<item row="0" column="0">
<widget class="QDoubleSpinBox" name="pumpFlow_2"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
<string>nm</string>
</property>
</widget>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>8000</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QLabel" name="label_10">
<property name="minimumSize">
<size>
<width>130</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>130</width>
<height>16777215</height>
</size>
</property>
<property name="font">
<font>
<family>Hack</family>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>File</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="maximumSize">
<size>
<width>130</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="WaitingSpinnerWidget" name="spinner" native="true"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="connState">
<property name="text">
<string>Connection: X</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="ZoomableChartWidget" name="chartWidget" native="true"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
@ -23,9 +417,55 @@
<height>22</height>
</rect>
</property>
<widget class="QMenu" name="menuQtChroma">
<property name="title">
<string>System</string>
</property>
<addaction name="actionConfiguration"/>
</widget>
<widget class="QMenu" name="menuConnection">
<property name="title">
<string>Connection</string>
</property>
<addaction name="actionConnConfiguration"/>
</widget>
<addaction name="menuQtChroma"/>
<addaction name="menuConnection"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionConfiguration">
<property name="text">
<string>Configuration</string>
</property>
</action>
<action name="connectionState">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>State: Loading...</string>
</property>
</action>
<action name="actionConnConfiguration">
<property name="text">
<string>Configuration</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>ZoomableChartWidget</class>
<extends>QWidget</extends>
<header>zoomablechartwidget.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>WaitingSpinnerWidget</class>
<extends>QWidget</extends>
<header>QtWaitingSpinner/waitingspinnerwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

@ -0,0 +1 @@
Subproject commit f610926f0c4411dd34c836b1cb7f66ca3e1631eb

View file

@ -46,6 +46,7 @@ ShimTCPController::ShimTCPController(QObject *parent) : QObject(parent)
connect(socket, &QTcpSocket::readyRead, this, &ShimTCPController::readData);
connect(socket, &QTcpSocket::errorOccurred, this, &ShimTCPController::displayError);
connect(socket, &QTcpSocket::stateChanged, this, &ShimTCPController::emitConnectionStateChanged);
connect(this, &ShimTCPController::dataAvailable, this, &ShimTCPController::dataAvailableErrorNoF);
}
@ -57,11 +58,12 @@ ShimTCPController::~ShimTCPController()
void ShimTCPController::connectToHost(QString host)
{
// Close Connection
qDebug() << TAG << "Connecting to host" << host;
// Close Connection CAUTION: If currently waiting for response this could mess up the state machine in an infinte waiting loop, TODO: proper handeling
socket->abort();
// Connect TCP Socket Port 5001
socket->connectToHost(host, 5001);
socket->waitForConnected();
//socket->waitForConnected();
}
// Wirte and flush data if connected
@ -75,39 +77,34 @@ bool ShimTCPController::writeData(QByteArray *data)
}
else
{
pendingData = new QByteArray(*data);
qDebug() << TAG << "socket write Data sceduled when connection state changed to ConnectedState!";
return false;
}
}
void ShimTCPController::displayError(QAbstractSocket::SocketError socketError)
{
// TODO: Proper centering by passing parent object!
switch (socketError) {
case QAbstractSocket::RemoteHostClosedError:
break;
case QAbstractSocket::HostNotFoundError:
/*
QMessageBox::information(this, tr("ShimLCController"),
QMessageBox::information(nullptr, tr("ShimLCController"),
tr("The host was not found. Please check the "
"host name and port settings."));
*/
break;
case QAbstractSocket::ConnectionRefusedError:
/*
QMessageBox::information(this, tr("ShimLCController"),
QMessageBox::information(nullptr, tr("ShimLCController"),
tr("The connection was refused by the peer."));
*/
break;
default:
break;
/*
QMessageBox::information(this, tr("ShimLCController"),
QMessageBox::information(nullptr, tr("ShimLCController"),
tr("The following error occurred: %1.")
.arg(tcpSocket->errorString()));
*/
.arg(socket->errorString()));
break;
}
qDebug() << socketError;
//getFortuneButton->setEnabled(true);
}
// Parse Data and reset parserFunction signal
@ -194,6 +191,18 @@ void ShimTCPController::dataAvailableErrorNoF(QByteArray data)
qDebug() << data;
}
void ShimTCPController::emitConnectionStateChanged()
{
QAbstractSocket::SocketState state = socket->state();
if(state == QAbstractSocket::ConnectedState and (pendingData != nullptr))
{
writeData(pendingData);
delete pendingData;
qDebug() << "pendng data sent!";
}
emit connectionStateChanged(state);
}
// -----------------------------------------------------------------------------------------------------------------------------
float QByteArrayToFloatBE(QByteArray arr)
@ -217,12 +226,12 @@ float QByteArrayToFloatLE(QByteArray arr)
}
ShimLCCommandStack::ShimLCCommandStack(QObject *parent)
:parent(parent)
{
disconnect(&connection, &ShimTCPController::dataAvailable, 0, 0);
connect(&connection, &ShimTCPController::dataAvailable, this, &ShimLCCommandStack::newResult);
connect(&connection, &ShimTCPController::irDone, this, &ShimLCCommandStack::exitedIr);
connection.connectToHost("192.168.200.99");
connect(&connection, &ShimTCPController::connectionStateChanged, this, &ShimLCCommandStack::connectionStateChanged);
}
ShimLCCommandStack::~ShimLCCommandStack()
@ -232,8 +241,10 @@ ShimLCCommandStack::~ShimLCCommandStack()
uint32_t ShimLCCommandStack::addCmd(char opcode, QString cmd, QByteArray* dest)
{
qDebug() << TAG << "added cmd: Opcode:" << opcode << "Cmd:" << cmd;
id ++;
stackIn.push_back(ShimLCCmd{id, opcode, cmd, dest});
qDebug() << TAG << "Current size of cmd stack:" << stackIn.size();
if(busy_id == 0)
this->next();
return id;
@ -310,6 +321,12 @@ uint32_t ShimLCCommandStack::iCmd(QString cmd, QByteArray* dest)
return addCmd(opcode, cmd, dest);
}
void ShimLCCommandStack::reconnect(QSettings *settings)
{
// TODO: PORT!
connection.connectToHost(settings->value("connection/addr", "localhost").toString());
}
void ShimLCCommandStack::exitedIr()
{
emit dataAvailable(busy_id);
@ -332,10 +349,14 @@ void ShimLCController::updateStatus()
ids[ID_STATUS] = cmd.iCmd("OR lmon.", &data);
}
void ShimLCController::reconnect(QSettings *settings)
{
cmd.reconnect(settings);
}
ShimLCController::ShimLCController(QObject *parent)
{
updateConfig();
updateStatus();
connect(&cmd, &ShimLCCommandStack::connectionStateChanged, this, &ShimLCController::connectionStateChanged);
}
ShimLCController::~ShimLCController()

View file

@ -10,6 +10,8 @@
#include <QList>
#include <tuple>
#include <cmath>
#include <QAbstractSocket>
#include <QMessageBox>
struct ShimLCCmdStackResult
{
@ -39,6 +41,7 @@ private slots:
void parseCbmIr();
void dataAvailableErrorNoF(QByteArray data);
void emitConnectionStateChanged();
public slots:
void connectToHost(QString host);
@ -46,12 +49,15 @@ public slots:
signals:
void irDone();
void dataAvailable(QByteArray data);
void connectionStateChanged(QAbstractSocket::SocketState state);
private:
QString TAG = "ShimTCPController";
QTcpSocket *socket;
QByteArray next_pkg{};
int irMode = 0;
QByteArray* irData = nullptr;
QByteArray* pendingData = nullptr;
};
// ---
@ -66,6 +72,7 @@ private slots:
signals:
void dataAvailable(uint32_t id);
void connectionStateChanged(QAbstractSocket::SocketState state);
public:
explicit ShimLCCommandStack(QObject *parent = 0);
@ -74,9 +81,11 @@ public:
uint32_t getSetVal(QString cmd, QByteArray *dest);
uint32_t getActVal(QString cmd, QByteArray *dest);
uint32_t iCmd(QString cmd, QByteArray *dest);
void reconnect(QSettings *settings);
private:
QString TAG = "ShimLCCommandStack";
using Connection = std::tuple<QObject*, const char*>;
struct ShimLCCmd
{
@ -94,6 +103,8 @@ private:
void next();
uint32_t addCmd(char opcode, QString cmd, QByteArray* dest);
QObject* parent;
};
// ---
@ -214,6 +225,8 @@ class ShimLCController : public QObject
public:
void updateConfig();
void updateStatus();
void reconnect(QSettings *settings);
QList<LCPort> configuration{};
explicit ShimLCController(QObject *parent = nullptr);
~ShimLCController();
@ -221,6 +234,7 @@ public:
signals:
void newConfigAv();
void newStatusAv();
void connectionStateChanged(QAbstractSocket::SocketState state);
private:
void parseLcnf(uint32_t idVal);
@ -228,7 +242,6 @@ private:
uint32_t ids[2]; // 0 - config / 1 - status
ShimLCCommandStack cmd{};
QByteArray data{};
QList<LCPort> configuration{};
LCStatus lastStatus{};
};

29
systemconfiguration.cpp Normal file
View file

@ -0,0 +1,29 @@
#include "systemconfiguration.h"
#include "ui_systemconfiguration.h"
SystemConfiguration::SystemConfiguration(ShimLCController* cmd, QWidget *parent)
: QDialog(parent)
, ui(new Ui::SystemConfiguration)
, cmd(cmd)
{
ui->setupUi(this);
ui->configOverView->setModel(&config_view_model);
connect(cmd, &ShimLCController::newConfigAv, this, &SystemConfiguration::updateTable);
cmd->updateConfig();
}
SystemConfiguration::~SystemConfiguration()
{
delete ui;
}
void SystemConfiguration::updateTable()
{
qDebug("Hi");
for(int i = 0; i<12; i++)
{
config_view_model.tableData[i][0] = cmd->configuration.at(i).name;
config_view_model.tableData[i][1] = cmd->configuration.at(i).version;
config_view_model.tableData[i][2] = cmd->configuration.at(i).serial;
}
}

101
systemconfiguration.h Normal file
View file

@ -0,0 +1,101 @@
#ifndef SYSTEMCONFIGURATION_H
#define SYSTEMCONFIGURATION_H
#include <QDialog>
#include <QTableView>
#include <QAbstractTableModel>
#include <QStringList>
#include <QAbstractTableModel>
#include <QStringList>
#include "shimlccontroller.h"
class ConfigViewModel : public QAbstractTableModel
{
Q_OBJECT
public:
QList<QList<QString>> tableData;
ConfigViewModel(QObject *parent = nullptr)
: QAbstractTableModel(parent)
{
// Initialize the data
for (int row = 0; row < 12; ++row) {
QList<QString> rowData;
for (int col = 0; col < 3; ++col) {
rowData.append(QString("Loading..."));
}
tableData.append(rowData);
}
}
int rowCount(const QModelIndex &parent = QModelIndex()) const override
{
Q_UNUSED(parent);
return 12; // Fixed 12 rows
}
int columnCount(const QModelIndex &parent = QModelIndex()) const override
{
Q_UNUSED(parent);
return 3; // Fixed 4 columns
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
{
if (!index.isValid())
return QVariant();
if (role == Qt::DisplayRole) {
return tableData[index.row()][index.column()];
}
return QVariant();
}
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
{
if (role == Qt::DisplayRole) {
if (orientation == Qt::Horizontal) {
if(section == 0)
return QString("Name");
if(section == 1)
return QString("Version");
if(section == 2)
return QString("Serial");
} else if (orientation == Qt::Vertical) {
return QString("Port %1").arg(section + 1);
}
}
return QVariant();
}
private:
};
namespace Ui {
class SystemConfiguration;
}
class SystemConfiguration : public QDialog
{
Q_OBJECT
public:
explicit SystemConfiguration(ShimLCController* cmd, QWidget *parent);
~SystemConfiguration();
private:
Ui::SystemConfiguration *ui;
ConfigViewModel config_view_model;
ShimLCController* cmd;
private slots:
void updateTable();
};
#endif // SYSTEMCONFIGURATION_H

98
systemconfiguration.ui Normal file
View file

@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SystemConfiguration</class>
<widget class="QDialog" name="SystemConfiguration">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>500</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Detected Devices</string>
</property>
</widget>
</item>
<item>
<widget class="QTableView" name="configOverView"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>38</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SystemConfiguration</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>40</x>
<y>655</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SystemConfiguration</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>66</x>
<y>655</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>