321 lines
12 KiB
C++
321 lines
12 KiB
C++
#include "gtl_gui_config_widget.h"
|
|
|
|
#include "gtl_gui_config_widget_device.h"
|
|
#include "gtl_gui_config_widget_analog.h"
|
|
|
|
#include "hw/gtl_hw_player.h"
|
|
|
|
#include "math/gtl_math_filter_iir.h"
|
|
#include "math/gtl_math_intg.h"
|
|
#include "math/gtl_math_diff.h"
|
|
|
|
namespace gtl
|
|
{
|
|
namespace gui
|
|
{
|
|
namespace config
|
|
{
|
|
widget::widget(gtl::data_model* model, QString hwplugings_path, QWidget *parent)
|
|
: QWidget{parent}
|
|
, _model(model)
|
|
, _hw_dialog(hwplugings_path)
|
|
, _popup_node(NULL)
|
|
{
|
|
_ui.setupUi(this);
|
|
|
|
_ui.view->setModel(_model);
|
|
_ui.view->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
connect(_ui.view, &QWidget::customContextMenuRequested, this, &widget::menu_reques);
|
|
|
|
QItemSelectionModel* selection = new QItemSelectionModel(model);
|
|
_ui.view->setSelectionModel(selection);
|
|
connect(selection, &QItemSelectionModel::currentChanged, this, &widget::selection_changed);
|
|
|
|
|
|
_add_hardware_action = new QAction(tr("Add hardware"), this);
|
|
connect(_add_hardware_action, &QAction::triggered, this, &widget::add_hardware);
|
|
|
|
_add_generator_action = new QAction(tr("Add virtual generator"), this);
|
|
connect(_add_generator_action, &QAction::triggered, this, &widget::add_generator);
|
|
|
|
_add_audio_action = new QAction(tr("Add audio input device"), this);
|
|
connect(_add_audio_action, &QAction::triggered, this, &widget::add_audio);
|
|
|
|
|
|
_add_iir_filter_action = new QAction(tr("Add IIR filter"), this);
|
|
connect(_add_iir_filter_action, &QAction::triggered, this, &widget::add_iir_filter);
|
|
|
|
_add_integrator_action = new QAction(tr("Add integrator"), this);
|
|
connect(_add_integrator_action, &QAction::triggered, this, &widget::add_integrator);
|
|
|
|
_add_differentioator_action = new QAction(tr("Add differentiator"), this);
|
|
connect(_add_differentioator_action, &QAction::triggered, this, &widget::add_differentiator);
|
|
|
|
_add_player_action = new QAction(tr("Add player"), this);
|
|
connect(_add_player_action, &QAction::triggered, this, &widget::add_player);
|
|
|
|
_remove_action = new QAction(tr("Remove"), this);
|
|
connect(_remove_action, &QAction::triggered, this, &widget::remove);
|
|
|
|
_set_config_action = new QAction(tr("Set config"), this);
|
|
connect(_set_config_action, &QAction::triggered, this, &widget::set_config);
|
|
|
|
_get_config_action = new QAction(tr("Get config"), this);
|
|
connect(_get_config_action, &QAction::triggered, this, &widget::get_config);
|
|
|
|
connect(_model, >l::data_model::create_node, this, &widget::create_node);
|
|
|
|
|
|
_ui.stackedWidget->addWidget(new widget_device(this));
|
|
_ui.stackedWidget->addWidget(new widget_analog(this));
|
|
|
|
|
|
}
|
|
|
|
void widget::save(QDomElement &root_element)
|
|
{
|
|
QDomElement devices_element = root_element.ownerDocument().createElement("devices");
|
|
root_element.appendChild(devices_element);
|
|
|
|
QDomElement splitter_element = root_element.ownerDocument().createElement("splitter");
|
|
root_element.appendChild(splitter_element);
|
|
splitter_element.setAttribute("state", QString(_ui.splitter->saveState().toBase64()));
|
|
|
|
_model->save(devices_element);
|
|
}
|
|
|
|
void widget::load(const QDomElement &root_element)
|
|
{
|
|
clear();
|
|
|
|
QDomElement devices_element = root_element.firstChildElement("devices");
|
|
|
|
QDomElement splitter_element = root_element.firstChildElement("splitter");
|
|
_ui.splitter->restoreState(QByteArray::fromBase64(splitter_element.attribute("state", "").toUtf8()));
|
|
|
|
_model->load(devices_element);
|
|
}
|
|
|
|
void widget::clear()
|
|
{
|
|
_model->clear();
|
|
for(auto it = _devices.begin(); it != _devices.end(); it++)
|
|
delete *it;
|
|
|
|
_devices.clear();
|
|
}
|
|
|
|
hw::device* widget::add(hw::device *device)
|
|
{
|
|
_model->add_device(device->gtl_device());
|
|
_devices.push_back(device);
|
|
|
|
return device;
|
|
}
|
|
|
|
void widget::menu_reques(const QPoint &pos)
|
|
{
|
|
QMenu menu;
|
|
|
|
QModelIndex index = _ui.view->indexAt(pos);
|
|
_popup_node = static_cast<gtl::data_model_node*>(index.internalPointer());
|
|
if(_popup_node == NULL)
|
|
{
|
|
menu.addAction(_add_hardware_action);
|
|
menu.addAction(_add_generator_action);
|
|
menu.addAction(_add_audio_action);
|
|
menu.addAction(_add_player_action);
|
|
}
|
|
else
|
|
{
|
|
if(_popup_node->type() == gtl::data_model_node::device)
|
|
{
|
|
/*
|
|
menu.addAction(_set_config_action);
|
|
menu.addAction(_get_config_action);
|
|
menu.addSeparator();
|
|
*/
|
|
menu.addAction(_remove_action);
|
|
}
|
|
else if(_popup_node->type() == gtl::data_model_node::analog)
|
|
{
|
|
menu.addAction(_add_iir_filter_action);
|
|
menu.addAction(_add_integrator_action);
|
|
menu.addAction(_add_differentioator_action);
|
|
|
|
if(_popup_node->parent_node()->type() != gtl::data_model_node::device)
|
|
{
|
|
menu.addSeparator();
|
|
menu.addAction(_remove_action);
|
|
}
|
|
}
|
|
}
|
|
|
|
menu.exec(_ui.view->viewport()->mapToGlobal(pos));
|
|
}
|
|
|
|
void widget::add_hardware()
|
|
{
|
|
_hw_dialog.setWindowTitle(tr("Add hardware"));
|
|
if(_hw_dialog.exec() == QDialog::Accepted)
|
|
{
|
|
if(std::find_if(_devices.begin(), _devices.end(), [=](gtl::hw::device* d){return d->gtl_device()->device_type() == _hw_dialog.type() && d->gtl_device()->id() == _hw_dialog.id();}) == _devices.end())
|
|
{
|
|
add(_hw_dialog.create_device())->start(_hw_dialog.id(), _hw_dialog.rate());
|
|
}
|
|
else
|
|
{
|
|
QMessageBox(QMessageBox::Icon::Warning, tr("Add device"), tr("Such device already exists.")).exec();
|
|
}
|
|
}
|
|
}
|
|
|
|
void widget::add_generator()
|
|
{
|
|
_hw_dialog.setWindowTitle(tr("Add generator"));
|
|
if(_hw_dialog.exec("generator") == QDialog::Accepted)
|
|
{
|
|
add(_hw_dialog.create_device("generator"))->start(_hw_dialog.id(), _hw_dialog.rate());
|
|
}
|
|
}
|
|
|
|
void widget::add_audio()
|
|
{
|
|
_hw_dialog.setWindowTitle(tr("Add audio input device"));
|
|
if(_hw_dialog.exec("audio") == QDialog::Accepted)
|
|
{
|
|
add(_hw_dialog.create_device("audio"))->start(_hw_dialog.id(), _hw_dialog.rate());
|
|
}
|
|
}
|
|
|
|
void widget::add_iir_filter()
|
|
{
|
|
new gtl::math::filter_iir(static_cast<gtl::analog_data*>(_popup_node));
|
|
}
|
|
|
|
void widget::add_integrator()
|
|
{
|
|
new gtl::math::intg(static_cast<gtl::analog_data*>(_popup_node));
|
|
}
|
|
|
|
void widget::add_differentiator()
|
|
{
|
|
new gtl::math::diff(static_cast<gtl::analog_data*>(_popup_node));
|
|
}
|
|
|
|
void widget::add_player()
|
|
{
|
|
/*
|
|
_hw_dialog.setWindowTitle(tr("Add player"));
|
|
if(_hw_dialog.exec("player") == QDialog::Accepted)
|
|
{
|
|
add(_hw_dialog.create_device("player"))->start("", 0);
|
|
}
|
|
*/
|
|
|
|
add(new gtl::hw::player())->start("", 0);
|
|
}
|
|
|
|
void widget::remove()
|
|
{
|
|
//_model->remove(_popup_node);
|
|
|
|
|
|
auto iter_device = std::find_if(_devices.begin(), _devices.end(), [=](const gtl::hw::device* d){return d->gtl_device() == _popup_node;});
|
|
if(iter_device != _devices.end())
|
|
{
|
|
delete *iter_device;
|
|
_devices.erase(iter_device);
|
|
}
|
|
else
|
|
delete _popup_node;
|
|
|
|
|
|
}
|
|
|
|
void widget::set_config()
|
|
{
|
|
auto iter_device = std::find_if(_devices.begin(), _devices.end(), [=](const gtl::hw::device* d){return d->gtl_device() == _popup_node;});
|
|
|
|
if(iter_device == _devices.end())
|
|
return;
|
|
|
|
QJsonDocument config = QJsonDocument::fromJson(QApplication::clipboard()->text().toUtf8());
|
|
|
|
if(config.isObject())
|
|
(*iter_device)->set_config(config.object());
|
|
else if(config.isArray())
|
|
(*iter_device)->set_config(config.array());
|
|
}
|
|
|
|
void widget::get_config()
|
|
{
|
|
auto iter_device = std::find_if(_devices.begin(), _devices.end(), [=](const gtl::hw::device* d){return d->gtl_device() == _popup_node;});
|
|
|
|
if(iter_device == _devices.end())
|
|
return;
|
|
|
|
QByteArray data;
|
|
if((*iter_device)->config().isObject())
|
|
data = QJsonDocument((*iter_device)->config().toObject()).toJson();
|
|
else
|
|
data = QJsonDocument((*iter_device)->config().toArray()).toJson();
|
|
|
|
QApplication::clipboard()->setText(QString(data));
|
|
|
|
}
|
|
|
|
gtl::data_model_node* widget::create_node(gtl::data_model_node* parent, QDomElement &node_element)
|
|
{
|
|
gtl::data_model_node* node = NULL;
|
|
|
|
if(node_element.attribute("node", "") == "gtl::device")
|
|
{
|
|
QString type = node_element.attribute("type", "");
|
|
|
|
gtl::hw::device* d = NULL;
|
|
if(type == "player")
|
|
d = new gtl::hw::player();
|
|
else
|
|
d = _hw_dialog.create_device(type);
|
|
|
|
if(d)
|
|
{
|
|
node = d->gtl_device();
|
|
_devices.push_back(d);
|
|
}
|
|
}
|
|
else if(node_element.attribute("node", "") == "gtl::math::filter_iir")
|
|
{
|
|
node = new gtl::math::filter_iir(static_cast<gtl::analog_data*>(parent));
|
|
}
|
|
else if(node_element.attribute("node", "") == "gtl::math::intg")
|
|
{
|
|
node = new gtl::math::intg(static_cast<gtl::analog_data*>(parent));
|
|
}
|
|
else if(node_element.attribute("node", "") == "gtl::math::diff")
|
|
{
|
|
node = new gtl::math::diff(static_cast<gtl::analog_data*>(parent));
|
|
}
|
|
|
|
return node;
|
|
}
|
|
|
|
void widget::selection_changed(const QModelIndex ¤t, const QModelIndex&)
|
|
{
|
|
if(!current.isValid())
|
|
{
|
|
_ui.stackedWidget->setCurrentIndex(0);
|
|
return;
|
|
}
|
|
|
|
|
|
gtl::data_model_node* node = static_cast<gtl::data_model_node*>(current.internalPointer());
|
|
|
|
static_cast<widget_node*>(_ui.stackedWidget->widget(node->type()))->set_node(node);
|
|
_ui.stackedWidget->setCurrentIndex(node->type());
|
|
}
|
|
}
|
|
}
|
|
}
|