void InputPatch_Test::patch() { InputMap im(m_doc, 4); QCOMPARE(m_doc->ioPluginCache()->plugins().size(), 1); OutputPluginStub* stub = static_cast<OutputPluginStub*> (m_doc->ioPluginCache()->plugins().at(0)); QVERIFY(stub != NULL); QLCInputProfile prof1; prof1.setManufacturer("Foo"); prof1.setManufacturer("Bar"); InputPatch* ip = new InputPatch(0, this); ip->set(stub, 0, &prof1); QVERIFY(ip->m_plugin == stub); QVERIFY(ip->m_input == 0); QVERIFY(ip->m_profile == &prof1); QVERIFY(ip->pluginName() == stub->name()); QVERIFY(ip->inputName() == stub->inputs()[0]); QVERIFY(ip->profileName() == prof1.name()); QVERIFY(stub->m_openInputs.size() == 1); QVERIFY(stub->m_openInputs.at(0) == 0); QLCInputProfile prof2; prof2.setManufacturer("Xyzzy"); prof2.setManufacturer("Foobar"); ip->set(stub, 3, &prof2); QVERIFY(ip->m_plugin == stub); QVERIFY(ip->m_input == 3); QVERIFY(ip->m_profile == &prof2); QVERIFY(ip->pluginName() == stub->name()); QVERIFY(ip->inputName() == stub->inputs()[3]); QVERIFY(ip->profileName() == prof2.name()); QVERIFY(stub->m_openInputs.size() == 1); QVERIFY(stub->m_openInputs.at(0) == 3); ip->reconnect(); QVERIFY(ip->m_plugin == stub); QVERIFY(ip->m_input == 3); QVERIFY(ip->m_profile == &prof2); QVERIFY(ip->pluginName() == stub->name()); QVERIFY(ip->inputName() == stub->inputs()[3]); QVERIFY(ip->profileName() == prof2.name()); QVERIFY(stub->m_openInputs.size() == 1); QVERIFY(stub->m_openInputs.at(0) == 3); delete ip; QVERIFY(stub->m_openInputs.size() == 0); }
void InputPatch_Test::patch() { InputMap im(this); QDir dir(TESTPLUGINDIR); dir.setFilter(QDir::Files); dir.setNameFilters(QStringList() << QString("*%1").arg(KExtPlugin)); im.loadPlugins(dir); QVERIFY(im.m_plugins.size() > 0); InputPluginStub* stub = static_cast<InputPluginStub*> (im.m_plugins.at(0)); QVERIFY(stub != NULL); QLCInputProfile prof1; prof1.setManufacturer("Foo"); prof1.setManufacturer("Bar"); InputPatch* ip = new InputPatch(this); ip->set(stub, 0, false, &prof1); QVERIFY(ip->m_plugin == stub); QVERIFY(ip->m_input == 0); QVERIFY(ip->m_profile == &prof1); QVERIFY(ip->pluginName() == stub->name()); QVERIFY(ip->inputName() == stub->inputs()[0]); QVERIFY(ip->profileName() == prof1.name()); QVERIFY(stub->m_openLines.size() == 1); QVERIFY(stub->m_openLines.at(0) == 0); QVERIFY(ip->m_feedbackEnabled == false); QVERIFY(ip->feedbackEnabled() == false); QLCInputProfile prof2; prof2.setManufacturer("Xyzzy"); prof2.setManufacturer("Foobar"); ip->set(stub, 3, true, &prof2); QVERIFY(ip->m_plugin == stub); QVERIFY(ip->m_input == 3); QVERIFY(ip->m_profile == &prof2); QVERIFY(ip->pluginName() == stub->name()); QVERIFY(ip->inputName() == stub->inputs()[3]); QVERIFY(ip->profileName() == prof2.name()); QVERIFY(stub->m_openLines.size() == 1); QVERIFY(stub->m_openLines.at(0) == 3); QVERIFY(ip->m_feedbackEnabled == true); QVERIFY(ip->feedbackEnabled() == true); delete ip; QVERIFY(stub->m_openLines.size() == 0); }
void InputPatch_Test::patch() { InputPluginStub stub; QLCInputProfile prof1; prof1.setManufacturer("Foo"); prof1.setManufacturer("Bar"); InputPatch* ip = new InputPatch(this); ip->set(&stub, 0, false, &prof1); QVERIFY(ip->m_plugin == &stub); QVERIFY(ip->m_input == 0); QVERIFY(ip->m_profile == &prof1); QVERIFY(ip->pluginName() == stub.name()); QVERIFY(ip->inputName() == stub.inputs()[0]); QVERIFY(ip->profileName() == prof1.name()); QVERIFY(stub.m_openLines.size() == 1); QVERIFY(stub.m_openLines.at(0) == 0); QVERIFY(ip->m_feedbackEnabled == false); QVERIFY(ip->feedbackEnabled() == false); QLCInputProfile prof2; prof2.setManufacturer("Xyzzy"); prof2.setManufacturer("Foobar"); ip->set(&stub, 3, true, &prof2); QVERIFY(ip->m_plugin == &stub); QVERIFY(ip->m_input == 3); QVERIFY(ip->m_profile == &prof2); QVERIFY(ip->pluginName() == stub.name()); QVERIFY(ip->inputName() == stub.inputs()[3]); QVERIFY(ip->profileName() == prof2.name()); QVERIFY(stub.m_openLines.size() == 1); QVERIFY(stub.m_openLines.at(0) == 3); QVERIFY(ip->m_feedbackEnabled == true); QVERIFY(ip->feedbackEnabled() == true); delete ip; QVERIFY(stub.m_openLines.size() == 0); }
InputOutputPatchEditor::InputOutputPatchEditor(QWidget* parent, quint32 universe, InputMap* inputMap, OutputMap* outputMap) : QWidget(parent) , m_inputMap(inputMap) , m_outputMap(outputMap) , m_universe(universe) { Q_ASSERT(universe < m_inputMap->universes()); Q_ASSERT(inputMap != NULL); Q_ASSERT(outputMap != NULL); setupUi(this); m_infoBrowser->setOpenExternalLinks(true); m_infoBrowser->setFixedHeight(250); InputPatch* inputPatch = m_inputMap->patch(universe); OutputPatch* outputPatch = m_outputMap->patch(universe); OutputPatch* feedbackPatch = m_outputMap->feedbackPatch(universe); Q_ASSERT(inputPatch != NULL); Q_ASSERT(outputPatch != NULL); /* Copy these so they can be applied if the user cancels */ m_currentInputPluginName = inputPatch->pluginName(); m_currentInput = inputPatch->input(); m_currentProfileName = inputPatch->profileName(); //m_currentFeedbackEnabled = inputPatch->feedbackEnabled(); m_currentOutputPluginName = outputPatch->pluginName(); m_currentOutput = outputPatch->output(); m_currentFeedbackPluginName = feedbackPatch->pluginName(); m_currentFeedback = feedbackPatch->output(); m_mapTree->header()->setResizeMode(QHeaderView::ResizeToContents); m_mapTree->setSortingEnabled(true); m_mapTree->sortByColumn(KMapColumnPluginName, Qt::AscendingOrder); /* Setup UI controls */ setupMappingPage(); setupProfilePage(); /* Select the top-most "None" item */ m_mapTree->setCurrentItem(m_mapTree->topLevelItem(0)); /* Listen to plugin configuration changes */ connect(m_inputMap, SIGNAL(pluginConfigurationChanged(const QString&)), this, SLOT(slotPluginConfigurationChanged(const QString&))); /* Listen to plugin configuration changes */ connect(m_outputMap, SIGNAL(pluginConfigurationChanged(const QString&)), this, SLOT(slotPluginConfigurationChanged(const QString&))); }
void InputOutputManager::updateItem(QTreeWidgetItem* item, quint32 universe) { Q_ASSERT(item != NULL); InputPatch* ip = m_inputMap->patch(universe); OutputPatch* op = m_outputMap->patch(universe); OutputPatch* fp = m_outputMap->feedbackPatch(universe); Q_ASSERT(ip != NULL); item->setText(KColumnUniverse, QString::number(universe + 1)); item->setText(KColumnInput, QString("[%1] %2").arg(ip->pluginName()).arg(ip->inputName())); item->setText(KColumnOutput, QString("[%1] %2").arg(op->pluginName()).arg(op->outputName())); item->setText(KColumnFeedback, QString("[%1] %2").arg(fp->pluginName()).arg(fp->outputName())); item->setText(KColumnProfile, ip->profileName()); item->setText(KColumnInputNum, QString::number(ip->input() + 1)); item->setText(KColumnOutputNum, QString::number(op->output() + 1)); m_tree->resizeColumnToContents(KColumnUniverse); m_tree->resizeColumnToContents(KColumnInput); m_tree->resizeColumnToContents(KColumnOutput); m_tree->resizeColumnToContents(KColumnProfile); }
InputOutputPatchEditor::InputOutputPatchEditor(QWidget* parent, quint32 universe, InputOutputMap *ioMap, Doc *doc) : QWidget(parent) , m_ioMap(ioMap) , m_doc(doc) , m_universe(universe) , m_currentInputPluginName(KInputNone) , m_currentInput(QLCIOPlugin::invalidLine()) , m_currentOutputPluginName(KOutputNone) , m_currentOutput(QLCIOPlugin::invalidLine()) , m_currentProfileName(KInputNone) , m_currentFeedbackPluginName(KOutputNone) , m_currentFeedback(QLCIOPlugin::invalidLine()) { Q_ASSERT(universe < m_ioMap->universes()); Q_ASSERT(ioMap != NULL); setupUi(this); m_infoBrowser->setOpenExternalLinks(true); m_infoBrowser->setFixedHeight(250); InputPatch* inputPatch = m_ioMap->inputPatch(universe); OutputPatch* outputPatch = m_ioMap->outputPatch(universe); OutputPatch* feedbackPatch = m_ioMap->feedbackPatch(universe); /* Copy these so they can be applied if the user cancels */ if (inputPatch != NULL) { m_currentInputPluginName = inputPatch->pluginName(); m_currentInput = inputPatch->input(); m_currentProfileName = inputPatch->profileName(); } if (outputPatch != NULL) { m_currentOutputPluginName = outputPatch->pluginName(); m_currentOutput = outputPatch->output(); } if (feedbackPatch != NULL) { m_currentFeedbackPluginName = feedbackPatch->pluginName(); m_currentFeedback = feedbackPatch->output(); } m_mapTree->setSortingEnabled(true); m_mapTree->sortByColumn(KMapColumnPluginName, Qt::AscendingOrder); /* Setup UI controls */ setupMappingPage(); setupProfilePage(); fillAudioTree(); /* Listen to itemChanged() signals to catch check state changes */ connect(m_audioMapTree, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(slotAudioDeviceItemChanged(QTreeWidgetItem*, int))); /* Select the top-most "None" item */ m_mapTree->setCurrentItem(m_mapTree->topLevelItem(0)); /* Listen to plugin configuration changes */ connect(m_ioMap, SIGNAL(pluginConfigurationChanged(const QString&)), this, SLOT(slotPluginConfigurationChanged(const QString&))); /* Listen to plugin configuration changes */ connect(m_ioMap, SIGNAL(pluginConfigurationChanged(const QString&)), this, SLOT(slotPluginConfigurationChanged(const QString&))); }
mg_result WebAccess::websocketDataHandler(mg_connection *conn) { if (conn == NULL) return MG_TRUE; m_conn = conn; // store this to send VC loaded async event if (conn->content_len == 0) return MG_TRUE; QString qData = QString(conn->content); qData.truncate(conn->content_len); qDebug() << "[websocketDataHandler]" << qData; QStringList cmdList = qData.split("|"); if (cmdList.isEmpty()) return MG_TRUE; if(cmdList[0] == "QLC+CMD") { if (cmdList.count() < 2) return MG_FALSE; if(cmdList[1] == "opMode") emit toggleDocMode(); return MG_TRUE; } else if (cmdList[0] == "QLC+IO") { if (cmdList.count() < 3) return MG_FALSE; int universe = cmdList[2].toInt(); if (cmdList[1] == "INPUT") { m_doc->inputOutputMap()->setInputPatch(universe, cmdList[3], cmdList[4].toUInt()); m_doc->inputOutputMap()->saveDefaults(); } else if (cmdList[1] == "OUTPUT") { m_doc->inputOutputMap()->setOutputPatch(universe, cmdList[3], cmdList[4].toUInt(), false); m_doc->inputOutputMap()->saveDefaults(); } else if (cmdList[1] == "FB") { m_doc->inputOutputMap()->setOutputPatch(universe, cmdList[3], cmdList[4].toUInt(), true); m_doc->inputOutputMap()->saveDefaults(); } else if (cmdList[1] == "PROFILE") { InputPatch *inPatch = m_doc->inputOutputMap()->inputPatch(universe); if (inPatch != NULL) { m_doc->inputOutputMap()->setInputPatch(universe, inPatch->pluginName(), inPatch->input(), cmdList[3]); m_doc->inputOutputMap()->saveDefaults(); } } else if (cmdList[1] == "PASSTHROUGH") { quint32 uniIdx = cmdList[2].toUInt(); if (cmdList[3] == "true") m_doc->inputOutputMap()->setUniversePassthrough(uniIdx, true); else m_doc->inputOutputMap()->setUniversePassthrough(uniIdx, false); m_doc->inputOutputMap()->saveDefaults(); } else if (cmdList[1] == "AUDIOIN") { QSettings settings; if (cmdList[2] == "__qlcplusdefault__") settings.remove(SETTINGS_AUDIO_INPUT_DEVICE); else { settings.setValue(SETTINGS_AUDIO_INPUT_DEVICE, cmdList[2]); m_doc->destroyAudioCapture(); } } else if (cmdList[1] == "AUDIOOUT") { QSettings settings; if (cmdList[2] == "__qlcplusdefault__") settings.remove(SETTINGS_AUDIO_OUTPUT_DEVICE); else settings.setValue(SETTINGS_AUDIO_OUTPUT_DEVICE, cmdList[2]); } else qDebug() << "[webaccess] Command" << cmdList[1] << "not supported !"; return MG_TRUE; } #if defined(Q_WS_X11) || defined(Q_OS_LINUX) else if(cmdList[0] == "QLC+SYS") { if (cmdList.at(1) == "NETWORK") { if (m_netConfig->updateNetworkFile(cmdList) == true) { QString wsMessage = QString("ALERT|" + tr("Network configuration changed. Reboot to apply the changes.")); mg_websocket_write(m_conn, WEBSOCKET_OPCODE_TEXT, wsMessage.toUtf8().data(), wsMessage.length()); return MG_TRUE; } else qDebug() << "[webaccess] Error writing network configuration file !"; return MG_TRUE; } else if (cmdList.at(1) == "AUTOSTART") { if (cmdList.count() < 3) return MG_FALSE; QString asName = QString("%1/%2/%3").arg(getenv("HOME")).arg(USERQLCPLUSDIR).arg(AUTOSTART_PROJECT_NAME); if (cmdList.at(2) == "none") QFile::remove(asName); else emit storeAutostartProject(asName); QString wsMessage = QString("ALERT|" + tr("Autostart configuration changed")); mg_websocket_write(m_conn, WEBSOCKET_OPCODE_TEXT, wsMessage.toUtf8().data(), wsMessage.length()); return MG_TRUE; } else if (cmdList.at(1) == "REBOOT") { QProcess *rebootProcess = new QProcess(); rebootProcess->start("reboot", QStringList()); } else if (cmdList.at(1) == "HALT") { QProcess *haltProcess = new QProcess(); haltProcess->start("halt", QStringList()); } } #endif else if (cmdList[0] == "QLC+API") { if (cmdList.count() < 2) return MG_FALSE; QString apiCmd = cmdList[1]; // compose the basic API reply messages QString wsAPIMessage = QString("QLC+API|%1|").arg(apiCmd); if (apiCmd == "isProjectLoaded") { if (m_pendingProjectLoaded) { wsAPIMessage.append("true"); m_pendingProjectLoaded = false; } else wsAPIMessage.append("false"); } else if (apiCmd == "getFunctionsNumber") { wsAPIMessage.append(QString::number(m_doc->functions().count())); } else if (apiCmd == "getFunctionsList") { foreach(Function *f, m_doc->functions()) wsAPIMessage.append(QString("%1|%2|").arg(f->id()).arg(f->name())); // remove trailing separator wsAPIMessage.truncate(wsAPIMessage.length() - 1); } else if (apiCmd == "getFunctionType") { if (cmdList.count() < 3) return MG_FALSE; quint32 fID = cmdList[2].toUInt(); Function *f = m_doc->function(fID); if (f != NULL) wsAPIMessage.append(m_doc->function(fID)->typeString()); else wsAPIMessage.append(Function::typeToString(Function::Undefined)); } else if (apiCmd == "getFunctionStatus") { if (cmdList.count() < 3) return MG_FALSE; quint32 fID = cmdList[2].toUInt(); Function *f = m_doc->function(fID); if (f != NULL) { if (f->isRunning()) wsAPIMessage.append("Running"); else wsAPIMessage.append("Stopped"); } else wsAPIMessage.append(Function::typeToString(Function::Undefined)); } else if (apiCmd == "getWidgetsNumber") { VCFrame *mainFrame = m_vc->contents(); QList<VCWidget *> chList = mainFrame->findChildren<VCWidget*>(); wsAPIMessage.append(QString::number(chList.count())); } else if (apiCmd == "getWidgetsList") { VCFrame *mainFrame = m_vc->contents(); foreach(VCWidget *widget, mainFrame->findChildren<VCWidget*>()) wsAPIMessage.append(QString("%1|%2|").arg(widget->id()).arg(widget->caption())); // remove trailing separator wsAPIMessage.truncate(wsAPIMessage.length() - 1); } else if (apiCmd == "getWidgetType") { if (cmdList.count() < 3) return MG_FALSE; quint32 wID = cmdList[2].toUInt(); VCWidget *widget = m_vc->widget(wID); if (widget != NULL) wsAPIMessage.append(widget->typeToString(widget->type())); else wsAPIMessage.append(widget->typeToString(VCWidget::UnknownWidget)); } else if (apiCmd == "getWidgetStatus") { if (cmdList.count() < 3) return MG_FALSE; quint32 wID = cmdList[2].toUInt(); VCWidget *widget = m_vc->widget(wID); if (widget != NULL) { switch(widget->type()) { case VCWidget::ButtonWidget: { VCButton *button = qobject_cast<VCButton*>(widget); if (button->isOn()) wsAPIMessage.append("255"); else wsAPIMessage.append("0"); } break; case VCWidget::SliderWidget: { VCSlider *slider = qobject_cast<VCSlider*>(widget); wsAPIMessage.append(QString::number(slider->sliderValue())); } break; case VCWidget::CueListWidget: { VCCueList *cue = qobject_cast<VCCueList*>(widget); quint32 chaserID = cue->chaserID(); Function *f = m_doc->function(chaserID); if (f != NULL && f->isRunning()) wsAPIMessage.append(QString("PLAY|%2|").arg(cue->getCurrentIndex())); else wsAPIMessage.append("STOP"); } break; } } } else if (apiCmd == "getChannelsValues") { if (cmdList.count() < 4) return MG_FALSE; quint32 universe = cmdList[2].toUInt() - 1; int startAddr = cmdList[3].toInt() - 1; int count = 1; if (cmdList.count() == 5) count = cmdList[4].toInt(); wsAPIMessage.append(WebAccessSimpleDesk::getChannelsMessage(m_doc, m_sd, universe, startAddr, count)); } else if (apiCmd == "sdResetUniverse") { m_sd->resetUniverse(); wsAPIMessage = "QLC+API|getChannelsValues|"; wsAPIMessage.append(WebAccessSimpleDesk::getChannelsMessage( m_doc, m_sd, m_sd->getCurrentUniverseIndex(), 0, m_sd->getSlidersNumber())); } //qDebug() << "Simple desk channels:" << wsAPIMessage; mg_websocket_write(conn, WEBSOCKET_OPCODE_TEXT, wsAPIMessage.toUtf8().data(), wsAPIMessage.length()); return MG_TRUE; } else if(cmdList[0] == "CH") { if (cmdList.count() < 3) return MG_FALSE; uint absAddress = cmdList[1].toInt() - 1; int value = cmdList[2].toInt(); m_sd->setAbsoluteChannelValue(absAddress, uchar(value)); return MG_TRUE; } else if(cmdList[0] == "POLL") return MG_TRUE; if (qData.contains("|") == false) return MG_FALSE; quint32 widgetID = cmdList[0].toUInt(); VCWidget *widget = m_vc->widget(widgetID); uchar value = 0; if (cmdList.count() > 1) value = (uchar)cmdList[1].toInt(); if (widget != NULL) { switch(widget->type()) { case VCWidget::ButtonWidget: { VCButton *button = qobject_cast<VCButton*>(widget); if ((value == 0 && button->isOn()) || (value != 0 && button->isOn() == false)) button->pressFunction(); } break; case VCWidget::SliderWidget: { VCSlider *slider = qobject_cast<VCSlider*>(widget); slider->setSliderValue(value); } break; case VCWidget::AudioTriggersWidget: { VCAudioTriggers *triggers = qobject_cast<VCAudioTriggers*>(widget); triggers->slotEnableButtonToggled(value ? true : false); } break; case VCWidget::CueListWidget: { if (cmdList.count() < 2) return MG_FALSE; VCCueList *cue = qobject_cast<VCCueList*>(widget); if (cmdList[1] == "PLAY") cue->slotPlayback(); else if (cmdList[1] == "PREV") cue->slotPreviousCue(); else if (cmdList[1] == "NEXT") cue->slotNextCue(); else if (cmdList[1] == "STEP") cue->playCueAtIndex(cmdList[2].toInt()); } break; case VCWidget::FrameWidget: case VCWidget::SoloFrameWidget: { VCFrame *frame = qobject_cast<VCFrame*>(widget); frame->blockSignals(true); if (cmdList[1] == "NEXT_PG") frame->slotNextPage(); else if (cmdList[1] == "PREV_PG") frame->slotPreviousPage(); frame->blockSignals(false); } break; default: break; } } return MG_TRUE; }