--- /dev/null
+QT -= core gui
+
+TARGET = usb_relay_device
+TEMPLATE = lib
+CONFIG += dll
+
+SOURCES += ../../lib/usb_relay_lib.c
+win32{
+ SOURCES += ../../commandline/hiddata_mswin.c
+}
+unix{
+ SOURCES += ../../commandline/hiddata_libusb01.c
+}
+
+HEADERS += ../../lib/usb_relay_device.h \
+ ../../lib/usb_relay_hw.h \
+ ../../commandline/hiddata.h
+
+INCLUDEPATH += ../../lib/usb-relay-dll/
+INCLUDEPATH += ../../commandline/
+
+win32{
+ INCLUDEPATH += C:/Program Files (x86)/Windows Kits/8.0/Include/
+}
+
+unix:{
+CONFIG += link_pkgconfig
+PKGCONFIG += libusb
+}
--- /dev/null
+#-------------------------------------------------
+#
+# Project created by QtCreator 2016-10-02T19:08:35
+#
+#-------------------------------------------------
+
+QT += core gui
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = QUsbRelayGui
+TEMPLATE = app
+
+
+SOURCES += main.cpp\
+ widget.cpp \
+ device.cpp
+
+HEADERS += widget.h \
+ device.h
+
+FORMS += widget.ui \
+ device.ui
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../QUsbRelay/release/ -lusb_relay_device
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../QUsbRelay/debug/ -lusb_relay_device
+else:unix: LIBS += -L$$OUT_PWD/../QUsbRelay/ -lusb_relay_device
+
+INCLUDEPATH += $$PWD/../QUsbRelay
+DEPENDPATH += $$PWD/../QUsbRelay
+
+INCLUDEPATH += $$PWD/../../lib
+DEPENDPATH += $$PWD/../../lib
+
+RESOURCES += \
+ resources.qrc
+
+win32: RC_ICONS = device_and_hardware_w.ico
--- /dev/null
+#include "device.h"
+#include "ui_device.h"
+
+Device::Device(qint16 index, QWidget *parent, QString name, QString serial, quint16 channelCount, QVector<bool> status) :
+ QWidget(parent),
+ ui(new Ui::device),
+ _index(index)
+{
+ ui->setupUi(this);
+
+ ui->device_channel_count_value->setText(QString::number(channelCount));
+ ui->device_name_value->setText(name);
+ ui->device_serial_value->setText(serial);
+
+ connect(ui->device_close_all,&QPushButton::clicked,[this](){
+ changeChannelStatus(false);
+ emit closeAllSignal(this->_index);
+ });
+
+ connect(ui->device_open_all,&QPushButton::clicked,[this](){
+ changeChannelStatus(true);
+ emit openAllSignal(this->_index);
+ });
+
+
+ QVBoxLayout *vbox = new QVBoxLayout;
+ for(auto i=1;i<channelCount+1;i++){
+ QCheckBox *checkBox = new QCheckBox(QString("Channel %1").arg(i),this);
+ connect(checkBox, &QCheckBox::clicked,[this,i](bool state){
+ emit changeChannelState(this->_index, state,i);
+ });
+ checkBox->setChecked(status[i-1]);
+ vbox->addWidget(checkBox);
+ }
+
+ ui->channels_windget->setLayout(vbox);
+}
+
+Device::~Device()
+{
+ delete ui;
+}
+
+void Device::changeChannelStatus(bool status)
+{
+ QList<QCheckBox *> allCButtons = this->ui->channels_windget->findChildren<QCheckBox *>();
+ for(const auto& i:allCButtons){
+ i->setChecked(status);
+ }
+}
--- /dev/null
+#ifndef DEVICE_H
+#define DEVICE_H
+
+#include <QWidget>
+#include <QCheckBox>
+#include <QSignalMapper>
+#include <QDebug>
+
+namespace Ui {
+class device;
+}
+
+class Device : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit Device(qint16 index, QWidget *parent = 0,QString name="", QString serial="", quint16 channelCount=0, QVector<bool> status = {});
+ ~Device();
+signals:
+ /*!
+ * \brief openAllSignal signaling about opening all channels in device with id passed as parameter
+ */
+ void openAllSignal(qint16);
+ /*!
+ * \brief closeAllSignal signaling about closing all channels in device with id passed as parameter
+ */
+ void closeAllSignal(qint16);
+ /*!
+ * \brief changeChannelState signaling aboud changing state of one channel in device with id passed as parameter
+ * \param handle device handle
+ * \param state state open\closed
+ * \param channel device channel number
+ */
+ void changeChannelState(qint16 handle,bool state,int channel);
+
+private:
+ Ui::device *ui;
+ qint16 _index;
+ /*!
+ * \brief changeChannelStatus heper functions - changes view for all channels at device
+ * \param status
+ */
+ void changeChannelStatus(bool status);
+};
+
+#endif // DEVICE_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>device</class>
+ <widget class="QWidget" name="device">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>318</width>
+ <height>227</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="device_name">
+ <property name="text">
+ <string>Device Name</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="device_name_value">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="device_serial_number">
+ <property name="text">
+ <string>Device Serial Number</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="device_serial_value">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="device_channel_count">
+ <property name="text">
+ <string>Device Channel Count</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="device_channel_count_value">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPushButton" name="device_open_all">
+ <property name="text">
+ <string>Open All</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="device_close_all">
+ <property name="text">
+ <string>Close All</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="channels_windget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>298</width>
+ <height>90</height>
+ </rect>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
--- /dev/null
+#include <QApplication>
+#include <QStyleFactory>
+
+#include "widget.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication a(argc, argv);
+
+ qApp->setStyle(QStyleFactory::create("Fusion"));
+
+ QPalette darkPalette;
+ darkPalette.setColor(QPalette::Window, QColor(53,53,53));
+ darkPalette.setColor(QPalette::WindowText, Qt::white);
+ darkPalette.setColor(QPalette::Base, QColor(25,25,25));
+ darkPalette.setColor(QPalette::AlternateBase, QColor(53,53,53));
+ darkPalette.setColor(QPalette::ToolTipBase, Qt::white);
+ darkPalette.setColor(QPalette::ToolTipText, Qt::white);
+ darkPalette.setColor(QPalette::Text, Qt::white);
+ darkPalette.setColor(QPalette::Button, QColor(53,53,53));
+ darkPalette.setColor(QPalette::ButtonText, Qt::white);
+ darkPalette.setColor(QPalette::BrightText, Qt::red);
+ darkPalette.setColor(QPalette::Link, QColor(42, 130, 218));
+
+ darkPalette.setColor(QPalette::Highlight, QColor(42, 130, 218));
+ darkPalette.setColor(QPalette::HighlightedText, Qt::black);
+
+ qApp->setPalette(darkPalette);
+
+ qApp->setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }");
+
+ Widget w;
+ w.show();
+
+ return a.exec();
+}
--- /dev/null
+<RCC>
+ <qresource prefix="/images">
+ <file>device_and_hardware_w.ico</file>
+ </qresource>
+</RCC>
--- /dev/null
+#include "widget.h"
+#include "ui_widget.h"
+
+Widget::Widget(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::Widget)
+{
+ ui->setupUi(this);
+
+ list.searchForDevices();
+
+ for(auto i=0; i< list.m_devices.size();i++){
+
+ getRelayStatus(i);
+
+ auto dev = list.m_devices[i];
+
+ //Device has qobject pointer to this and will be deleated by qt system
+ Device* k = new Device(i,this,dev.m_name,dev.m_serialNumber,dev.m_channelsNumber,dev.m_channelsStatus);
+
+ connect(k,&Device::closeAllSignal,this,&Widget::onSomeonWantCloseAll);
+ connect(k,&Device::openAllSignal,this,&Widget::onSomeonWantOpenAll);
+ connect(k,&Device::changeChannelState,this,&Widget::onSomeoneWantToDoAnythingWithChannel);
+
+ QListWidgetItem* j = new QListWidgetItem();
+ j->setSizeHint(k->size());
+
+ listWidgetsVector.push_back(j);
+
+ ui->listWidget->addItem(j);
+ ui->listWidget->setItemWidget(j,k);
+ }
+}
+
+Widget::~Widget()
+{
+ delete ui;
+ for(auto& i: listWidgetsVector){
+ delete i;
+ }
+}
+
+void Widget::getRelayStatus(int value)
+{
+ auto handle = usb_relay_device_open(list.m_devices[value].m_raw_pointer);
+ unsigned int status;
+ usb_relay_device_get_status(handle,&status);
+ QVector<bool> tmp;
+ tmp.resize(list.m_devices[value].m_channelsNumber);
+ for (int j = 0; j < list.m_devices[value].m_channelsNumber ; ++j){
+ tmp[j] = 0 != (status & (1 << j));
+ }
+ list.m_devices[value].m_channelsStatus = tmp;
+ usb_relay_device_close(handle);
+}
+
+void Widget::onSomeonWantCloseAll(qint16 value)
+{
+ auto handle = usb_relay_device_open(list.m_devices[value].m_raw_pointer);
+ usb_relay_device_close_all_relay_channel(handle);
+ usb_relay_device_close(handle);
+}
+
+void Widget::onSomeonWantOpenAll(qint16 value)
+{
+ auto handle = usb_relay_device_open(list.m_devices[value].m_raw_pointer);
+ usb_relay_device_open_all_relay_channel(handle);
+ usb_relay_device_close(handle);
+}
+
+void Widget::onSomeoneWantToDoAnythingWithChannel(qint16 value, bool state, int channel)
+{
+ auto handle = usb_relay_device_open(list.m_devices[value].m_raw_pointer);
+ if(state){
+ usb_relay_device_open_one_relay_channel(handle,channel);
+ }else{
+ usb_relay_device_close_one_relay_channel(handle,channel);
+ }
+ usb_relay_device_close(handle);
+}
--- /dev/null
+#ifndef WIDGET_H
+#define WIDGET_H
+
+#include <QWidget>
+#include <QAbstractListModel>
+#include <QAbstractItemDelegate>
+#include <QPainter>
+#include <QApplication>
+#include <QStyledItemDelegate>
+#include <QSignalMapper>
+#include <QListWidgetItem>
+#include "device.h"
+
+#include <usb_relay_device.h>
+
+/*!
+ * \brief The DeviceInfo class stores anything we need to know about usb relay device
+ */
+class DeviceInfo{
+public:
+ DeviceInfo() = default;
+ DeviceInfo(QString nm, QString sn, quint16 cn, usb_relay_device_info* rp, QString cun):
+ m_name(nm),
+ m_serialNumber(sn),
+ m_channelsNumber(cn),
+ m_raw_pointer(rp),
+ m_customName(cun)
+ {
+ }
+
+ QString m_name;
+ QString m_serialNumber;
+ quint16 m_channelsNumber;
+ usb_relay_device_info* m_raw_pointer;
+ QString m_customName;
+ QVector<bool> m_channelsStatus;
+};
+
+Q_DECLARE_METATYPE(DeviceInfo)
+
+
+class DeviceList
+{
+public:
+ DeviceList() = default;
+
+ void searchForDevices(){
+ auto device = usb_relay_device_enumerate();
+ if(device == nullptr){
+ m_devices.clear();
+ return;
+ }
+ bool hasNext = true;
+ while(hasNext){
+ m_devices.push_back(DeviceInfo(device->device_path,device->serial_number,device->type,device,""));
+
+ if(device->next != nullptr){
+ device++;
+ }else{
+ hasNext = false;
+ }
+ }
+ }
+
+ ~DeviceList() = default;
+
+ std::vector<DeviceInfo> m_devices;
+};
+
+
+namespace Ui {
+ class Widget;
+}
+
+/*!
+ * \brief The Widget class main idea - share device id as an index in DeviceList vector
+ */
+class Widget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit Widget(QWidget *parent = 0);
+ ~Widget();
+
+private:
+ Ui::Widget *ui;
+ DeviceList list;
+
+ QVector<QListWidgetItem*> listWidgetsVector;
+
+ void getRelayStatus(int);
+
+private slots:
+ /*!
+ * \brief onSomeonWantCloseAll
+ * \param value device id - see brief of a class
+ */
+ void onSomeonWantCloseAll(qint16 value);
+ /*!
+ * \brief onSomeonWantOpenAll
+ * \param value device id - see brief of a class
+ */
+ void onSomeonWantOpenAll(qint16 value);
+ void onSomeoneWantToDoAnythingWithChannel(qint16 value,bool state,int channel);
+
+};
+
+#endif // WIDGET_H
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Widget</class>
+ <widget class="QWidget" name="Widget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>UsbRelayGui</string>
+ </property>
+ <property name="windowIcon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/images/device_and_hardware_w.ico</normaloff>:/images/device_and_hardware_w.ico</iconset>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QListWidget" name="listWidget"/>
+ </item>
+ </layout>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <resources>
+ <include location="resources.qrc"/>
+ </resources>
+ <connections/>
+</ui>
--- /dev/null
+TEMPLATE = subdirs
+
+SUBDIRS += \
+ QUsbRelay \
+ QUsbRelayGui