void VirtualConsole::slotFont() { bool ok = false; QFont font; Q_ASSERT(contents() != NULL); if (m_selectedWidgets.isEmpty() == true) font = contents()->font(); else font = m_selectedWidgets.last()->font(); /* This crashes with Qt 4.6.x on OSX. Upgrade to 4.7.x. */ font = QFontDialog::getFont(&ok, font); if (ok == true) { if (m_selectedWidgets.isEmpty() == true) { contents()->setFont(font); } else { VCWidget* widget; foreach(widget, m_selectedWidgets) widget->setFont(font); } } }
void VirtualConsole::slotBackgroundColor() { QColor color; Q_ASSERT(contents() != NULL); if (m_selectedWidgets.isEmpty() == true) color = contents()->backgroundColor(); else color = m_selectedWidgets.last()->backgroundColor(); color = QColorDialog::getColor(color); if (color.isValid() == true) { if (m_selectedWidgets.isEmpty() == true) { contents()->setBackgroundColor(color); } else { VCWidget* widget; foreach(widget, m_selectedWidgets) widget->setBackgroundColor(color); } } }
void VirtualConsole::slotBackgroundImage() { QString path; Q_ASSERT(contents() != NULL); if (m_selectedWidgets.isEmpty() == true) path = contents()->backgroundImage(); else path = m_selectedWidgets.last()->backgroundImage(); path = QFileDialog::getOpenFileName(this, tr("Select background image"), path, "Images (*.png *.xpm *.jpg *.gif)"); if (path.isEmpty() == false) { if (m_selectedWidgets.isEmpty() == true) { contents()->setBackgroundImage(path); } else { VCWidget* widget; foreach(widget, m_selectedWidgets) widget->setBackgroundImage(path); } } }
void VirtualConsole::slotEditDelete() { QString msg(tr("Do you wish to delete the selected widgets?")); QString title(tr("Delete widgets")); int result = QMessageBox::question(this, title, msg, QMessageBox::Yes, QMessageBox::No); if (result == QMessageBox::Yes) { while (m_selectedWidgets.isEmpty() == false) { /* Consume the selected list until it is empty and delete each widget. */ VCWidget* widget = m_selectedWidgets.takeFirst(); widget->deleteLater(); /* Remove the widget from clipboard as well so that deleted widgets won't be pasted anymore anywhere */ m_clipboard.removeAll(widget); m_editPasteAction->setEnabled(false); } updateActions(); } }
void VirtualConsole::updateCustomMenu() { /* Get rid of the custom menu, but delete it later because this might be called from the very menu that is being deleted. */ if (m_customMenu != NULL) { delete m_customMenu; m_customMenu = NULL; } if (m_selectedWidgets.size() > 0) { /* Change the custom menu to the last selected widget's menu */ VCWidget* latestWidget = m_selectedWidgets.last(); m_customMenu = latestWidget->customMenu(m_editMenu); if (m_customMenu != NULL) m_editMenu->addMenu(m_customMenu); } else { /* Change the custom menu to the bottom frame's menu */ Q_ASSERT(contents() != NULL); m_customMenu = contents()->customMenu(m_editMenu); if (m_customMenu != NULL) m_editMenu->addMenu(m_customMenu); } }
void VirtualConsole::slotStackingLower() { Q_ASSERT(contents() != NULL); if (m_selectedWidgets.isEmpty() == true) return; VCWidget* widget; foreach(widget, m_selectedWidgets) widget->lower(); }
void VirtualConsole::slotFrameNone() { Q_ASSERT(contents() != NULL); if (m_selectedWidgets.isEmpty() == true) return; VCWidget* widget; foreach(widget, m_selectedWidgets) widget->setFrameStyle(KVCFrameStyleNone); }
void VirtualConsole::slotForegroundNone() { Q_ASSERT(contents() != NULL); if (m_selectedWidgets.isEmpty() == true) return; VCWidget* widget; foreach(widget, m_selectedWidgets) widget->resetForegroundColor(); }
void WebAccess::slotFramePageChanged(int pageNum) { if (m_conn == NULL) return; VCWidget *frame = (VCWidget *)sender(); QString wsMessage = QString("%1|FRAME|%2").arg(frame->id()).arg(pageNum); QByteArray ba = wsMessage.toUtf8(); mg_websocket_write(m_conn, WEBSOCKET_OPCODE_TEXT, ba.data(), ba.length()); }
void VirtualConsole::slotEditProperties() { VCWidget* widget; Q_ASSERT(contents() != NULL); if (m_selectedWidgets.isEmpty() == true) widget = contents(); else widget = m_selectedWidgets.last(); if (widget != NULL) widget->editProperties(); }
void VCWidgetSelection::updateWidgetsTree() { VCFrame* contents = VirtualConsole::instance()->contents(); m_widgetsList = getChildren((VCWidget *)contents); foreach (QObject *object, m_widgetsList) { VCWidget *widget = (VCWidget *)object; QTreeWidgetItem *item = new QTreeWidgetItem(m_tree); item->setText(KColumnName, widget->caption()); item->setIcon(KColumnName, VCWidget::typeToIcon(widget->type())); item->setText(KColumnType, VCWidget::typeToString(widget->type())); }
QList<VCWidget *> VCWidgetSelection::getChildren(VCWidget *obj) { QList<VCWidget *> list; if (obj == NULL) return list; QListIterator <VCWidget*> it(obj->findChildren<VCWidget*>()); while (it.hasNext() == true) { VCWidget* child = it.next(); qDebug() << Q_FUNC_INFO << "append: " << child->caption(); if (m_filters.isEmpty() || m_filters.contains(child->type())) list.append(child); } return list; }
void VirtualConsole::slotResetFont() { Q_ASSERT(contents() != NULL); if (m_selectedWidgets.isEmpty() == true) { contents()->resetFont(); } else { VCWidget* widget; foreach(widget, m_selectedWidgets) widget->resetFont(); } }
void VirtualConsole::slotEditRename() { if (m_selectedWidgets.isEmpty() == true) return; bool ok = false; QString text(m_selectedWidgets.last()->caption()); text = QInputDialog::getText(this, tr("Rename widgets"), tr("Caption:"), QLineEdit::Normal, text, &ok); if (ok == true) { VCWidget* widget; foreach(widget, m_selectedWidgets) widget->setCaption(text); } }
void VirtualConsole::slotForegroundColor() { Q_ASSERT(contents() != NULL); if (m_selectedWidgets.isEmpty() == true) return; QColor color(m_selectedWidgets.last()->foregroundColor()); color = QColorDialog::getColor(color); if (color.isValid() == true) { VCWidget* widget; foreach(widget, m_selectedWidgets) widget->setForegroundColor(color); } }
void VCFrameProperties::accept() { bool hasHeader = m_frame->isHeaderVisible(); m_frame->setCaption(m_frameName->text()); m_frame->setAllowChildren(m_allowChildrenCheck->isChecked()); m_frame->setAllowResize(m_allowResizeCheck->isChecked()); /* If the frame is coming from a headerless state, * all the children widgets must be moved down */ if (m_showHeaderCheck->isChecked() && hasHeader == false) { QListIterator <VCWidget*> it(m_frame->findChildren<VCWidget*>()); // resize the frame too if it contains children if (it.hasNext()) m_frame->resize(QSize(m_frame->width(), m_frame->height() + 40)); while (it.hasNext() == true) { VCWidget* child = it.next(); // move only first level children if (child->parentWidget() == m_frame) child->move(QPoint(child->x(), child->y() + 40)); } } m_frame->setHeaderVisible(m_showHeaderCheck->isChecked()); m_frame->setEnableButtonVisible(m_showEnableButtonCheck->isChecked()); m_frame->setMultipageMode(m_enablePaging->isChecked()); m_frame->setTotalPagesNumber(m_totalPagesSpin->value()); m_frame->setPagesLoop(m_pagesLoopCheck->isChecked()); /* Key sequences */ m_frame->setEnableKeySequence(m_inputEnableWidget->keySequence()); m_frame->setNextPageKeySequence(m_inputNextPageWidget->keySequence()); m_frame->setPreviousPageKeySequence(m_inputPrevPageWidget->keySequence()); /* Input sources */ m_frame->setInputSource(m_inputEnableWidget->inputSource(), VCFrame::enableInputSourceId); m_frame->setInputSource(m_inputNextPageWidget->inputSource(), VCFrame::nextPageInputSourceId); m_frame->setInputSource(m_inputPrevPageWidget->inputSource(), VCFrame::previousPageInputSourceId); QDialog::accept(); }
VCWidget* VirtualConsole::closestParent() const { /* If nothing is selected, return the bottom-most contents frame */ if (m_selectedWidgets.isEmpty() == true) return contents(); /* Find the next VCWidget in the hierarchy that accepts children */ VCWidget* widget = m_selectedWidgets.last(); while (widget != NULL) { if (widget->allowChildren() == true) return widget; else widget = qobject_cast<VCWidget*> (widget->parentWidget()); } return NULL; }
bool VCFrame::saveXML(QDomDocument* doc, QDomElement* vc_root) { QDomElement root; QDomElement tag; QDomText text; QString str; Q_ASSERT(doc != NULL); Q_ASSERT(vc_root != NULL); /* VC Frame entry */ root = doc->createElement(xmlTagName()); vc_root->appendChild(root); /* Caption */ root.setAttribute(KXMLQLCVCCaption, caption()); /* Save appearance */ saveXMLAppearance(doc, &root); /* Save widget proportions only for child frames */ if (isBottomFrame() == false) saveXMLWindowState(doc, &root); /* Save children */ QListIterator <VCWidget*> it(findChildren<VCWidget*>()); while (it.hasNext() == true) { VCWidget* widget = it.next(); /* findChildren() is recursive, so the list contains all possible child widgets below this frame. Each frame must save only its direct children to preserve hierarchy, so save only such widgets that have this widget as their direct parent. */ if (widget->parentWidget() == this) widget->saveXML(doc, &root); } return true; }
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; }
void VirtualConsole::slotEditPaste() { if (m_clipboard.size() == 0) { /* Invalidate the edit action if there's nothing to paste */ m_editAction = EditNone; m_editPasteAction->setEnabled(false); return; } VCWidget* parent; VCWidget* widget; QRect bounds; Q_ASSERT(contents() != NULL); /* Select the parent that gets the cut clipboard contents */ parent = closestParent(); /* Get the bounding rect for all selected widgets */ QListIterator <VCWidget*> it(m_clipboard); while (it.hasNext() == true) { widget = it.next(); Q_ASSERT(widget != NULL); bounds = bounds.united(widget->geometry()); } /* Get the upcoming parent's last mouse click point */ QPoint cp(parent->lastClickPoint()); if (m_editAction == EditCut) { it.toFront(); while (it.hasNext() == true) { widget = it.next(); Q_ASSERT(widget != NULL); if (widget == parent) continue; /* Get widget's relative pos to the bounding rect */ QPoint p(widget->x() - bounds.x() + cp.x(), widget->y() - bounds.y() + cp.y()); /* Reparent and move to the correct place */ widget->setParent(parent); widget->move(p); widget->show(); } /* Clear clipboard after pasting stuff that was CUT */ m_clipboard.clear(); m_editPasteAction->setEnabled(false); } else if (m_editAction == EditCopy) { it.toFront(); while (it.hasNext() == true) { widget = it.next(); Q_ASSERT(widget != NULL); if (widget == parent) continue; /* Get widget's relative pos to the bounding rect */ QPoint p(widget->x() - bounds.x() + cp.x(), widget->y() - bounds.y() + cp.y()); /* Create a copy and move to correct place */ VCWidget* copy = widget->createCopy(parent); Q_ASSERT(copy != NULL); copy->move(p); copy->show(); } } updateActions(); }