rework directory structure
This commit is contained in:
parent
0090fa5706
commit
b3ee265745
|
@ -1,7 +1,17 @@
|
|||
cmake_minimum_required(VERSION 3.20)
|
||||
set(DEFAULT_BUILD_TYPE "Release")
|
||||
project(OpenLCP VERSION 0.2.0 LANGUAGES CXX)
|
||||
|
||||
add_subdirectory(protocols)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG")
|
||||
endif()
|
||||
|
||||
add_subdirectory(platform)
|
||||
add_subdirectory(protocol)
|
||||
add_subdirectory(test)
|
||||
add_subdirectory(platform/qt)
|
||||
add_subdirectory(example)
|
||||
|
||||
#if (CMAKE_BUILD_TYPE MATCHES "^[Rr]elease")
|
||||
option(BUILD_DOC "Build documentation" ON)
|
||||
|
|
|
@ -127,7 +127,8 @@ FILE_PATTERNS = *.cpp \
|
|||
*.md \
|
||||
*.py
|
||||
RECURSIVE = YES
|
||||
EXCLUDE = @CMAKE_CURRENT_SOURCE_DIR@/platform \
|
||||
EXCLUDE = @CMAKE_CURRENT_SOURCE_DIR@/example \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/platform \
|
||||
@CMAKE_CURRENT_SOURCE_DIR@/test
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
add_subdirectory("sACN Explorer")
|
|
@ -0,0 +1,60 @@
|
|||
project(sacnExplorer VERSION 1.1.1 LANGUAGES CXX)
|
||||
|
||||
find_package(QT NAMES Qt5 Qt6 COMPONENTS Widgets REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED)
|
||||
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
|
||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
qt_add_executable(${PROJECT_NAME} MANUAL_FINALIZATION)
|
||||
else()
|
||||
if(ANDROID)
|
||||
add_library(${PROJECT_NAME} SHARED)
|
||||
else()
|
||||
add_executable(${PROJECT_NAME})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_sources(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
adduniversedialog.cpp
|
||||
adduniversedialog.h
|
||||
adduniversedialog.ui
|
||||
multiverseitem.h
|
||||
multiverseitem.cpp
|
||||
multiversemodel.h
|
||||
multiversemodel.cpp
|
||||
main.cpp
|
||||
multiverseview.cpp
|
||||
multiverseview.h
|
||||
multiverseview.ui
|
||||
sacnexplorer.h
|
||||
sacnexplorer.cpp
|
||||
universemodel.cpp
|
||||
universemodel.h
|
||||
universeview.h
|
||||
universeview.cpp
|
||||
universeview.ui
|
||||
universeviewdelegate.h
|
||||
universeviewdelegate.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PRIVATE
|
||||
Qt${QT_VERSION_MAJOR}::Widgets
|
||||
QsACN
|
||||
)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
MACOSX_BUNDLE_GUI_IDENTIFIER ${PROJECT_NAME}.company235.com
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
||||
)
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 6)
|
||||
qt_finalize_executable(${PROJECT_NAME})
|
||||
endif()
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#include "adduniversedialog.h"
|
||||
#include "ui_adduniversedialog.h"
|
||||
|
||||
AddUniverseDialog::AddUniverseDialog(QWidget *parent, uint16_t universe,
|
||||
QString title)
|
||||
: QDialog(parent)
|
||||
, ui(new Ui::AddUniverseDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->spinBox->setValue(universe);
|
||||
|
||||
setWindowTitle(title.isEmpty() ? tr("Add Universe") : title);
|
||||
|
||||
connect(this, &QDialog::accepted,
|
||||
this, &AddUniverseDialog::requestAddition);
|
||||
}
|
||||
|
||||
AddUniverseDialog::~AddUniverseDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void AddUniverseDialog::requestAddition() {
|
||||
emit additionRequested(ui->spinBox->value());
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
class AddUniverseDialog;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class AddUniverseDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AddUniverseDialog(QWidget *parent = nullptr, uint16_t universe = 1,
|
||||
QString title = "");
|
||||
virtual ~AddUniverseDialog();
|
||||
|
||||
public slots:
|
||||
void requestAddition();
|
||||
|
||||
signals:
|
||||
void additionRequested(int universe);
|
||||
|
||||
private:
|
||||
Ui::AddUniverseDialog *ui;
|
||||
};
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AddUniverseDialog</class>
|
||||
<widget class="QDialog" name="AddUniverseDialog">
|
||||
<layout class="QVBoxLayout" name="_3">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Universe</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spinBox">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>63999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="dialogButtonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>dialogButtonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>AddUniverseDialog</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>dialogButtonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>AddUniverseDialog</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>
|
|
@ -0,0 +1,7 @@
|
|||
#include "sacnexplorer.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SacnExplorer a(argc, argv);
|
||||
return a.exec();
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
#include "multiverseitem.h"
|
||||
#include "multiversemodel.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QMetaEnum>
|
||||
#include <QMetaType>
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::MultiverseItem
|
||||
* @param universe
|
||||
* @param parent
|
||||
*/
|
||||
MultiverseItem::MultiverseItem(MultiverseItem* parent,
|
||||
QSacnUniverse *universe,
|
||||
discoveredUniverse *discovery)
|
||||
: universe_(universe)
|
||||
, discovery_(discovery)
|
||||
, parentItem_(parent)
|
||||
, override_data_(QVariant())
|
||||
{
|
||||
if(parent)
|
||||
parent->appendChild(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::~MultiverseItem
|
||||
*/
|
||||
MultiverseItem::~MultiverseItem()
|
||||
{
|
||||
for (const auto & child : childItems_)
|
||||
delete child;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::appendChild
|
||||
* @param item
|
||||
*/
|
||||
void MultiverseItem::appendChild(MultiverseItem* item)
|
||||
{
|
||||
childItems_.append(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::removeChild
|
||||
* @param child
|
||||
*/
|
||||
void MultiverseItem::removeChild(MultiverseItem* child)
|
||||
{
|
||||
for (int i = 0; i < childItems_.size(); ++i)
|
||||
if (childItems_.at(i) == child)
|
||||
childItems_.remove(i);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::setOverrideData
|
||||
* @param data
|
||||
*/
|
||||
void MultiverseItem::setOverrideData(QVariant data)
|
||||
{
|
||||
override_data_ = data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::child
|
||||
* @param row
|
||||
* @return
|
||||
*/
|
||||
MultiverseItem* MultiverseItem::child(int row)
|
||||
{
|
||||
if (row < 0 || row >= childItems_.size())
|
||||
return nullptr;
|
||||
return childItems_.at(row);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::childCount
|
||||
* @return
|
||||
*/
|
||||
int MultiverseItem::childCount() const
|
||||
{
|
||||
return childItems_.count();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::row
|
||||
* @return
|
||||
*/
|
||||
int MultiverseItem::row() const
|
||||
{
|
||||
if (parentItem_)
|
||||
return parentItem_->childItems_.indexOf(const_cast<MultiverseItem*>(this));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::data
|
||||
* @param column
|
||||
* @return
|
||||
*/
|
||||
QVariant MultiverseItem::data(int column, int role) const
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
if (!universe_ && !discovery_)
|
||||
return column ? QVariant() : override_data_;
|
||||
if (universe_)
|
||||
{
|
||||
switch (static_cast<MultiverseModel::Column>(column))
|
||||
{
|
||||
case MultiverseModel::Universe:
|
||||
return universe_->number();
|
||||
case MultiverseModel::Priority:
|
||||
{
|
||||
auto v = universe_->priority();
|
||||
if (v > 200)
|
||||
return QVariant();
|
||||
return v;
|
||||
}
|
||||
case MultiverseModel::Description:
|
||||
return universe_->description();
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
if (discovery_)
|
||||
{
|
||||
switch (static_cast<MultiverseModel::Column>(column))
|
||||
{
|
||||
case MultiverseModel::Universe:
|
||||
return discovery_->universe;
|
||||
case MultiverseModel::Description:
|
||||
return QString::fromUtf8(discovery_->description);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
}
|
||||
case Qt::FontRole:
|
||||
if (!universe_ && !discovery_)
|
||||
{
|
||||
QFont bold;
|
||||
bold.setBold(true);
|
||||
return QVariant(bold);
|
||||
}
|
||||
return QVariant();
|
||||
case Qt::EditRole:
|
||||
if (universe_)
|
||||
return QVariant(QVariant::fromValue(universe_));
|
||||
if (discovery_)
|
||||
return QVariant(QVariant::fromValue(static_cast<void*>(discovery_)));
|
||||
return data(column, Qt::DisplayRole);
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::flags
|
||||
* @param column
|
||||
* @return
|
||||
*/
|
||||
Qt::ItemFlags MultiverseItem::flags(int column, Qt::ItemFlags base) const
|
||||
{
|
||||
if (!universe_ && !universe_)
|
||||
{
|
||||
if (column)
|
||||
return Qt::NoItemFlags;
|
||||
return base & ~Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
base |= Qt::ItemIsEditable;
|
||||
|
||||
switch (static_cast<MultiverseModel::Column>(column))
|
||||
{
|
||||
case MultiverseModel::Universe:
|
||||
return base;
|
||||
case MultiverseModel::Priority:
|
||||
return base;
|
||||
case MultiverseModel::Description:
|
||||
return base;
|
||||
default:
|
||||
return Qt::NoItemFlags;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseItem::parentItem
|
||||
* @return
|
||||
*/
|
||||
MultiverseItem * MultiverseItem::parentItem()
|
||||
{
|
||||
return parentItem_;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
|
||||
#include "sacn/extended.h"
|
||||
|
||||
#include <QVariant>
|
||||
#include <QVector>
|
||||
|
||||
class QSacnUniverse; // forward declare
|
||||
|
||||
using discoveredUniverse = sACN::EXTENDED::DISCOVERY::discoveredUniverse;
|
||||
|
||||
/**
|
||||
* @brief The MultiverseItem class
|
||||
*/
|
||||
class MultiverseItem
|
||||
{
|
||||
public:
|
||||
explicit MultiverseItem(MultiverseItem* parentItem = nullptr,
|
||||
QSacnUniverse * universe = nullptr,
|
||||
discoveredUniverse * discovery = nullptr);
|
||||
virtual ~MultiverseItem();
|
||||
|
||||
void appendChild(MultiverseItem* child);
|
||||
void removeChild(MultiverseItem* child);
|
||||
void setOverrideData(QVariant data);
|
||||
|
||||
MultiverseItem * child(int row);
|
||||
int childCount() const;
|
||||
QVariant data(int column, int role = Qt::DisplayRole) const;
|
||||
Qt::ItemFlags flags(int column, Qt::ItemFlags base) const;
|
||||
int row() const;
|
||||
MultiverseItem * parentItem();
|
||||
|
||||
private:
|
||||
QVector<MultiverseItem*> childItems_;
|
||||
QSacnUniverse* universe_;
|
||||
discoveredUniverse* discovery_;
|
||||
MultiverseItem* parentItem_;
|
||||
QVariant override_data_;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(discoveredUniverse*)
|
||||
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
#include "multiverseitem.h"
|
||||
#include "multiversemodel.h"
|
||||
#include "uuid/uuid.h"
|
||||
#include "qsacnnode.h"
|
||||
|
||||
#include <QMetaEnum>
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::MultiverseModel
|
||||
* @param parent
|
||||
* @param node
|
||||
*/
|
||||
MultiverseModel::MultiverseModel(QObject *parent, QSacnNode *node)
|
||||
: QAbstractItemModel(parent)
|
||||
, node_(node)
|
||||
, rootItem_(new MultiverseItem())
|
||||
{
|
||||
QMetaEnum e = QMetaEnum::fromType<MultiverseModel::Catagory>();
|
||||
for (int k = 0; k < e.keyCount(); k++)
|
||||
{
|
||||
auto item = new MultiverseItem(rootItem_);
|
||||
item->setOverrideData(QString(e.key(k)));
|
||||
auto idx = MultiverseModel::index(k, 0, QModelIndex());
|
||||
categoryIndexes.insert(static_cast<MultiverseModel::Catagory>
|
||||
(e.value(k)), idx);
|
||||
}
|
||||
|
||||
connect(node, &QSacnNode::subscribing,
|
||||
this, &MultiverseModel::doSubscription);
|
||||
connect(node, &QSacnNode::creating,
|
||||
this, &MultiverseModel::doCreation);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::~MultiverseModel
|
||||
*/
|
||||
MultiverseModel::~MultiverseModel()
|
||||
{
|
||||
delete rootItem_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::root
|
||||
* @return
|
||||
*/
|
||||
MultiverseItem * MultiverseModel::root()
|
||||
{
|
||||
return rootItem_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::getItem
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
MultiverseItem * MultiverseModel::getItem(const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid())
|
||||
{
|
||||
auto item = static_cast<MultiverseItem*>(index.internalPointer());
|
||||
if (item)
|
||||
return item;
|
||||
}
|
||||
return rootItem_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::headerData
|
||||
* @param section
|
||||
* @param orientation
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
QVariant MultiverseModel::headerData(int section, Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
switch (static_cast<Column>(section)) {
|
||||
case Universe:
|
||||
return QString(tr("Universe"));
|
||||
case Priority:
|
||||
return QString(tr("Priority"));
|
||||
case Description:
|
||||
return QString(tr("Description"));
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::index
|
||||
* @param row
|
||||
* @param column
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
QModelIndex MultiverseModel::index(int row, int column,
|
||||
const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid() && parent.column() != 0)
|
||||
return QModelIndex();
|
||||
|
||||
MultiverseItem *parentItem = getItem(parent);
|
||||
if (!parentItem)
|
||||
return QModelIndex();
|
||||
|
||||
auto childItem = parentItem->child(row);
|
||||
if (childItem)
|
||||
return createIndex(row, column, childItem);
|
||||
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::parent
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
QModelIndex MultiverseModel::parent(const QModelIndex &index) const
|
||||
{
|
||||
if (!checkIndex(index, CheckIndexOption::IndexIsValid |
|
||||
CheckIndexOption::DoNotUseParent))
|
||||
return QModelIndex();
|
||||
|
||||
auto childItem = getItem(index);
|
||||
auto parentItem = childItem ? childItem->parentItem() : nullptr;
|
||||
|
||||
if (parentItem == rootItem_ || !parentItem)
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(parentItem->row(), 0, parentItem);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::rowCount
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
int MultiverseModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
auto parentItem = getItem(parent);
|
||||
return parentItem ? parentItem->childCount() : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::columnCount
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
int MultiverseModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return QMetaEnum::fromType<Column>().keyCount();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::data
|
||||
* @param index
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
QVariant MultiverseModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
|
||||
return QVariant();
|
||||
|
||||
return getItem(index)->data(index.column(), role);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::flags
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
Qt::ItemFlags MultiverseModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
auto item = getItem(index);
|
||||
|
||||
if (!item)
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
return item->flags(index.column(), QAbstractItemModel::flags(index));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::insert
|
||||
* @param universe
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
void MultiverseModel::insert(const QModelIndex &parent,
|
||||
QSacnUniverse *universe,
|
||||
discoveredUniverse *discovery)
|
||||
{
|
||||
auto item = getItem(parent);
|
||||
beginInsertRows(parent, item->childCount(), item->childCount() + 1);
|
||||
new MultiverseItem(item, universe, discovery);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::doSubscription
|
||||
* @param universe
|
||||
*/
|
||||
void MultiverseModel::doSubscription(QSacnUniverse* universe)
|
||||
{
|
||||
auto parentIndex = categoryIndexes.value(MultiverseModel::Receiver);
|
||||
insert(parentIndex, universe);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MultiverseModel::doCreation
|
||||
* @param universe
|
||||
*/
|
||||
void MultiverseModel::doCreation(QSacnUniverse* universe)
|
||||
{
|
||||
auto parentIndex = categoryIndexes.value(MultiverseModel::Source);
|
||||
insert(parentIndex, universe);
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#pragma once
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include "qsacnuniverse.h"
|
||||
#include "multiverseitem.h"
|
||||
|
||||
class QSacnNode; // forward declare node class
|
||||
|
||||
/**
|
||||
* @brief The MultiverseModel class
|
||||
*/
|
||||
class MultiverseModel
|
||||
: public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// @brief The Catagory enum
|
||||
enum Catagory {
|
||||
Discovery,
|
||||
Receiver,
|
||||
Source
|
||||
};
|
||||
Q_ENUM(Catagory)
|
||||
|
||||
/// @brief The Column enum
|
||||
enum Column {
|
||||
Universe,
|
||||
Priority,
|
||||
Description
|
||||
};
|
||||
Q_ENUM(Column)
|
||||
|
||||
explicit MultiverseModel(QObject *parent = nullptr,
|
||||
QSacnNode *node = nullptr);
|
||||
virtual ~MultiverseModel();
|
||||
|
||||
// Model overrides:
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
QModelIndex index(int row, int column,
|
||||
const QModelIndex &parent = QModelIndex()) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
|
||||
// non-standard model operations
|
||||
MultiverseItem * root();
|
||||
void insert(const QModelIndex &parent,
|
||||
QSacnUniverse *universe = nullptr,
|
||||
discoveredUniverse *discovery = nullptr);
|
||||
|
||||
QMap<MultiverseModel::Catagory, QModelIndex> categoryIndexes;
|
||||
|
||||
public slots:
|
||||
void doSubscription(QSacnUniverse*);
|
||||
void doCreation(QSacnUniverse*);
|
||||
|
||||
private:
|
||||
MultiverseItem * getItem(const QModelIndex &index) const;
|
||||
|
||||
QSacnNode * node_;
|
||||
MultiverseItem * rootItem_;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#include "multiverseview.h"
|
||||
#include "multiversemodel.h"
|
||||
#include "ui_multiverseview.h"
|
||||
#include "universeviewdelegate.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
/**
|
||||
* @brief MultiverseView::MultiverseView
|
||||
* @param parent
|
||||
*/
|
||||
MultiverseView::MultiverseView(QWidget *parent, QSacnNode *node)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::MultiverseView)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->multiverseView->setModel(new MultiverseModel(this, node));
|
||||
ui->multiverseView->setItemDelegate(new UniverseViewDelegate());
|
||||
ui->multiverseView->expandAll();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseView::~MultiverseView
|
||||
*/
|
||||
MultiverseView::~MultiverseView()
|
||||
{
|
||||
delete ui;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
multiverseview.h
|
||||
|
||||
Copyright (c) 2021 Kevin Matz (kevin.matz@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QMainWindow>
|
||||
#include "qsacnnode.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
class MultiverseView;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MultiverseView
|
||||
: public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MultiverseView(QWidget *parent = nullptr,
|
||||
QSacnNode* node = nullptr);
|
||||
virtual ~MultiverseView();
|
||||
|
||||
private:
|
||||
Ui::MultiverseView *ui;
|
||||
};
|
|
@ -0,0 +1,134 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MultiverseView</class>
|
||||
<widget class="QMainWindow" name="MultiverseView">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>391</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>sACN Multiverse</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTreeView" name="multiverseView">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoExpandDelay">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="animated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>120</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>25</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuEPI_19">
|
||||
<property name="title">
|
||||
<string>EPI 19</string>
|
||||
</property>
|
||||
<addaction name="actionUACN"/>
|
||||
</widget>
|
||||
<addaction name="menuEPI_19"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>toolBar</string>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<addaction name="actionCreate"/>
|
||||
<addaction name="actionTerminate"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionSubscribe"/>
|
||||
<addaction name="actionUnsubscribe"/>
|
||||
</widget>
|
||||
<action name="actionSubscribe">
|
||||
<property name="text">
|
||||
<string>Subscribe</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Subscribe to an sACN Universe</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>+</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUnsubscribe">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unsubscribe</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionCreate">
|
||||
<property name="text">
|
||||
<string>Create</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>N</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionTerminate">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Terminate</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Terminate</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>X</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUACN">
|
||||
<property name="text">
|
||||
<string>User Assigned Component Name</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Set this Component's UACN</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,74 @@
|
|||
#include "sacnexplorer.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSettings>
|
||||
|
||||
SacnExplorer::SacnExplorer(int argc, char *argv[])
|
||||
: QApplication(argc, argv)
|
||||
{
|
||||
setOrganizationName("Company235");
|
||||
setOrganizationDomain("company235.com");
|
||||
setApplicationName(tr("sACN Explorer"));
|
||||
|
||||
loadSettings();
|
||||
|
||||
node_ = new QSacnNode(this, cid_);
|
||||
qDebug() << "sACN node started with CID" << node_->cid().string().c_str();
|
||||
node_->assignUserName(applicationName().toStdString());
|
||||
qDebug() << "Starting sACN discovery.";
|
||||
node_->discoveryStart();
|
||||
|
||||
window = new MultiverseView(nullptr, node_);
|
||||
window->show();
|
||||
|
||||
node_->subscribe(1);
|
||||
node_->subscribe(2);
|
||||
node_->subscribe(3);
|
||||
node_->subscribe(4);
|
||||
|
||||
node_->create(1);
|
||||
node_->sACN::Source::universe(1)->setValue(100, 1);
|
||||
node_->create(2);
|
||||
node_->sACN::Source::universe(2)->setValue(100, 2);
|
||||
node_->create(3);
|
||||
node_->sACN::Source::universe(3)->setValue(100, 3);
|
||||
}
|
||||
|
||||
|
||||
SacnExplorer::~SacnExplorer()
|
||||
{
|
||||
saveSettings();
|
||||
|
||||
delete window;
|
||||
delete node_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MultiverseView::loadSettings
|
||||
*/
|
||||
void SacnExplorer::loadSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
qDebug() << "Loading application settings from" << settings.fileName();
|
||||
|
||||
settings.beginGroup("acn");
|
||||
cid_ = QUuid(settings.value("cid",
|
||||
QUuid::createUuid().toString()).toString());
|
||||
qDebug() << "Persistent CID is" << cid_.toString().toStdString().c_str();
|
||||
settings.endGroup();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief MultiverseView::saveSettings
|
||||
*/
|
||||
void SacnExplorer::saveSettings()
|
||||
{
|
||||
QSettings settings;
|
||||
qDebug() << "Saving application settings to" << settings.fileName();
|
||||
|
||||
settings.beginGroup("acn");
|
||||
settings.setValue("cid", cid_.toString());
|
||||
settings.endGroup();
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include "multiverseview.h"
|
||||
#include "qsacnnode.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QUuid>
|
||||
|
||||
class SacnExplorer
|
||||
: public QApplication
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SacnExplorer(int argc, char *argv[]);
|
||||
virtual ~SacnExplorer();
|
||||
|
||||
private:
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
|
||||
MultiverseView* window;
|
||||
QSacnNode *node_;
|
||||
QUuid cid_;
|
||||
};
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
#include "universemodel.h"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QFont>
|
||||
#include <QChar>
|
||||
#include <QMetaEnum>
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::UniverseModel
|
||||
* @param parent
|
||||
*/
|
||||
UniverseModel::UniverseModel(QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
, universe_(nullptr)
|
||||
, data_mode_(Decimal)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::headerData
|
||||
* @param section
|
||||
* @param orientation
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
QVariant UniverseModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
switch (role)
|
||||
{
|
||||
case Qt::DisplayRole:
|
||||
switch (orientation)
|
||||
{
|
||||
case Qt::Horizontal:
|
||||
return section + 1;
|
||||
case Qt::Vertical:
|
||||
return section * 10;
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::rowCount
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
int UniverseModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
return 52;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::columnCount
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
int UniverseModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::data
|
||||
* @param index
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
QVariant UniverseModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
|
||||
return QVariant();
|
||||
|
||||
if (!universe_)
|
||||
return QVariant();
|
||||
|
||||
uint16_t slot = (index.row() * 10) + (index.column() + 1);
|
||||
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
if (slot == 0 || slot > 512)
|
||||
return QVariant();
|
||||
switch (data_mode_)
|
||||
{
|
||||
case Decimal:
|
||||
return universe_->slot(slot);
|
||||
case Hex:
|
||||
return QString("%1")
|
||||
.arg(universe_->slot(slot), 2, 16, QChar('0'))
|
||||
.toUpper();
|
||||
case Percent:
|
||||
return QString("%1%").arg((universe_->slot(slot) / 255.0F) * 100,
|
||||
0, 'f', 0, '0');
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
case Qt::FontRole:
|
||||
return QFont("monospace");
|
||||
case Qt::TextAlignmentRole:
|
||||
return int(Qt::AlignCenter | Qt::AlignVCenter);
|
||||
case Qt::ForegroundRole:
|
||||
{
|
||||
if (slot > universe_->activeSlots() - 1)
|
||||
return QBrush(Qt::gray);
|
||||
return QVariant();
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::setData
|
||||
* @param index
|
||||
* @param value
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
bool UniverseModel::setData(const QModelIndex &index, const QVariant &value,
|
||||
int role)
|
||||
{
|
||||
if (!universe_->isEditable())
|
||||
return false;
|
||||
|
||||
if (data(index, role) == value)
|
||||
return false;
|
||||
|
||||
uint16_t slot = (index.row() * 10) + (index.column() + 1);
|
||||
uint8_t data;
|
||||
|
||||
switch (data_mode_)
|
||||
{
|
||||
case Decimal:
|
||||
{
|
||||
if (!value.canConvert<uint>())
|
||||
return false;
|
||||
uint d = value.toUInt();
|
||||
if (d > 255)
|
||||
return false;
|
||||
data = d;
|
||||
}
|
||||
break;
|
||||
case Hex:
|
||||
{
|
||||
if (!value.canConvert<QString>())
|
||||
return false;
|
||||
bool ok;
|
||||
uint d = value.toString().toInt(&ok, 16);
|
||||
if (!ok || d > 255)
|
||||
return false;
|
||||
data = d;
|
||||
}
|
||||
break;
|
||||
case Percent:
|
||||
{
|
||||
if (!value.canConvert<double>())
|
||||
return false;
|
||||
int d = 255 * (value.toDouble() / 100);
|
||||
if (d < 0 || d > 255)
|
||||
return false;
|
||||
data = d;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
universe_->setValue(slot, data);
|
||||
emit dataChanged(index, index, QVector<int>() << role);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::flags
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
Qt::ItemFlags UniverseModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!checkIndex(index, CheckIndexOption::IndexIsValid))
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
if (!universe_)
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
uint16_t slot = (index.row() * 10) + (index.column() + 1);
|
||||
|
||||
if (slot == 0 || slot > 512)
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
auto f = QAbstractItemModel::flags(index);
|
||||
return universe_->isEditable() ? f | Qt::ItemIsEditable : f;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::universeRefreshed
|
||||
*/
|
||||
void UniverseModel::universeRefreshed() {
|
||||
emit dataChanged(index(0,0), index(rowCount(), columnCount()));
|
||||
emit recievedUpdate(universe_);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::setDataMode
|
||||
* @param mode
|
||||
*/
|
||||
void UniverseModel::setDataMode(const QString mode)
|
||||
{
|
||||
auto metaEnum = QMetaEnum::fromType<data_modes>();
|
||||
data_mode_ = static_cast<data_modes>(metaEnum.keyToValue(mode.toLocal8Bit()));
|
||||
emit dataChanged(index(0,0), index(rowCount(), columnCount()));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::setUniverse
|
||||
* @param universe
|
||||
*/
|
||||
void UniverseModel::setUniverse(QSacnUniverse *universe)
|
||||
{
|
||||
if (universe_)
|
||||
disconnect(universe_, 0, this, 0);
|
||||
universe_ = universe;
|
||||
connect(universe_, &QSacnUniverse::changed,
|
||||
this, &UniverseModel::universeRefreshed);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::universe
|
||||
* @return
|
||||
*/
|
||||
QSacnUniverse * UniverseModel::universe() const
|
||||
{
|
||||
return universe_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseModel::dataMode
|
||||
* @return
|
||||
*/
|
||||
UniverseModel::data_modes UniverseModel::dataMode()
|
||||
{
|
||||
return data_mode_;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#include <QAbstractTableModel>
|
||||
#include "qsacnuniverse.h"
|
||||
|
||||
class UniverseModel
|
||||
: public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// @brief The data_modes enum
|
||||
enum data_modes {
|
||||
Decimal,
|
||||
Hex,
|
||||
Percent
|
||||
};
|
||||
Q_ENUM(data_modes)
|
||||
|
||||
explicit UniverseModel(QObject *parent = nullptr);
|
||||
|
||||
// Model overrides:
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value,
|
||||
int role = Qt::EditRole) override;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
|
||||
// Data source:
|
||||
void setUniverse(QSacnUniverse *universe);
|
||||
QSacnUniverse * universe() const;
|
||||
data_modes dataMode();
|
||||
|
||||
signals:
|
||||
void recievedUpdate(const QSacnUniverse*);
|
||||
|
||||
public slots:
|
||||
void universeRefreshed();
|
||||
void setDataMode(const QString mode);
|
||||
|
||||
private:
|
||||
QSacnUniverse * universe_;
|
||||
data_modes data_mode_;
|
||||
};
|
|
@ -0,0 +1,98 @@
|
|||
#include "universeview.h"
|
||||
#include "ui_universeview.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
#include <QMetaEnum>
|
||||
|
||||
/**
|
||||
* @brief UniverseView::UniverseView
|
||||
* @param parent
|
||||
*/
|
||||
UniverseView::UniverseView(QWidget *parent, QSacnUniverse *universe)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::UniverseView())
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
auto model = new UniverseModel(this);
|
||||
ui->tableView->setModel(model);
|
||||
|
||||
model->setUniverse(universe);
|
||||
|
||||
// update the status bar whenever the universe refreshes
|
||||
connect(model, &UniverseModel::recievedUpdate,
|
||||
this, &UniverseView::updateStatus);
|
||||
|
||||
// add data format combobox to toolbar
|
||||
auto formatLabel = new QLabel(this);
|
||||
formatLabel->setText(tr("Data Format") + ": ");
|
||||
ui->toolBar->addWidget(formatLabel);
|
||||
auto dataModes = new QComboBox(this);
|
||||
const QMetaEnum types = QMetaEnum::fromType<UniverseModel::data_modes>();
|
||||
for (int i=0; i < types.keyCount(); ++i)
|
||||
dataModes->addItem(types.key(i));
|
||||
connect(dataModes, &QComboBox::currentTextChanged,
|
||||
model, &UniverseModel::setDataMode);
|
||||
ui->toolBar->addWidget(dataModes);
|
||||
|
||||
ui->toolBar->addSeparator();
|
||||
|
||||
// add priority picker to the toolbar
|
||||
auto priorityLabel = new QLabel(this);
|
||||
priorityLabel->setText(tr("Priority") + ": ");
|
||||
ui->toolBar->addWidget(priorityLabel);
|
||||
prioritySpinBox = new QSpinBox(this);
|
||||
prioritySpinBox->setMinimum(0);
|
||||
prioritySpinBox->setValue(100);
|
||||
prioritySpinBox->setMaximum(200);
|
||||
prioritySpinBox->setEnabled(false);
|
||||
ui->toolBar->addWidget(prioritySpinBox);
|
||||
|
||||
ui->toolBar->addSeparator();
|
||||
|
||||
updateStatus(universe);
|
||||
if (universe->isEditable())
|
||||
{
|
||||
prioritySpinBox->setValue(universe->priority());
|
||||
prioritySpinBox->setEnabled(true);
|
||||
connect(prioritySpinBox, &QSpinBox::valueChanged,
|
||||
universe, &QSacnUniverse::setPriority);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseView::~UniverseView
|
||||
*/
|
||||
UniverseView::~UniverseView()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UniverseView::updateStatusBar
|
||||
* @param universe
|
||||
*/
|
||||
void UniverseView::updateStatus(const QSacnUniverse * universe)
|
||||
{
|
||||
// window title
|
||||
QString titlestring = QString("%1 " + tr("Universe") + " %2 - \"%3\"").arg(
|
||||
universe->isEditable() ? tr("Editing") : tr("Viewing"),
|
||||
QString::number(universe->number()),
|
||||
universe->description());
|
||||
this->setWindowTitle(titlestring);
|
||||
|
||||
if (!universe->isEditable())
|
||||
{
|
||||
// status bar
|
||||
ui->statusbar->clearMessage();
|
||||
QString message = QString("%1 " + tr("Hz")).arg(
|
||||
QString::number(universe->rxRate()));
|
||||
ui->statusbar->showMessage(message, 2500);
|
||||
|
||||
// priority spinbox
|
||||
prioritySpinBox->setValue(universe->priority());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QSpinBox>
|
||||
|
||||
#include "multiversemodel.h"
|
||||
#include "universemodel.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
class UniverseView;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class UniverseView
|
||||
: public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit UniverseView(QWidget *parent = nullptr,
|
||||
QSacnUniverse* universe = nullptr);
|
||||
virtual ~UniverseView();
|
||||
|
||||
public slots:
|
||||
void updateStatus(const QSacnUniverse*);
|
||||
|
||||
private:
|
||||
Ui::UniverseView *ui;
|
||||
QSpinBox *prioritySpinBox;
|
||||
};
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>UniverseView</class>
|
||||
<widget class="QMainWindow" name="UniverseView">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>800</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableView" name="tableView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderDefaultSectionSize">
|
||||
<number>60</number>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar"/>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<widget class="QToolBar" name="toolBar">
|
||||
<attribute name="toolBarArea">
|
||||
<enum>TopToolBarArea</enum>
|
||||
</attribute>
|
||||
<attribute name="toolBarBreak">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,32 @@
|
|||
#include "adduniversedialog.h"
|
||||
#include "qsacnuniverse.h"
|
||||
#include "sacn/extended.h"
|
||||
#include "universeview.h"
|
||||
#include "universeviewdelegate.h"
|
||||
|
||||
|
||||
QWidget * UniverseViewDelegate::createEditor(QWidget *parent,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QVariant data = index.data(Qt::EditRole);
|
||||
|
||||
if (data.metaType().id() == qMetaTypeId<QSacnUniverse*>())
|
||||
{
|
||||
auto univ = data.value<QSacnUniverse*>();
|
||||
auto universeView = new UniverseView(parent, univ);
|
||||
universeView->show();
|
||||
|
||||
return new QWidget(parent);
|
||||
}
|
||||
|
||||
if (index.data().canConvert<sACN::EXTENDED::DISCOVERY::discoveredUniverse*>())
|
||||
{
|
||||
auto disc = data.value<sACN::EXTENDED::DISCOVERY::discoveredUniverse*>();
|
||||
auto subscribe = new AddUniverseDialog(parent, disc->universe,
|
||||
tr("Subscribe to Universe"));
|
||||
return subscribe;
|
||||
}
|
||||
|
||||
return QStyledItemDelegate::createEditor(parent, option, index);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
class UniverseViewDelegate
|
||||
: public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override;
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
add_subdirectory(qt)
|
|
@ -2,14 +2,8 @@ project(QsACN VERSION 0.1 LANGUAGES CXX)
|
|||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG")
|
||||
endif()
|
||||
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Network Gui REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Network Gui REQUIRED)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Network REQUIRED)
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Network REQUIRED)
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED)
|
||||
|
||||
|
@ -18,15 +12,16 @@ target_sources(${PROJECT_NAME}
|
|||
qsacnnode.h
|
||||
qsacnuniverse.h
|
||||
PRIVATE
|
||||
qsacn_global.h
|
||||
qsacnnode.cpp
|
||||
qsacnuniverse.cpp
|
||||
qsacn_global.h
|
||||
)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC
|
||||
Qt${QT_VERSION_MAJOR}::Network
|
||||
Qt${QT_VERSION_MAJOR}::Gui
|
||||
OpenLCP)
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
PUBLIC
|
||||
Qt${QT_VERSION_MAJOR}::Network
|
||||
LCP
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC ${PROJECT_NAME}_LIBRARY)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
project(OpenLCP VERSION 0.2.0 LANGUAGES CXX)
|
||||
set(DEFAULT_BUILD_TYPE "Release")
|
||||
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
project(LCP VERSION 0.2.0 LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue