diff --git a/companion/src/firmwares/io_data.cpp b/companion/src/firmwares/io_data.cpp index f7df7ddf6..b0201d3d5 100644 --- a/companion/src/firmwares/io_data.cpp +++ b/companion/src/firmwares/io_data.cpp @@ -85,6 +85,11 @@ void LimitData::clear() max = +1000; } +bool LimitData::isEmpty() const +{ + return (min == -1000 && max == 1000 && !revert && !offset && !ppmCenter && !symetrical && name[0] == '\0'); +} + /* * CurveData diff --git a/companion/src/firmwares/io_data.h b/companion/src/firmwares/io_data.h index b501d4944..7f22b045a 100644 --- a/companion/src/firmwares/io_data.h +++ b/companion/src/firmwares/io_data.h @@ -111,6 +111,7 @@ class LimitData { QString revertToString() const; QString nameToString(int index) const; void clear(); + bool isEmpty() const; }; class CurvePoint { diff --git a/companion/src/modeledit/channels.cpp b/companion/src/modeledit/channels.cpp index 4fbe64a9a..593121d83 100644 --- a/companion/src/modeledit/channels.cpp +++ b/companion/src/modeledit/channels.cpp @@ -101,6 +101,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera { Stopwatch s1("Channels"); + chnCapability = firmware->getCapability(Outputs); int channelNameMaxLen = firmware->getCapability(ChannelsName); QStringList headerLabels; @@ -115,11 +116,11 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera headerLabels << tr("PPM Center"); if (firmware->getCapability(SYMLimits)) headerLabels << tr("Linear Subtrim"); - TableLayout *tableLayout = new TableLayout(this, firmware->getCapability(LogicalSwitches), headerLabels); + TableLayout *tableLayout = new TableLayout(this, chnCapability, headerLabels); s1.report("header"); - for (int i=0; igetCapability(Outputs); i++) { + for (int i=0; iresizeColumnsToContents(); - tableLayout->pushRowsUp(firmware->getCapability(Outputs)+1); + tableLayout->pushRowsUp(chnCapability+1); s1.report("end"); } @@ -279,7 +280,7 @@ void Channels::ppmcenterEdited() void Channels::update() { - for (int i=0; igetCapability(Outputs); i++) { + for (int i=0; imimeData(); - if (mimeData->hasFormat("application/x-companion-chn")) { - QByteArray chnData = mimeData->data("application/x-companion-chn"); + if (mimeData->hasFormat(MIMETYPE_CHN)) { + QByteArray chnData = mimeData->data(MIMETYPE_CHN); LimitData *chn = &model->limitData[selectedChannel]; memcpy(chn, chnData.constData(), sizeof(LimitData)); updateLine(selectedChannel); @@ -326,8 +327,17 @@ void Channels::chnPaste() void Channels::chnDelete() { - model->limitData[selectedChannel].clear(); - updateLine(selectedChannel); + int maxidx = chnCapability - 1; + for (int i=selectedChannel; ilimitData[i].isEmpty() || !model->limitData[i+1].isEmpty()) { + LimitData *chn1 = &model->limitData[i]; + LimitData *chn2 = &model->limitData[i+1]; + memcpy(chn1, chn2, sizeof(LimitData)); + updateLine(i); + } + } + model->limitData[maxidx].clear(); + updateLine(maxidx); emit modified(); } @@ -336,32 +346,93 @@ void Channels::chnCopy() QByteArray chnData; chnData.append((char*)&model->limitData[selectedChannel],sizeof(LimitData)); QMimeData *mimeData = new QMimeData; - mimeData->setData("application/x-companion-chn", chnData); + mimeData->setData(MIMETYPE_CHN, chnData); QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); } void Channels::chnCut() { chnCopy(); - chnDelete(); + chnClear(); } void Channels::chn_customContextMenuRequested(QPoint pos) { - QLabel *label = (QLabel *)sender(); - selectedChannel = label->property("index").toInt(); + QLabel *label = (QLabel *)sender(); + selectedChannel = 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-chn"); + const QClipboard *clipboard = QApplication::clipboard(); + const QMimeData *mimeData = clipboard->mimeData(); + bool hasData = mimeData->hasFormat(MIMETYPE_CHN); + bool moveUpAllowed = (selectedChannel > 0); + bool moveDownAllowed = (selectedChannel < (chnCapability - 1)); + bool insertAllowed = (selectedChannel < (chnCapability - 1)) && (model->limitData[chnCapability - 1].isEmpty()); - QMenu contextMenu; - contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(chnCopy())); - contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(chnCut())); - contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(chnPaste()))->setEnabled(hasData); - contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(chnDelete())); + QMenu contextMenu; + contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"),this,SLOT(chnCopy())); + contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"),this,SLOT(chnCut())); + contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"),this,SLOT(chnPaste()))->setEnabled(hasData); + contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"),this,SLOT(chnClear())); + contextMenu.addSeparator(); + contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"),this,SLOT(chnInsert()))->setEnabled(insertAllowed); + contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"),this,SLOT(chnDelete())); + contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(chnMoveUp()))->setEnabled(moveUpAllowed); + contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(chnMoveDown()))->setEnabled(moveDownAllowed); + contextMenu.addSeparator(); + contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"),this,SLOT(chnClearAll())); - contextMenu.exec(globalPos); + contextMenu.exec(globalPos); +} + +void Channels::chnMoveUp() +{ + swapChnData(selectedChannel, selectedChannel - 1); +} + +void Channels::chnMoveDown() +{ + swapChnData(selectedChannel, selectedChannel + 1); +} + +void Channels::chnClear() +{ + model->limitData[selectedChannel].clear(); + updateLine(selectedChannel); + emit modified(); +} + +void Channels::chnClearAll() +{ + for (int i=0; ilimitData[i].clear(); + updateLine(i); + } + emit modified(); +} + +void Channels::chnInsert() +{ + for (int i=(chnCapability - 1); i>selectedChannel; i--) { + if (!model->limitData[i].isEmpty() || !model->limitData[i-1].isEmpty()) { + memcpy(&model->limitData[i], &model->limitData[i-1], sizeof(LimitData)); + updateLine(i); + } + } + chnClear(); +} + +void Channels::swapChnData(int idx1, int idx2) +{ + if ((idx1 != idx2) && (!model->limitData[idx1].isEmpty() || !model->limitData[idx2].isEmpty())) { + LimitData chntmp = model->limitData[idx2]; + LimitData *chn1 = &model->limitData[idx1]; + LimitData *chn2 = &model->limitData[idx2]; + memcpy(chn2, chn1, sizeof(LimitData)); + memcpy(chn1, &chntmp, sizeof(LimitData)); + updateLine(idx1); + updateLine(idx2); + emit modified(); + } } diff --git a/companion/src/modeledit/channels.h b/companion/src/modeledit/channels.h index a13fa84a6..f50c72b89 100644 --- a/companion/src/modeledit/channels.h +++ b/companion/src/modeledit/channels.h @@ -26,6 +26,8 @@ #include +constexpr char MIMETYPE_CHN[] = "application/x-companion-chn"; + class GVarGroup; class LimitsGroup @@ -70,9 +72,15 @@ class Channels : public ModelPanel void chnCopy(); void chnPaste(); void chnCut(); + void chnMoveUp(); + void chnMoveDown(); + void chnInsert(); + void chnClear(); + void chnClearAll(); void chn_customContextMenuRequested(QPoint pos); private: + void swapChnData(int idx1, int idx2); QLineEdit *name[CPN_MAX_CHNOUT]; LimitsGroup *chnOffset[CPN_MAX_CHNOUT]; LimitsGroup *chnMin[CPN_MAX_CHNOUT]; @@ -82,6 +90,7 @@ class Channels : public ModelPanel QSpinBox *centerSB[CPN_MAX_CHNOUT]; QCheckBox *symlimitsChk[CPN_MAX_CHNOUT]; int selectedChannel; + int chnCapability; }; #endif // _CHANNELS_H_