#include "inputs.h" #include #include "expodialog.h" #include "helpers.h" InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, FirmwareInterface * firmware): ModelPanel(parent, model, generalSettings, firmware), expoInserted(false) { QGridLayout * exposLayout = new QGridLayout(this); ExposlistWidget = new MixersList(this, true); QPushButton * qbUp = new QPushButton(this); QPushButton * qbDown = new QPushButton(this); QPushButton * qbClear = new QPushButton(this); qbUp->setText(tr("Move Up")); qbUp->setIcon(CompanionIcon("moveup.png")); qbUp->setShortcut(QKeySequence(tr("Ctrl+Up"))); qbDown->setText(tr("Move Down")); qbDown->setIcon(CompanionIcon("movedown.png")); qbDown->setShortcut(QKeySequence(tr("Ctrl+Down"))); qbClear->setText(tr("Clear All Inputs")); qbClear->setIcon(CompanionIcon("clear.png")); exposLayout->addWidget(ExposlistWidget,1,1,1,3); exposLayout->addWidget(qbUp,2,1); exposLayout->addWidget(qbClear,2,2); exposLayout->addWidget(qbDown,2,3); connect(ExposlistWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(expolistWidget_customContextMenuRequested(QPoint))); connect(ExposlistWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(expolistWidget_doubleClicked(QModelIndex))); connect(ExposlistWidget, SIGNAL(mimeDropped(int,const QMimeData*,Qt::DropAction)), this, SLOT(mimeExpoDropped(int, const QMimeData*, Qt::DropAction))); connect(qbUp, SIGNAL(pressed()),SLOT(moveExpoUp())); connect(qbDown, SIGNAL(pressed()),SLOT(moveExpoDown())); connect(qbClear, SIGNAL(pressed()),SLOT(clearExpos())); connect(ExposlistWidget, SIGNAL(keyWasPressed(QKeyEvent*)), this, SLOT(expolistWidget_KeyPress(QKeyEvent*))); } InputsPanel::~InputsPanel() { } void InputsPanel::update() { lock = true; int inputsCount = firmware->getCapability(VirtualInputs); if (inputsCount == 0) inputsCount = NUM_STICKS; // curDest -> destination channel // i -> mixer number QByteArray qba; ExposlistWidget->clear(); firstLine = true; int curDest = -1; for (int i=0; imode==0) break; QString str; while (curDest<(int)md->chn-1) { curDest++; AddInputLine(-curDest-1); } if (AddInputLine(i)) { curDest++; } } while (curDest Input05) if dest >=0 then create used input based on model input data from slot dest (dest=4 -> model expoData[4]) @retval true created input number is different from the previous list item false created input number is the same as previous list item */ bool InputsPanel::AddInputLine(int dest) { bool new_ch; QString str = getInputText(dest, &new_ch); QListWidgetItem *itm = new QListWidgetItem(str); QByteArray qba(1, (quint8)dest); if (dest >= 0) { //add input data ExpoData *md = &model.expoData[dest]; qba.append((const char*)md, sizeof(ExpoData)); } itm->setData(Qt::UserRole, qba); #if MIX_ROW_HEIGHT_INCREASE > 0 if (new_ch && !firstLine) { //increase size of this row itm->setData(GroupHeaderRole, 1); } #endif ExposlistWidget->addItem(itm); firstLine = false; //qDebug() << "InputsPanel::AddInputLine(): dest" << dest << "text" << str; return new_ch; } /** @brief Returns HTML formated input representation @param[in] dest defines which input line to create. If dest < 0 then create empty input slot for input -dest ( dest=-6 -> Input05) if dest >=0 then create used input based on model input data from slot dest (dest=4 -> model expoData[4]) @retval string input line in HTML */ QString InputsPanel::getInputText(int dest, bool * new_ch) { QString str; if (new_ch) *new_ch = 0; if (dest < 0) { str = getInputStr(model, -dest-1); if (new_ch) *new_ch = 1; } else { ExpoData *md = &model.expoData[dest]; if ((dest == 0) || (model.expoData[dest-1].chn != md->chn)) { if (new_ch) *new_ch = 1; if (firmware->getCapability(VirtualInputs)) str = QString("%1").arg(getInputStr(model, md->chn), -10, ' '); else str = getInputStr(model, md->chn); } else { if (firmware->getCapability(VirtualInputs)) str = " "; else str = " "; } if (firmware->getCapability(VirtualInputs)) { str += " " + tr("Source(%1)").arg(md->srcRaw.toString()); if (md->carryTrim>0) { str += " " + tr("No Trim"); } else if (md->carryTrim<0) { str += " " + RawSource(SOURCE_TYPE_TRIM, (-(md->carryTrim)-1)).toString(); } } switch (md->mode) { case (1): str += " <-"; break; case (2): str += " ->"; break; default: str += " "; break; } str += " " + tr("Weight(%1)").arg(getGVarString(md->weight)); if (md->curve.value) str += " " + md->curve.toString(); QString phasesStr = getPhasesStr(md->phases, model); if (!phasesStr.isEmpty()) str += " " + phasesStr; if (md->swtch.type != SWITCH_TYPE_NONE) str += " " + tr("Switch(%1)").arg(md->swtch.toString()); if (firmware->getCapability(HasExpoNames)) { QString expoName = md->name; if (!expoName.isEmpty()) str += QString(" [%1]").arg(expoName); } } return Qt::escape(str).replace(" ", " "); } bool InputsPanel::gm_insertExpo(int idx) { if (idx<0 || idx>=C9X_MAX_EXPOS || model.expoData[C9X_MAX_EXPOS-1].mode > 0) { QMessageBox::information(this, "Companion", tr("Not enough available inputs!")); return false; } int chn = model.expoData[idx].chn; ExpoData * newExpo = model.insertInput(idx); newExpo->chn = chn; newExpo->weight = 100; newExpo->mode = INPUT_MODE_BOTH; return true; } void InputsPanel::gm_deleteExpo(int index) { model.removeInput(index); } void InputsPanel::gm_openExpo(int index) { if(index<0 || index>=C9X_MAX_EXPOS) return; ExpoData mixd(model.expoData[index]); char inputName[4+1]; emit modified(); update(); if (firmware->getCapability(VirtualInputs)) strcpy(inputName, model.inputNames[mixd.chn]); ExpoDialog *g = new ExpoDialog(this, model, &mixd, generalSettings, firmware, inputName); if (g->exec()) { model.expoData[index] = mixd; if (firmware->getCapability(VirtualInputs)) strcpy(model.inputNames[mixd.chn], inputName); emit modified(); update(); } else { if (expoInserted) { gm_deleteExpo(index); } expoInserted=false; emit modified(); update(); } } int InputsPanel::getExpoIndex(unsigned int dch) { unsigned int i = 0; while (model.expoData[i].chn<=dch && model.expoData[i].mode && i InputsPanel::createExpoListFromSelected() { QList list; foreach(QListWidgetItem *item, ExposlistWidget->selectedItems()) { int idx= item->data(Qt::UserRole).toByteArray().at(0); if(idx>=0 && idx list) { for(int i=0; icount(); i++) { int t = ExposlistWidget->item(i)->data(Qt::UserRole).toByteArray().at(0); if(list.contains(t)) ExposlistWidget->item(i)->setSelected(true); } } void InputsPanel::exposDelete(bool ask) { QMessageBox::StandardButton ret = QMessageBox::No; if(ask) ret = QMessageBox::warning(this, "companion", tr("Delete Selected Inputs?"), QMessageBox::Yes | QMessageBox::No); if ((ret == QMessageBox::Yes) || (!ask)) { exposDeleteList(createExpoListFromSelected()); emit modified(); update(); } } void InputsPanel::exposCut() { exposCopy(); exposDelete(false); } void InputsPanel::exposCopy() { QList list = createExpoListFromSelected(); QByteArray mxData; foreach(int idx, list) { mxData.append((char*)&model.expoData[idx],sizeof(ExpoData)); } QMimeData *mimeData = new QMimeData; mimeData->setData("application/x-companion-expo", mxData); QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); } void InputsPanel::mimeExpoDropped(int index, const QMimeData *data, Qt::DropAction /*action*/) { int idx = ExposlistWidget->item(index > 0 ? index-1 : 0)->data(Qt::UserRole).toByteArray().at(0); pasteExpoMimeData(data, idx); } #include #include void InputsPanel::pasteExpoMimeData(const QMimeData * mimeData, int destIdx) { if (mimeData->hasFormat("application/x-companion-expo")) { int idx; // mixer index int dch; if (destIdx < 0) { dch = -destIdx - 1; idx = getExpoIndex(dch) - 1; //get expo index to insert } else { idx = destIdx; dch = model.expoData[idx].chn; } QByteArray mxData = mimeData->data("application/x-companion-expo"); int i = 0; while (i < mxData.size()) { idx++; if (!gm_insertExpo(idx)) break; ExpoData *md = &model.expoData[idx]; memcpy(md, mxData.mid(i, sizeof(ExpoData)).constData(), sizeof(ExpoData)); md->chn = dch; i += sizeof(ExpoData); } emit modified(); update(); } } void InputsPanel::exposPaste() { const QClipboard *clipboard = QApplication::clipboard(); const QMimeData *mimeData = clipboard->mimeData(); QListWidgetItem *item = ExposlistWidget->currentItem(); if (item) pasteExpoMimeData(mimeData, item->data(Qt::UserRole).toByteArray().at(0)); } void InputsPanel::exposDuplicate() { exposCopy(); exposPaste(); } void InputsPanel::expoOpen(QListWidgetItem *item) { if (!item) item = ExposlistWidget->currentItem(); int idx = item->data(Qt::UserRole).toByteArray().at(0); if (idx<0) { int ch = -idx-1; idx = getExpoIndex(ch); // get expo index to insert if (!gm_insertExpo(idx)) return; model.expoData[idx].chn = ch; expoInserted=true; } else { expoInserted=false; } gm_openExpo(idx); } void InputsPanel::expoAdd() { int index = ExposlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0); if(index<0) { // if empty then return relevant index expoOpen(); } else { index++; if (!gm_insertExpo(index)) return; model.expoData[index].chn = model.expoData[index-1].chn; } gm_openExpo(index); } void InputsPanel::expolistWidget_customContextMenuRequested(QPoint pos) { QPoint globalPos = ExposlistWidget->mapToGlobal(pos); const QClipboard *clipboard = QApplication::clipboard(); const QMimeData *mimeData = clipboard->mimeData(); bool hasData = mimeData->hasFormat("application/x-companion-expo"); QMenu contextMenu; contextMenu.addAction(CompanionIcon("add.png"), tr("&Add"),this,SLOT(expoAdd()),tr("Ctrl+A")); contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"),this,SLOT(expoOpen()),tr("Enter")); contextMenu.addSeparator(); contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(exposDelete()),tr("Delete")); contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(exposCopy()),tr("Ctrl+C")); contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(exposCut()),tr("Ctrl+X")); contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(exposPaste()),tr("Ctrl+V"))->setEnabled(hasData); contextMenu.addAction(CompanionIcon("duplicate.png"), tr("Du&plicate"),this,SLOT(exposDuplicate()),tr("Ctrl+U")); contextMenu.addSeparator(); contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(moveExpoUp()),tr("Ctrl+Up")); contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(moveExpoDown()),tr("Ctrl+Down")); contextMenu.exec(globalPos); } void InputsPanel::expolistWidget_KeyPress(QKeyEvent *event) { if(event->matches(QKeySequence::SelectAll)) expoAdd(); //Ctrl A if(event->matches(QKeySequence::Delete)) exposDelete(); if(event->matches(QKeySequence::Copy)) exposCopy(); if(event->matches(QKeySequence::Cut)) exposCut(); if(event->matches(QKeySequence::Paste)) exposPaste(); if(event->matches(QKeySequence::Underline)) exposDuplicate(); if(event->key()==Qt::Key_Return || event->key()==Qt::Key_Enter) expoOpen(); if(event->matches(QKeySequence::MoveToNextLine)) ExposlistWidget->setCurrentRow(ExposlistWidget->currentRow()+1); if(event->matches(QKeySequence::MoveToPreviousLine)) ExposlistWidget->setCurrentRow(ExposlistWidget->currentRow()-1); } int InputsPanel::gm_moveExpo(int idx, bool dir) //true=inc=down false=dec=up { if(idx>C9X_MAX_EXPOS || (idx==C9X_MAX_EXPOS && dir)) return idx; int tdx = dir ? idx+1 : idx-1; ExpoData temp; temp.clear(); ExpoData &src=model.expoData[idx]; ExpoData &tgt=model.expoData[tdx]; if (!dir && tdx<0 && src.chn>0) { src.chn--; return idx; } else if (!dir && tdx<0) { return idx; } if(memcmp(&src,&temp,sizeof(ExpoData))==0) return idx; bool tgtempty=(memcmp(&tgt,&temp,sizeof(ExpoData))==0 ? 1:0); if(tgt.chn!=src.chn || tgtempty) { if ((dir) && (src.chn<(NUM_STICKS-1))) src.chn++; if ((!dir) && (src.chn>0)) src.chn--; return idx; } //flip between idx and tgt memcpy(&temp,&src,sizeof(ExpoData)); memcpy(&src,&tgt,sizeof(ExpoData)); memcpy(&tgt,&temp,sizeof(ExpoData)); return tdx; } void InputsPanel::moveExpoUp() { QList list = createExpoListFromSelected(); QList highlightList; foreach(int idx, list) { highlightList << gm_moveExpo(idx, false); } emit modified(); update(); setSelectedByExpoList(highlightList); } void InputsPanel::moveExpoDown() { QList list = createExpoListFromSelected(); QList highlightList; foreach(int idx, list) { highlightList << gm_moveExpo(idx, true); } emit modified(); update(); setSelectedByExpoList(highlightList); } void InputsPanel::expolistWidget_doubleClicked(QModelIndex index) { expoOpen(ExposlistWidget->item(index.row())); } void InputsPanel::exposDeleteList(QList list) { qSort(list.begin(), list.end()); int iDec = 0; foreach(int idx, list) { gm_deleteExpo(idx-iDec); iDec++; } } void InputsPanel::clearExpos() { if (QMessageBox::question(this, tr("Clear Inputs?"), tr("Really clear all the inputs?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { model.clearInputs(); emit modified(); update(); } }