test_sdk/gui/config/gtl_gui_config_widget.cpp

321 lines
12 KiB
C++
Raw Permalink Normal View History

#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, &gtl::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 &current, 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());
}
}
}
}