From 135effa536144cf6c2a5a0f0e9be7200b2999e54 Mon Sep 17 00:00:00 2001 From: Neil Horne Date: Thu, 21 Nov 2019 18:31:22 +1100 Subject: [PATCH] Context menu enhancements (#7029) --- companion/src/modeledit/customfunctions.cpp | 146 ++++++++++++++------ companion/src/modeledit/customfunctions.h | 12 +- 2 files changed, 118 insertions(+), 40 deletions(-) diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index dfcc1809e..c30454bdc 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -74,7 +74,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, { Stopwatch s1("CustomFunctionsPanel - populate"); lock = true; - int num_fsw = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions); + fswCapability = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions); rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, model, model ? RawSwitch::SpecialFunctionsContext : RawSwitch::GlobalFunctionsContext, this); rawSrcAllItemModel = new RawSourceFilterItemModel(&generalSettings, model, this); @@ -83,7 +83,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, if (!firmware->getCapability(VoicesAsNumbers)) { tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength)); - for (int i=0; igetBoard())) { scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/FUNCTIONS", QStringList() << "*.lua", firmware->getCapability(VoicesMaxLength)); - for (int i=0; isetContextMenuPolicy(Qt::CustomContextMenu); @@ -244,7 +244,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, tableLayout->resizeColumnsToContents(); s1.report("resizeColumnsToContents"); tableLayout->setColumnWidth(3, 300); - tableLayout->pushRowsUp(num_fsw+1); + tableLayout->pushRowsUp(fswCapability+1); s1.report("end"); } @@ -579,7 +579,6 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) widgetsMask |= CUSTOM_FUNCTION_ENABLE; } } - } fswtchFunc[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SHOW_FUNC); @@ -603,8 +602,7 @@ void CustomFunctionsPanel::update() { updateDataModels(); lock = true; - int num_fsw = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions); - for (int i=0; imimeData(); - if (mimeData->hasFormat("application/x-companion-fsw")) { - QByteArray fswData = mimeData->data("application/x-companion-fsw"); + if (mimeData->hasFormat(MIMETYPE_FSW)) { + QByteArray fswData = mimeData->data(MIMETYPE_FSW); CustomFunctionData *fsw = &functions[selectedFunction]; memcpy(fsw, fswData.constData(), sizeof(CustomFunctionData)); - lock = true; - fswtchSwtch[selectedFunction]->setCurrentIndex(fswtchSwtch[selectedFunction]->findData(functions[selectedFunction].swtch.toValue())); - fswtchFunc[selectedFunction]->setCurrentIndex(fswtchFunc[selectedFunction]->findData(functions[selectedFunction].func)); - populateGVmodeCB(fswtchGVmode[selectedFunction], functions[selectedFunction].adjustMode); - populateFuncParamCB(fswtchParamT[selectedFunction], functions[selectedFunction].func, functions[selectedFunction].param, functions[selectedFunction].adjustMode); - refreshCustomFunction(selectedFunction); - lock = false; + resetCBsAndRefresh(selectedFunction); emit modified(); } } void CustomFunctionsPanel::fswDelete() { - functions[selectedFunction].clear(); - // TODO update switch and func - lock = true; - fswtchSwtch[selectedFunction]->setCurrentIndex(fswtchSwtch[selectedFunction]->findData(functions[selectedFunction].swtch.toValue())); - fswtchFunc[selectedFunction]->setCurrentIndex(fswtchFunc[selectedFunction]->findData(functions[selectedFunction].func)); - refreshCustomFunction(selectedFunction); - lock = false; + int maxidx = fswCapability - 1; + for (int i=selectedFunction; isetData("application/x-companion-fsw", fswData); + mimeData->setData(MIMETYPE_FSW, fswData); QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } void CustomFunctionsPanel::fswCut() { fswCopy(); - fswDelete(); + fswClear(); } void CustomFunctionsPanel::fsw_customContextMenuRequested(QPoint pos) { - QLabel *label = (QLabel *)sender(); - selectedFunction = label->property("index").toInt(); + QLabel *label = (QLabel *)sender(); + selectedFunction = label->property("index").toInt(); - QPoint globalPos = label->mapToGlobal(pos); + QPoint globalPos = label->mapToGlobal(pos); - const QClipboard *clipboard = QApplication::clipboard(); - const QMimeData *mimeData = clipboard->mimeData(); - bool hasData = mimeData->hasFormat("application/x-companion-fsw"); + const QClipboard *clipboard = QApplication::clipboard(); + const QMimeData *mimeData = clipboard->mimeData(); + bool hasData = mimeData->hasFormat(MIMETYPE_FSW); + bool moveUpAllowed = (selectedFunction > 0); + bool moveDownAllowed = (selectedFunction < (fswCapability - 1)); + bool insertAllowed = (selectedFunction < (fswCapability - 1)) && (functions[fswCapability - 1].isEmpty()); - QMenu contextMenu; - contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(fswCopy())); - contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(fswCut())); - contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(fswPaste()))->setEnabled(hasData); - contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(fswDelete())); + QMenu contextMenu; + contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"),this,SLOT(fswCopy())); + contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"),this,SLOT(fswCut())); + contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"),this,SLOT(fswPaste()))->setEnabled(hasData); + contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"),this,SLOT(fswClear())); + contextMenu.addSeparator(); + contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"),this,SLOT(fswInsert()))->setEnabled(insertAllowed); + contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"),this,SLOT(fswDelete())); + contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(fswMoveUp()))->setEnabled(moveUpAllowed); + contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(fswMoveDown()))->setEnabled(moveDownAllowed); + contextMenu.addSeparator(); + contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"),this,SLOT(fswClearAll())); - contextMenu.exec(globalPos); + contextMenu.exec(globalPos); } void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value) @@ -755,3 +761,65 @@ void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsi b->hide(); } } + +void CustomFunctionsPanel::fswMoveUp() +{ + swapFuncData(selectedFunction, selectedFunction - 1); +} + +void CustomFunctionsPanel::fswMoveDown() +{ + swapFuncData(selectedFunction, selectedFunction + 1); +} + +void CustomFunctionsPanel::fswClear() +{ + functions[selectedFunction].clear(); + resetCBsAndRefresh(selectedFunction); + emit modified(); +} + +void CustomFunctionsPanel::fswClearAll() +{ + for (int i=0; iselectedFunction; i--) { + if (!functions[i].isEmpty() || !functions[i-1].isEmpty()) { + memcpy(&functions[i], &functions[i-1], sizeof(CustomFunctionData)); + resetCBsAndRefresh(i); + } + } + fswClear(); +} + +void CustomFunctionsPanel::swapFuncData(int idx1, int idx2) +{ + if ((idx1 != idx2) && (!functions[idx1].isEmpty() || !functions[idx2].isEmpty())) { + CustomFunctionData fswtmp = functions[idx2]; + CustomFunctionData *fsw1 = &functions[idx1]; + CustomFunctionData *fsw2 = &functions[idx2]; + memcpy(fsw2, fsw1, sizeof(CustomFunctionData)); + memcpy(fsw1, &fswtmp, sizeof(CustomFunctionData)); + resetCBsAndRefresh(idx1); + resetCBsAndRefresh(idx2); + emit modified(); + } +} + +void CustomFunctionsPanel::resetCBsAndRefresh(int idx) +{ + lock = true; + fswtchSwtch[idx]->setCurrentIndex(fswtchSwtch[idx]->findData(functions[idx].swtch.toValue())); + fswtchFunc[idx]->setCurrentIndex(fswtchFunc[idx]->findData(functions[idx].func)); + fswtchGVmode[idx]->setCurrentIndex(functions[idx].adjustMode); + populateFuncParamCB(fswtchParamT[idx], functions[idx].func, functions[idx].param, functions[idx].adjustMode); + refreshCustomFunction(idx); + lock = false; +} diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h index 26cb4b273..fd257ce98 100644 --- a/companion/src/modeledit/customfunctions.h +++ b/companion/src/modeledit/customfunctions.h @@ -30,6 +30,8 @@ class RawSourceFilterItemModel; class RawSwitchFilterItemModel; class TimerEdit; +constexpr char MIMETYPE_FSW[] = "application/x-companion-fsw"; + class RepeatComboBox: public QComboBox { Q_OBJECT @@ -53,7 +55,7 @@ class CustomFunctionsPanel : public GenericPanel Q_OBJECT public: - CustomFunctionsPanel(QWidget *parent, ModelData * mode, GeneralSettings & generalSettings, Firmware * firmware); + CustomFunctionsPanel(QWidget *parent, ModelData * model, GeneralSettings & generalSettings, Firmware * firmware); ~CustomFunctionsPanel(); virtual void update(); @@ -77,11 +79,18 @@ class CustomFunctionsPanel : public GenericPanel void fswCopy(); void fswPaste(); void fswCut(); + void fswMoveUp(); + void fswMoveDown(); + void fswInsert(); + void fswClear(); + void fswClearAll(); private: void populateFuncCB(QComboBox *b, unsigned int value); void populateGVmodeCB(QComboBox *b, unsigned int value); void populateFuncParamCB(QComboBox *b, uint function, unsigned int value, unsigned int adjustmode=0); + void swapFuncData(int idx1, int idx2); + void resetCBsAndRefresh(int idx); RawSwitchFilterItemModel * rawSwitchItemModel; RawSourceFilterItemModel * rawSrcAllItemModel; RawSourceFilterItemModel * rawSrcInputsItemModel; @@ -105,6 +114,7 @@ class CustomFunctionsPanel : public GenericPanel QMediaPlayer * mediaPlayer; int selectedFunction; + int fswCapability; };