#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(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(_popup_node)); } void widget::add_integrator() { new gtl::math::intg(static_cast(_popup_node)); } void widget::add_differentiator() { new gtl::math::diff(static_cast(_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(parent)); } else if(node_element.attribute("node", "") == "gtl::math::intg") { node = new gtl::math::intg(static_cast(parent)); } else if(node_element.attribute("node", "") == "gtl::math::diff") { node = new gtl::math::diff(static_cast(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(current.internalPointer()); static_cast(_ui.stackedWidget->widget(node->type()))->set_node(node); _ui.stackedWidget->setCurrentIndex(node->type()); } } } }