diff --git a/CMakeLists.txt b/CMakeLists.txt index ed9bb60..e86a2c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,35 +1,50 @@ - cmake_minimum_required(VERSION 3.14) -# Set the project name -project(eismultiplexer-qt) +project(eismuliplexer-qt) + +set(CMAKE_PROJECT_VERSION_MAJOR 0) +set(CMAKE_PROJECT_VERSION_MINOR 9) +set(CMAKE_PROJECT_VERSION_PATCH 0) + +add_compile_definitions(VERSION_MAJOR=${CMAKE_PROJECT_VERSION_MAJOR}) +add_compile_definitions(VERSION_MINOR=${CMAKE_PROJECT_VERSION_MINOR}) +add_compile_definitions(VERSION_PATCH=${CMAKE_PROJECT_VERSION_PATCH}) + +if(CMAKE_HOST_SYSTEM_NAME MATCHES "Windows") + message(FATAL_ERROR "Windows builds have to be cross compiled on UNIX") +endif() + +message("Platform " ${CMAKE_SYSTEM_NAME}) +if(WIN32) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/release-win.sh ${CMAKE_CURRENT_BINARY_DIR}/release.sh @ONLY) + add_custom_target(package + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/release.sh + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Createing release archive" + VERBATIM) +endif(WIN32) -# Set C++ standard set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -# Find Qt6 +find_package(PkgConfig REQUIRED) +pkg_check_modules(EISMULIPLEXER REQUIRED eismuliplexer) find_package(Qt6 REQUIRED COMPONENTS Widgets) +find_package(Qt6 REQUIRED COMPONENTS Core) -# Enable automoc for Qt meta-object compiler set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTOUIC ON) -# Include the libeismultiplexer library -include_directories(/workspace/libeismultiplexer) -link_directories(/workspace/libeismultiplexer/build) - -# Add the application executable -add_executable(eismultiplexer-qt +add_executable(${PROJECT_NAME} main.cpp - mainwindow.cpp - mainwindow.h channelwidget.cpp channelwidget.h + mainwindow.h + mainwindow.cpp + mainwindow.ui + multiplexer.h + multiplexer.cpp ) -target_compile_options(eismultiplexer-qt PUBLIC "-Wall") - -# Link Qt Widgets -target_link_libraries(eismultiplexer-qt Qt6::Widgets eismultiplexer) - -# Include directories -target_include_directories(eismultiplexer-qt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_compile_options(${PROJECT_NAME} PUBLIC "-Wall") +target_link_libraries(${PROJECT_NAME} PRIVATE Qt6::Widgets Qt6::Core ${EISMULIPLEXER_LIBRARIES}) +#target_include_directories(${PROJECT_NAME} PUBLIC ${EISMULIPLEXER_INCLUDE_DIRS}) diff --git a/channelwidget.cpp b/channelwidget.cpp index b5df245..ae259fc 100644 --- a/channelwidget.cpp +++ b/channelwidget.cpp @@ -1,78 +1,97 @@ - - - #include "channelwidget.h" #include #include -ChannelWidget::ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber, struct eismultiplexer* multiplexer, +ChannelWidget::ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber, + std::shared_ptr multiplexer, QWidget *parent) - : QWidget(parent), deviceSerial(deviceSerial), channelNumber(channelNumber), multiplexer(multiplexer) + : + QWidget(parent), + deviceSerial(deviceSerial), + channelNumber(channelNumber), + multiplexer(multiplexer), + checkbox("Enable"), + devicelabel(QString::asprintf("Device %04u", deviceSerial)), + channellabel(QString::asprintf("Channel %u", channelNumber)), + ganglabel("Ganged:") { - // Create layout - QHBoxLayout* layout = new QHBoxLayout(this); + hlayout.addLayout(&labellayout); + vlayout.addLayout(&hlayout); - // Create label with device serial and channel number - label = new QLabel(QString("Device %1, Channel %2").arg(deviceSerial).arg(channelNumber), this); - layout->addWidget(label); + labellayout.addWidget(&devicelabel); + labellayout.addWidget(&channellabel); - // Create checkbox - checkbox = new QCheckBox(this); - layout->addWidget(checkbox); + line.setGeometry(QRect(320, 150, 118, 3)); + line.setFrameShape(QFrame::HLine); + line.setFrameShadow(QFrame::Sunken); + vlayout.addWidget(&line); - // Connect checkbox signal - connect(checkbox, &QCheckBox::toggled, this, &ChannelWidget::onChannelToggled); + gangcombo.addItem("Unganged"); - // Set layout - setLayout(layout); + hlayout.addStretch(); + hlayout.addWidget(&ganglabel); + hlayout.addWidget(&gangcombo); + hlayout.addWidget(&checkbox); + connect(&checkbox, &QCheckBox::toggled, this, &ChannelWidget::onChannelToggled); + + setFixedHeight(96); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + + setLayout(&vlayout); } ChannelWidget::~ChannelWidget() { - // Nothing to clean up + // Nothing to clean up } uint16_t ChannelWidget::getDeviceSerial() const { - return deviceSerial; + return deviceSerial; } uint16_t ChannelWidget::getChannelNumber() const { - return channelNumber; + return channelNumber; } bool ChannelWidget::isChecked() const { - return checkbox->isChecked(); + return checkbox.isChecked(); } void ChannelWidget::onChannelToggled(bool checked) { - if (checked) { - // Emit signal before actually turning on the channel - emit channelAboutToBeTurnedOn(deviceSerial, channelNumber); - } + if (checked) + { + // Emit signal before actually turning on the channel + emit channelAboutToBeTurnedOn(deviceSerial, channelNumber); + } - channel_t channelFlag = static_cast(1 << channelNumber); - if (checked) { - if (eismultiplexer_connect_channel(multiplexer.get(), channelFlag) < 0) { - QMessageBox::warning(this, tr("Connection Failed"), - tr("Failed to connect channel %1 on device %2").arg(channelNumber).arg(deviceSerial)); - qWarning() << "Failed to connect channel" << channelNumber << "on device" << deviceSerial; - checkbox->blockSignals(true); - checkbox->setChecked(false); - setEnabled(false); // Gray out the widget - } - } else { - if (eismultiplexer_disconnect_channel(multiplexer.get(), channelFlag) < 0) { - QMessageBox::warning(this, tr("Disconnection Failed"), - tr("Failed to disconnect channel %1 on device %2").arg(channelNumber).arg(deviceSerial)); - qWarning() << "Failed to disconnect channel" << channelNumber << "on device" << deviceSerial; - checkbox->blockSignals(true); - checkbox->setChecked(true); - setEnabled(false); // Gray out the widget - } - } + channel_t channelFlag = static_cast(1 << channelNumber); + if (checked) + { + if (eismultiplexer_connect_channel(multiplexer.get(), channelFlag) < 0) + { + QMessageBox::warning(this, tr("Connection Failed"), + tr("Failed to connect channel %1 on device %2").arg(channelNumber).arg(deviceSerial)); + qWarning() << "Failed to connect channel" << channelNumber << "on device" << deviceSerial; + checkbox.blockSignals(true); + checkbox.setChecked(false); + setEnabled(false); // Gray out the widget + } + } + else + { + if (eismultiplexer_disconnect_channel(multiplexer.get(), channelFlag) < 0) + { + QMessageBox::warning(this, tr("Disconnection Failed"), + tr("Failed to disconnect channel %1 on device %2").arg(channelNumber).arg(deviceSerial)); + qWarning() << "Failed to disconnect channel" << channelNumber << "on device" << deviceSerial; + checkbox.blockSignals(true); + checkbox.setChecked(true); + setEnabled(false); // Gray out the widget + } + } } diff --git a/channelwidget.h b/channelwidget.h index 0c10019..08762a6 100644 --- a/channelwidget.h +++ b/channelwidget.h @@ -5,34 +5,43 @@ #include #include #include +#include #include #include class ChannelWidget : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber, struct eismultiplexer* multiplexer, - QWidget *parent = nullptr); - ~ChannelWidget() override; + explicit ChannelWidget(uint16_t deviceSerial, uint16_t channelNumber, + std::shared_ptr multiplexer, + QWidget *parent = nullptr); + ~ChannelWidget() override; - uint16_t getDeviceSerial() const; - uint16_t getChannelNumber() const; - bool isChecked() const; + uint16_t getDeviceSerial() const; + uint16_t getChannelNumber() const; + bool isChecked() const; signals: - void channelAboutToBeTurnedOn(uint16_t deviceSerial, uint16_t channelNumber); + void channelAboutToBeTurnedOn(uint16_t deviceSerial, uint16_t channelNumber); private slots: - void onChannelToggled(bool checked); + void onChannelToggled(bool checked); private: - uint16_t deviceSerial; - uint16_t channelNumber; - std::shared_ptr multiplexer; - QCheckBox* checkbox; - QLabel* label; + uint16_t deviceSerial; + uint16_t channelNumber; + std::shared_ptr multiplexer; + QCheckBox checkbox; + QLabel devicelabel; + QLabel channellabel; + QLabel ganglabel; + QComboBox gangcombo; + QFrame line; + QVBoxLayout vlayout; + QHBoxLayout hlayout; + QVBoxLayout labellayout; }; #endif // CHANNELWIDGET_H diff --git a/main.cpp b/main.cpp index 6bbb0be..fb4d5b4 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,10 @@ - #include #include "mainwindow.h" int main(int argc, char *argv[]) { - QApplication app(argc, argv); - MainWindow window; - window.show(); - return app.exec(); + QApplication app(argc, argv); + MainWindow window; + window.show(); + return app.exec(); } diff --git a/mainwindow.cpp b/mainwindow.cpp index 6a97402..99a5739 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -1,85 +1,68 @@ -#include "mainwindow.h" -#include -#include #include -#include +#include +#include "mainwindow.h" +#include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) + : QMainWindow(parent) + , ui(new Ui::MainWindow) { - setupUi(); - enumerateDevices(); + ui->setupUi(this); + enumerateDevices(); + + connect(ui->actionQuit, &QAction::triggered, this, [this]() + { + close(); + }); } MainWindow::~MainWindow() { - // Clean up all channel widgets - for (auto widget : channelWidgets) { - delete widget; - } + delete ui; } -void MainWindow::setupUi() -{ - // Create central widget and main layout - centralWidget = new QWidget(this); - mainLayout = new QVBoxLayout(centralWidget); - - // Create scroll area - scrollArea = new QScrollArea(this); - scrollContent = new QWidget(); - scrollLayout = new QVBoxLayout(scrollContent); - - // Set up scroll area properties - scrollArea->setWidget(scrollContent); - scrollArea->setWidgetResizable(true); - scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - // Add scroll area to main layout - mainLayout->addWidget(scrollArea); - - // Set central widget - setCentralWidget(centralWidget); - setWindowTitle("EIS Multiplexer Controller"); -} - -void MainWindow::onChannelAboutToBeTurnedOn(uint16_t deviceSerial, uint16_t channelNumber) -{} - void MainWindow::enumerateDevices() { - size_t count = 0; - uint16_t* serials = eismultiplexer_list_available_devices(&count); + size_t count = 0; + uint16_t* serials = eismultiplexer_list_available_devices(&count); - if (!serials || count == 0) { - QMessageBox::warning(this, tr("No Devices Found"), - tr("No EIS multiplexer devices were found. Please connect a device and try again.")); - qWarning() << "No EIS multiplexer devices found"; - close(); - return; - } + if (!serials || count == 0) + { + QMessageBox::warning(nullptr, tr("No Devices Found"), + tr("No EIS multiplexer devices were found. Please connect a device and try again.")); + qWarning() << "No EIS multiplexer devices found"; + exit(0); + return; + } - for (size_t i = 0; i < count; i++) { - uint16_t serial = serials[i]; - std::shared_ptr multiplexer(new struct eismultiplexer); - if (eismultiplexer_connect(multiplexer.get(), serial) >= 0) { - uint16_t channelCount = 0; - qDebug()<<"Adding channels from device "<= 0) { - for (uint16_t channel = 0; channel < channelCount; channel++) { - ChannelWidget* widget = new ChannelWidget(serial, channel, multiplexer.get()); - qDebug()<<"Added widget from device "<addWidget(widget); - } - } - } else { - QMessageBox::warning(this, tr("Connection Failed"), - tr("Failed to connect to device with serial %1").arg(serial)); - qWarning() << "Failed to connect to device with serial" << serial; - } - } + for (size_t i = 0; i < count; i++) + { + uint16_t serial = serials[i]; + std::shared_ptr multiplexer(new struct eismultiplexer); + if (eismultiplexer_connect(multiplexer.get(), serial) >= 0) + { + uint16_t channelCount = 0; + qDebug()<<"Adding channels from device "<= 0) + { + for (uint16_t channel = 0; channel < channelCount; channel++) + { + std::shared_ptr widget(new ChannelWidget(serial, channel, multiplexer)); + qDebug()<<"Added widget from device "<channelLayout->addWidget(widget.get()); + } + } + } + else + { + QMessageBox::warning(this, tr("Connection Failed"), + tr("Failed to connect to device with serial %1").arg(serial)); + qWarning() << "Failed to connect to device with serial" << serial; + } + ui->channelLayout->addStretch(); + } + ui->statusbar->showMessage("Ready"); - free(serials); + free(serials); } - diff --git a/mainwindow.h b/mainwindow.h index 4426a48..cb1a19c 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -1,42 +1,31 @@ - - #ifndef MAINWINDOW_H #define MAINWINDOW_H #include -#include -#include -#include -#include +#include + #include "channelwidget.h" -QT_BEGIN_NAMESPACE -namespace Ui { class MainWindow; } -QT_END_NAMESPACE +namespace Ui +{ +class MainWindow; +} class MainWindow : public QMainWindow { - Q_OBJECT + Q_OBJECT + std::vector> channels; + Ui::MainWindow *ui; + +signals: + void channelStateChanged(uint16_t device, uint16_t channel); public: - explicit MainWindow(QWidget *parent = nullptr); - ~MainWindow() override; - -private slots: - void onChannelAboutToBeTurnedOn(uint16_t deviceSerial, uint16_t channelNumber); + explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow(); private: - void enumerateDevices(); - void setupUi(); - - QWidget *centralWidget; - QVBoxLayout *mainLayout; - QScrollArea *scrollArea; - QWidget *scrollContent; - QVBoxLayout *scrollLayout; - - std::vector channelWidgets; + void enumerateDevices(); }; #endif // MAINWINDOW_H - diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..53aca8f --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,68 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + EisMultiplexer-Qt + + + + + + + true + + + + + 0 + 0 + 788 + 537 + + + + + + + + + + + + + + + + 0 + 0 + 800 + 29 + + + + + File + + + + + + + + + Quit + + + + + + diff --git a/multiplexer.cpp b/multiplexer.cpp new file mode 100644 index 0000000..3e1c8e0 --- /dev/null +++ b/multiplexer.cpp @@ -0,0 +1,16 @@ +#include "multiplexer.h" + +Multiplexer::Multiplexer(QObject *parent) + : QObject{parent} +{} + +Multiplexer::~Multiplexer() +{ + for(auto& multiplexer : multiplexers) + eismultiplexer_disconnect(multiplexer.get()); +} + +void Multiplexer::probe() +{ + +} diff --git a/multiplexer.h b/multiplexer.h new file mode 100644 index 0000000..32a04ec --- /dev/null +++ b/multiplexer.h @@ -0,0 +1,22 @@ +#ifndef MULTIPLEXER_H +#define MULTIPLEXER_H + +#include +#include "eismultiplexer.h" + +class Multiplexer : public QObject +{ + Q_OBJECT + std::vector> multiplexers; + std::vector channelStates; + +public: + explicit Multiplexer(QObject *parent = nullptr); + ~Multiplexer(); + void probe(); + +signals: + void foundDevice(std::shared_ptr); +}; + +#endif // MULTIPLEXER_H