diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index 16ba240e0..d38069827 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -532,6 +532,8 @@ int ModelData::updateReference() Firmware *fw = getCurrentFirmware(); + updRefInfo.occurences = 1; + switch (updRefInfo.type) { case REF_UPD_TYPE_CHANNEL: @@ -566,6 +568,7 @@ int ModelData::updateReference() updRefInfo.srcType = SOURCE_TYPE_TELEMETRY; updRefInfo.swtchType = SWITCH_TYPE_SENSOR; updRefInfo.maxindex = fw->getCapability(Sensors); + updRefInfo.occurences = 3; break; case REF_UPD_TYPE_TIMER: updRefInfo.srcType = SOURCE_TYPE_SPECIAL; @@ -767,15 +770,35 @@ int ModelData::updateReference() //s1.report("Telemetry"); } - // TODO maybe less risk to leave it up to the user?? - /* for (int i = 0; i < CPN_MAX_SENSORS; i++) { SensorData *sd = &sensorData[i]; - if (sd->isAvailable() && sd->type == SensorData::TELEM_TYPE_CALCULATED) { + if (!sd->isEmpty() && sd->type == SensorData::TELEM_TYPE_CALCULATED) { + if (sd->formula == SensorData::TELEM_FORMULA_CELL) { + updateTelemetryRef(sd->source); + if (sd->source == 0) { + sd->clear(); + appendUpdateReferenceParams(REF_UPD_TYPE_SENSOR, REF_UPD_ACT_CLEAR, i); + } + } + else if (sd->formula == SensorData::TELEM_FORMULA_DIST) { + updateTelemetryRef(sd->gps); + updateTelemetryRef(sd->alt); + } + else if (sd->formula == SensorData::TELEM_FORMULA_CONSUMPTION || sd->formula == SensorData::TELEM_FORMULA_TOTALIZE) { + updateTelemetryRef(sd->amps); + if (sd->amps == 0) { + sd->clear(); + appendUpdateReferenceParams(REF_UPD_TYPE_SENSOR, REF_UPD_ACT_CLEAR, i); + } + } + else { + for (unsigned int i = 0; i < 4; i++) { + updateTelemetryRef(sd->sources[i]); + } + } } } - s1.report("Telemetry Sensors"); - */ + //s1.report("Telemetry Sensors"); // TODO needs lua incorporated into Companion as script needs to be parsed to determine if input field is source or value /* @@ -811,38 +834,40 @@ void ModelData::updateTypeIndexRef(R & curRef, const T type, const int idxAdj, c newRef.type = curRef.type; newRef.index = abs(curRef.index); + div_t idx = div(newRef.index, updRefInfo.occurences); + switch (updRefInfo.action) { case REF_UPD_ACT_CLEAR: - if (newRef.index != (updRefInfo.index1 + idxAdj)) + if (idx.quot != (updRefInfo.index1 + idxAdj)) return; if (defClear) newRef.clear(); else { newRef.type = (T)defType; - newRef.index = defIndex; + newRef.index = defIndex + idxAdj; } break; case REF_UPD_ACT_SHIFT: - if (newRef.index < (updRefInfo.index1 + idxAdj)) + if (idx.quot < (updRefInfo.index1 + idxAdj)) return; newRef.index += updRefInfo.shift; - if (newRef.index < (updRefInfo.index1 + idxAdj) || newRef.index > (updRefInfo.maxindex + idxAdj)) { + if (idx.quot < (updRefInfo.index1 + idxAdj) || idx.quot > (updRefInfo.maxindex + idxAdj)) { if (defClear) newRef.clear(); else { newRef.type = (T)defType; - newRef.index = defIndex; + newRef.index = defIndex + idxAdj; } } break; case REF_UPD_ACT_SWAP: - if (newRef.index == updRefInfo.index1 + idxAdj) - newRef.index = updRefInfo.index2 + idxAdj; - else if (newRef.index == updRefInfo.index2 + idxAdj) - newRef.index = updRefInfo.index1 + idxAdj; + if (idx.quot == updRefInfo.index1 + idxAdj) + newRef.index = ((updRefInfo.index2 + idxAdj) * updRefInfo.occurences) + idx.rem; + else if (idx.quot == updRefInfo.index2 + idxAdj) + newRef.index = ((updRefInfo.index1 + idxAdj) * updRefInfo.occurences) + idx.rem; break; default: qDebug() << "Error - unhandled action:" << updRefInfo.action; @@ -877,7 +902,7 @@ void ModelData::updateTypeValueRef(R & curRef, const T type, const int idxAdj, c newRef.clear(); else { newRef.type = (T)defType; - newRef.value = defValue; + newRef.value = defValue + idxAdj; } break; case REF_UPD_ACT_SHIFT: @@ -891,7 +916,7 @@ void ModelData::updateTypeValueRef(R & curRef, const T type, const int idxAdj, c newRef.clear(); else { newRef.type = (T)defType; - newRef.value = defValue; + newRef.value = defValue + idxAdj; } } break; @@ -1120,13 +1145,14 @@ void ModelData::updateFlightModeFlags(unsigned int & curRef) } } -void ModelData::updateTelemetryRef(unsigned int & curRef) +void ModelData::updateTelemetryRef(int & curRef) { if (updRefInfo.type != REF_UPD_TYPE_SENSOR) return; const int idxAdj = 1; int newRef = curRef; + switch (updRefInfo.action) { case REF_UPD_ACT_CLEAR: @@ -1154,13 +1180,23 @@ void ModelData::updateTelemetryRef(unsigned int & curRef) return; } - if (curRef != static_cast(newRef)) { + if (curRef != newRef) { //qDebug() << "Updated reference:" << curRef << " -> " << newRef; curRef = newRef; updRefInfo.updcnt++; } } +void ModelData::updateTelemetryRef(unsigned int & curRef) +{ + int newRef = (int)curRef; + updateTelemetryRef(newRef); + + if (curRef != static_cast(newRef)) { + curRef = (unsigned int)newRef; + } +} + void ModelData::updateModuleFailsafes(ModuleData * md) { if (updRefInfo.type != REF_UPD_TYPE_CHANNEL) diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index b5ba8e45c..560206c72 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -298,6 +298,7 @@ class ModelData { int shift; int updcnt; int maxindex; + int occurences; RawSourceType srcType; RawSwitchType swtchType; }; @@ -315,6 +316,7 @@ class ModelData { void updateDestCh(MixData * md); void updateLimitCurveRef(CurveReference & crv); void updateFlightModeFlags(unsigned int & flags); + void updateTelemetryRef(int & idx); void updateTelemetryRef(unsigned int & idx); void updateModuleFailsafes(ModuleData * md); inline void updateSourceRef(RawSource & src) { updateTypeIndexRef(src, updRefInfo.srcType); } diff --git a/companion/src/firmwares/sensordata.cpp b/companion/src/firmwares/sensordata.cpp index 6048b8641..a9b8d7640 100644 --- a/companion/src/firmwares/sensordata.cpp +++ b/companion/src/firmwares/sensordata.cpp @@ -104,7 +104,7 @@ QString SensorData::getOrigin(const ModelData * model) const { if (type != TELEM_TYPE_CUSTOM || !id) return QString(); - + const ModuleData & module = model->moduleData[moduleIdx]; if (module.isPxx2Module() && rxIdx <= 2 && module.access.receivers & (1 << rxIdx)) { return QString(module.access.receiverName[rxIdx]); @@ -113,3 +113,8 @@ QString SensorData::getOrigin(const ModelData * model) const return QString(); } } + +bool SensorData::isEmpty() const +{ + return (!isAvailable() && type == 0 && id == 0 && subid == 0 && instance == 0 && rxIdx == 0 && moduleIdx == 0 && unit == 0 && ratio == 0 && prec == 0 && offset == 0 && autoOffset == 0 && filter == 0 && onlyPositive == 0 && logs == 0); +} diff --git a/companion/src/firmwares/sensordata.h b/companion/src/firmwares/sensordata.h index 7b0a5f368..a2b993bcc 100644 --- a/companion/src/firmwares/sensordata.h +++ b/companion/src/firmwares/sensordata.h @@ -24,6 +24,7 @@ #include constexpr int CPN_MAX_SENSORS = 60; +constexpr int SENSOR_LABEL_LEN = 4; class ModelData; @@ -133,7 +134,7 @@ class SensorData { unsigned int moduleIdx; unsigned int persistentValue; unsigned int formula; - char label[4+1]; + char label[SENSOR_LABEL_LEN + 1]; unsigned int unit; unsigned int prec; bool autoOffset; @@ -166,6 +167,7 @@ class SensorData { QString nameToString(int index) const; QString getOrigin(const ModelData* model) const; void clear() { memset(this, 0, sizeof(SensorData)); } + bool isEmpty() const; }; #endif // SENSORDATA_H diff --git a/companion/src/modeledit/channels.cpp b/companion/src/modeledit/channels.cpp index 0cde45109..6442cc2fb 100644 --- a/companion/src/modeledit/channels.cpp +++ b/companion/src/modeledit/channels.cpp @@ -349,8 +349,11 @@ void Channels::cmCopy() void Channels::cmCut() { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + cmCopy(); - cmClear(); + cmClear(false); } void Channels::onCustomContextMenuRequested(QPoint pos) @@ -412,10 +415,12 @@ void Channels::cmMoveDown() swapData(selectedIndex, selectedIndex + 1); } -void Channels::cmClear() +void Channels::cmClear(bool prompt) { - if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) - return; + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + } model->limitData[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); diff --git a/companion/src/modeledit/channels.h b/companion/src/modeledit/channels.h index caa0fca38..d20923a35 100644 --- a/companion/src/modeledit/channels.h +++ b/companion/src/modeledit/channels.h @@ -75,7 +75,7 @@ class Channels : public ModelPanel void cmMoveUp(); void cmMoveDown(); void cmInsert(); - void cmClear(); + void cmClear(bool prompt = true); void cmClearAll(); void onCustomContextMenuRequested(QPoint pos); diff --git a/companion/src/modeledit/curves.cpp b/companion/src/modeledit/curves.cpp index 5759e60e6..662dc61c4 100644 --- a/companion/src/modeledit/curves.cpp +++ b/companion/src/modeledit/curves.cpp @@ -699,10 +699,12 @@ bool Curves::moveUpAllowed() const return selectedIndex > 0; } -void Curves::cmClear() +void Curves::cmClear(bool prompt) { - if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) - return; + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + } model->curves[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); @@ -734,8 +736,10 @@ void Curves::cmCopy() void Curves::cmCut() { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; cmCopy(); - cmClear(); + cmClear(false); } void Curves::cmDelete() diff --git a/companion/src/modeledit/curves.h b/companion/src/modeledit/curves.h index d9a5364a6..34d1a675e 100644 --- a/companion/src/modeledit/curves.h +++ b/companion/src/modeledit/curves.h @@ -81,7 +81,7 @@ class Curves : public ModelPanel void onPointSizeEdited(); void onNodeDelete(); void onCustomContextMenuRequested(QPoint pos); - void cmClear(); + void cmClear(bool prompt = true); void cmClearAll(); void cmCopy(); void cmCut(); diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index f5c42443e..1bf06cfd6 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -628,8 +628,10 @@ void CustomFunctionsPanel::cmCopy() void CustomFunctionsPanel::cmCut() { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Special Function. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; cmCopy(); - cmClear(); + cmClear(false); } void CustomFunctionsPanel::onCustomContextMenuRequested(QPoint pos) @@ -743,10 +745,12 @@ void CustomFunctionsPanel::cmMoveDown() swapData(selectedIndex, selectedIndex + 1); } -void CustomFunctionsPanel::cmClear() +void CustomFunctionsPanel::cmClear(bool prompt) { - if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Special Function. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) - return; + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Special Function. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + } functions[selectedIndex].clear(); resetCBsAndRefresh(selectedIndex); diff --git a/companion/src/modeledit/customfunctions.h b/companion/src/modeledit/customfunctions.h index 1c93f3e96..54a83ddcf 100644 --- a/companion/src/modeledit/customfunctions.h +++ b/companion/src/modeledit/customfunctions.h @@ -82,7 +82,7 @@ class CustomFunctionsPanel : public GenericPanel void cmMoveUp(); void cmMoveDown(); void cmInsert(); - void cmClear(); + void cmClear(bool prompt = true); void cmClearAll(); private: diff --git a/companion/src/modeledit/flightmodes.cpp b/companion/src/modeledit/flightmodes.cpp index 1634aed3a..12082091d 100644 --- a/companion/src/modeledit/flightmodes.cpp +++ b/companion/src/modeledit/flightmodes.cpp @@ -708,10 +708,12 @@ bool FlightModePanel::moveUpAllowed() const return phaseIdx > 0; } -void FlightModePanel::cmClear() +void FlightModePanel::cmClear(bool prompt) { - if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Flight Mode. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) - return; + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Flight Mode. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + } phase.clear(phaseIdx); @@ -780,8 +782,10 @@ void FlightModePanel::cmCopy() void FlightModePanel::cmCut() { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Flight Mode. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; cmCopy(); - cmClear(); + cmClear(false); } void FlightModePanel::cmDelete() @@ -1059,7 +1063,7 @@ void FlightModePanel::gvOnCustomContextMenuRequested(QPoint pos) bool FlightModePanel::gvHasClipboardData() const { - if (gvHasDefnClipboardData() || gvHasValueClipboardData()) + if ((phaseIdx == 0 && gvHasDefnClipboardData() && gvHasAllValuesClipboardData()) || (phaseIdx > 0 && gvHasValueClipboardData())) return true; return false; } @@ -1092,6 +1096,20 @@ bool FlightModePanel::gvHasValueClipboardData(QByteArray * data) const return false; } +bool FlightModePanel::gvHasAllValuesClipboardData(QByteArray * data) const +{ + const QClipboard * clipboard = QApplication::clipboard(); + const QMimeData * mimeData = clipboard->mimeData(); + if (phaseIdx == 0 && mimeData->hasFormat(MIMETYPE_GVAR_ALL_VALUES)) { + if (data) { + data->clear(); + data->append(mimeData->data(MIMETYPE_GVAR_ALL_VALUES)); + } + return true; + } + return false; +} + bool FlightModePanel::gvDeleteAllowed() const { return phaseIdx == 0; @@ -1124,11 +1142,13 @@ bool FlightModePanel::gvMoveUpAllowed() const return (phaseIdx == 0 && gvIdx > 0); } -void FlightModePanel::gvCmClear() +void FlightModePanel::gvCmClear(bool prompt) { if (phaseIdx == 0) { - if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear selected Global Variable across all Flight Modes. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) - return; + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Global Variable across all Flight Modes. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + } model->gvarData[gvIdx].clear(); for (int i = 0; i < fmCount; i++) { model->flightModeData[i].gvars[gvIdx] = model->flightModeData[i].linkedGVarFlightModeZero(i); @@ -1136,6 +1156,10 @@ void FlightModePanel::gvCmClear() model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_CLEAR, gvIdx); } else { + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Global Variable. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + } phase.gvars[gvIdx] = phase.linkedGVarFlightModeZero(phaseIdx); } emit datachanged(); @@ -1173,38 +1197,58 @@ void FlightModePanel::gvCmCopy() if (phaseIdx == 0) { data.append((char*)&model->gvarData[gvIdx], sizeof(GVarData)); mimeData->setData(MIMETYPE_GVAR_PARAMS, data); + QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); + + data.clear(); + for (int j = 0; j < fmCount; j++) { + data.append((char*)&model->flightModeData[j].gvars[gvIdx], sizeof(phase.gvars[0])); + } + mimeData->setData(MIMETYPE_GVAR_ALL_VALUES, data); + QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); + + mimeData->removeFormat(MIMETYPE_GVAR_VALUE); + QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } else { mimeData->removeFormat(MIMETYPE_GVAR_PARAMS); + QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); + + mimeData->removeFormat(MIMETYPE_GVAR_ALL_VALUES); + QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); + + data.clear(); + int val = phase.gvars[gvIdx]; + if (model->isGVarLinked(phaseIdx, gvIdx)) + val = GVAR_MAX_VALUE + 1 + model->getGVarFlightModeIndex(phaseIdx, gvIdx); // store index in case paste is to another flight mode + data.setNum(val); + mimeData->setData(MIMETYPE_GVAR_VALUE, data); + QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } - QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); - int val = phase.gvars[gvIdx]; - if (model->isGVarLinked(phaseIdx, gvIdx)) - val = GVAR_MAX_VALUE + 1 + model->getGVarFlightModeIndex(phaseIdx, gvIdx); // store index in case paste is to another flight mode - data.setNum(val); - mimeData->setData(MIMETYPE_GVAR_VALUE, data); - QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); } void FlightModePanel::gvCmCut() { - gvCmCopy(); - if (phaseIdx > 0) { - gvCmClear(); + if (phaseIdx == 0) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Global Variable across all Flight Modes. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; } else { - model->gvarData[gvIdx].clear(); - phase.gvars[gvIdx] = 0; - model->updateAllReferences(ModelData::REF_UPD_TYPE_GLOBAL_VARIABLE, ModelData::REF_UPD_ACT_CLEAR, gvIdx); - emit datachanged(); - emit modified(); + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Global Variable. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; } + + gvCmCopy(); + gvCmClear(false); } void FlightModePanel::gvCmDelete() { if (phaseIdx > 0) return; + + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Global Variable. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + int maxidx = gvCount - 1; for (int i = gvIdx; i < maxidx; i++) { memcpy(&model->gvarData[i], &model->gvarData[i + 1], sizeof(GVarData)); @@ -1254,11 +1298,20 @@ void FlightModePanel::gvCmMoveUp() void FlightModePanel::gvCmPaste() { QByteArray data; - if (phaseIdx == 0 && gvHasDefnClipboardData(&data)) { - GVarData *gvd = &model->gvarData[gvIdx]; - memcpy(gvd, data.constData(), sizeof(GVarData)); + if (phaseIdx == 0) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Paste to selected Global Variable across all Flight Modes. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + if (gvHasDefnClipboardData(&data)) { + memcpy(&model->gvarData[gvIdx], data.constData(), sizeof(GVarData)); + } + if (gvHasAllValuesClipboardData(&data)) { + for (int j = 0; j < fmCount; j++) { + int *gvar = &model->flightModeData[j].gvars[gvIdx]; + memcpy(gvar, data.mid(j * sizeof(phase.gvars[0]), sizeof(phase.gvars[0])).constData(), sizeof(phase.gvars[0])); + } + } } - if (gvHasValueClipboardData(&data)) { + else if (gvHasValueClipboardData(&data)) { int val = data.toInt(); if (val > GVAR_MAX_VALUE) { if (phaseIdx > 0) diff --git a/companion/src/modeledit/flightmodes.h b/companion/src/modeledit/flightmodes.h index 1986f1e46..61e25c59a 100644 --- a/companion/src/modeledit/flightmodes.h +++ b/companion/src/modeledit/flightmodes.h @@ -29,6 +29,7 @@ class RawSwitchFilterItemModel; constexpr char MIMETYPE_FLIGHTMODE[] = "application/x-companion-flightmode"; constexpr char MIMETYPE_GVAR_PARAMS[] = "application/x-companion-gvar-params"; constexpr char MIMETYPE_GVAR_VALUE[] = "application/x-companion-gvar-value"; +constexpr char MIMETYPE_GVAR_ALL_VALUES[] = "application/x-companion-gvar-all-values"; namespace Ui { class FlightMode; @@ -67,7 +68,7 @@ class FlightModePanel : public ModelPanel void phaseREValue_editingFinished(); void phaseREUse_currentIndexChanged(int index); void onCustomContextMenuRequested(QPoint pos); - void cmClear(); + void cmClear(bool prompt = true); void cmClearAll(); void cmCopy(); void cmCut(); @@ -77,7 +78,7 @@ class FlightModePanel : public ModelPanel void cmMoveDown(); void cmMoveUp(); void gvOnCustomContextMenuRequested(QPoint pos); - void gvCmClear(); + void gvCmClear(bool prompt = true); void gvCmClearAll(); void gvCmCopy(); void gvCmCut(); @@ -127,6 +128,7 @@ class FlightModePanel : public ModelPanel bool gvHasClipboardData() const; bool gvHasDefnClipboardData(QByteArray * data = nullptr) const; bool gvHasValueClipboardData(QByteArray * data = nullptr) const; + bool gvHasAllValuesClipboardData(QByteArray * data = nullptr) const; bool gvDeleteAllowed() const; bool gvInsertAllowed() const; bool gvMoveDownAllowed() const; diff --git a/companion/src/modeledit/inputs.cpp b/companion/src/modeledit/inputs.cpp index 806de54fc..2e65c788c 100644 --- a/companion/src/modeledit/inputs.cpp +++ b/companion/src/modeledit/inputs.cpp @@ -227,26 +227,27 @@ void InputsPanel::setSelectedByExpoList(QList list) } } -void InputsPanel::exposDelete(bool ask) +void InputsPanel::exposDelete(bool prompt) { QList list = createExpoListFromSelected(); if (list.isEmpty()) return; - QMessageBox::StandardButton ret = QMessageBox::No; - - if (ask) - ret = QMessageBox::warning(this, CPN_STR_APP_NAME, tr("Delete selected Inputs. Are you sure?"), QMessageBox::Yes | QMessageBox::No); - - if ((ret == QMessageBox::Yes) || (!ask)) { - exposDeleteList(list, ask); - emit modified(); - update(); + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete selected Input lines. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; } + + exposDeleteList(list, prompt); + emit modified(); + update(); } void InputsPanel::exposCut() { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut selected Input lines. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + exposCopy(); exposDelete(false); } @@ -317,7 +318,6 @@ void InputsPanel::pasteExpoMimeData(const QMimeData * mimeData, int destIdx) } } - void InputsPanel::exposPaste() { const QClipboard *clipboard = QApplication::clipboard(); @@ -515,7 +515,7 @@ void InputsPanel::exposDeleteList(QList list, bool clearName) void InputsPanel::clearExpos() { - if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Inputs. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Input lines. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { model->clearInputs(); for (int i = 0; i < inputsCount; i++) { model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, i); @@ -559,7 +559,7 @@ bool InputsPanel::cmInputMoveUpAllowed() const void InputsPanel::cmInputClear() { - if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Input. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all lines for the selected Inputs. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; for (int i = CPN_MAX_EXPOS - 1; i >= 0; i--) { @@ -574,7 +574,7 @@ void InputsPanel::cmInputClear() void InputsPanel::cmInputDelete() { - if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Input. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete all lines for the selected Inputs. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) return; for (int i = 0; i < CPN_MAX_EXPOS; i++) { diff --git a/companion/src/modeledit/inputs.h b/companion/src/modeledit/inputs.h index 884573fef..9922f2873 100644 --- a/companion/src/modeledit/inputs.h +++ b/companion/src/modeledit/inputs.h @@ -46,7 +46,7 @@ class InputsPanel : public ModelPanel void expolistWidget_customContextMenuRequested(QPoint pos); void expolistWidget_doubleClicked(QModelIndex index); void expolistWidget_KeyPress(QKeyEvent *event); - void exposDelete(bool ask=true); + void exposDelete(bool prompt = true); void exposCut(); void exposCopy(); void exposPaste(); diff --git a/companion/src/modeledit/logicalswitches.cpp b/companion/src/modeledit/logicalswitches.cpp index 63a2ae22f..e70d63568 100644 --- a/companion/src/modeledit/logicalswitches.cpp +++ b/companion/src/modeledit/logicalswitches.cpp @@ -533,8 +533,10 @@ void LogicalSwitchesPanel::cmCopy() void LogicalSwitchesPanel::cmCut() { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Logical Switch. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; cmCopy(); - cmClear(); + cmClear(false); } // TODO make something generic here! @@ -597,8 +599,13 @@ void LogicalSwitchesPanel::cmMoveDown() swapData(selectedIndex, selectedIndex + 1); } -void LogicalSwitchesPanel::cmClear() +void LogicalSwitchesPanel::cmClear(bool prompt) { + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Logical Switch. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + } + model->logicalSw[selectedIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); update(); diff --git a/companion/src/modeledit/logicalswitches.h b/companion/src/modeledit/logicalswitches.h index 2aea300c5..62aa69f30 100644 --- a/companion/src/modeledit/logicalswitches.h +++ b/companion/src/modeledit/logicalswitches.h @@ -59,7 +59,7 @@ class LogicalSwitchesPanel : public ModelPanel void cmMoveUp(); void cmMoveDown(); void cmInsert(); - void cmClear(); + void cmClear(bool prompt = true); void cmClearAll(); private: diff --git a/companion/src/modeledit/mixes.cpp b/companion/src/modeledit/mixes.cpp index c92105ec6..4d0f5f4cd 100644 --- a/companion/src/modeledit/mixes.cpp +++ b/companion/src/modeledit/mixes.cpp @@ -253,28 +253,27 @@ void MixesPanel::setSelectedByMixList(QList list) } -void MixesPanel::mixersDelete(bool ask) +void MixesPanel::mixersDelete(bool prompt) { QList list = createMixListFromSelected(); - if(list.isEmpty()) return; + if(list.isEmpty()) + return; - QMessageBox::StandardButton ret = QMessageBox::No; - - if(ask) { - ret = QMessageBox::warning(this, "companion", - tr("Delete Selected Mixes?"), - QMessageBox::Yes | QMessageBox::No); + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete selected Mix lines. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; } - if ((ret == QMessageBox::Yes) || (!ask)) { - mixersDeleteList(list); - emit modified(); - update(); - } + mixersDeleteList(list); + emit modified(); + update(); } void MixesPanel::mixersCut() { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut selected Mix lines. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + mixersCopy(); mixersDelete(false); } diff --git a/companion/src/modeledit/mixes.h b/companion/src/modeledit/mixes.h index 46a51a21a..95765465e 100644 --- a/companion/src/modeledit/mixes.h +++ b/companion/src/modeledit/mixes.h @@ -39,7 +39,7 @@ class MixesPanel : public ModelPanel private slots: // TODO all slots? void clearMixes(); - void mixersDelete(bool ask=true); + void mixersDelete(bool prompt = true); void mixersCut(); void mixersCopy(); void mixersPaste(); diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 2bd8cc055..dcbe4f101 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -1592,10 +1592,12 @@ bool SetupPanel::moveTimerUpAllowed() const return selectedTimerIndex > 0; } -void SetupPanel::cmTimerClear() +void SetupPanel::cmTimerClear(bool prompt) { - if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Timer. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) - return; + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Timer. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + } model->timers[selectedTimerIndex].clear(); model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_CLEAR, selectedTimerIndex); @@ -1627,8 +1629,10 @@ void SetupPanel::cmTimerCopy() void SetupPanel::cmTimerCut() { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Timer. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; cmTimerCopy(); - cmTimerClear(); + cmTimerClear(false); } void SetupPanel::cmTimerDelete() diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index fbd56ed86..0aa48ea76 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -154,7 +154,7 @@ class SetupPanel : public ModelPanel void on_potWarningMode_currentIndexChanged(int index); void on_editText_clicked(); void onTimerCustomContextMenuRequested(QPoint pos); - void cmTimerClear(); + void cmTimerClear(bool prompt = true); void cmTimerClearAll(); void cmTimerCopy(); void cmTimerCut(); diff --git a/companion/src/modeledit/telemetry.cpp b/companion/src/modeledit/telemetry.cpp index 99915eae5..b34caa89e 100644 --- a/companion/src/modeledit/telemetry.cpp +++ b/companion/src/modeledit/telemetry.cpp @@ -28,9 +28,6 @@ #include - -/******************************************************/ - TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, FrSkyScreenData & screen, GeneralSettings & generalSettings, Firmware * firmware, RawSourceFilterItemModel * srcModel): ModelPanel(parent, model, generalSettings, firmware), ui(new Ui::TelemetryCustomScreen), @@ -38,17 +35,17 @@ TelemetryCustomScreen::TelemetryCustomScreen(QWidget *parent, ModelData & model, { ui->setupUi(this); - for (int l=0; l<4; l++) { - for (int c=0; cgetCapability(TelemetryCustomScreensFieldsPerLine); c++) { + for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensLines); l++) { + for (int c = 0; c < firmware->getCapability(TelemetryCustomScreensFieldsPerLine); c++) { fieldsCB[l][c] = new QComboBox(this); - fieldsCB[l][c]->setProperty("index", c + (l<<8)); + fieldsCB[l][c]->setProperty("index", c + (l << 8)); fieldsCB[l][c]->setModel(srcModel); ui->screenNumsLayout->addWidget(fieldsCB[l][c], l, c, 1, 1); connect(fieldsCB[l][c], SIGNAL(activated(int)), this, SLOT(customFieldChanged(int))); } } - for (int l=0; l<4; l++) { + for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensBars); l++) { barsCB[l] = new QComboBox(this); barsCB[l]->setProperty("index", l); barsCB[l]->setModel(srcModel); @@ -122,18 +119,18 @@ void TelemetryCustomScreen::update() ui->screenNums->setVisible(screen.type == TELEMETRY_SCREEN_NUMBERS); ui->screenBars->setVisible(screen.type == TELEMETRY_SCREEN_BARS); - for (int l=0; l<4; l++) { - for (int c=0; cgetCapability(TelemetryCustomScreensFieldsPerLine); c++) { + for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensLines); l++) { + for (int c = 0; c < firmware->getCapability(TelemetryCustomScreensFieldsPerLine); c++) { fieldsCB[l][c]->setCurrentIndex(fieldsCB[l][c]->findData(screen.body.lines[l].source[c].toValue())); } } - for (int l=0; l<4; l++) { + for (int l = 0; l < firmware->getCapability(TelemetryCustomScreensBars); l++) { barsCB[l]->setCurrentIndex(barsCB[l]->findData(screen.body.bars[l].source.toValue())); } if (screen.type == TELEMETRY_SCREEN_BARS) { - for (int i=0; i<4; i++) { + for (int i = 0; i < firmware->getCapability(TelemetryCustomScreensBars); i++) { updateBar(i); } } @@ -292,13 +289,14 @@ void TelemetryCustomScreen::barTimeChanged() /******************************************************/ -TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): +TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): ModelPanel(parent, model, generalSettings, firmware), ui(new Ui::TelemetrySensor), sensor(sensor), lock(false), sensorIndex(sensorIndex), - selectedIndex(0) + selectedIndex(0), + sensorCapability(sensorCapability) { ui->setupUi(this); ui->numLabel->setText(tr("TELE%1").arg(sensorIndex + 1)); @@ -326,7 +324,7 @@ TelemetrySensorPanel::TelemetrySensorPanel(QWidget *parent, SensorData & sensor, ui->ampsSensor->setField(sensor.amps, this); ui->cellsSensor->setField(sensor.source, this); ui->cellsIndex->addItem(tr("Lowest"), SensorData::TELEM_CELL_INDEX_LOWEST); - for (int i = 1; i <= 6; i++) + for (int i = SensorData::TELEM_CELL_INDEX_LOWEST + 1; i < SensorData::TELEM_CELL_INDEX_HIGHEST; i++) ui->cellsIndex->addItem(tr("Cell %1").arg(i), i); ui->cellsIndex->addItem(tr("Highest"), SensorData::TELEM_CELL_INDEX_HIGHEST); ui->cellsIndex->addItem(tr("Delta"), SensorData::TELEM_CELL_INDEX_DELTA); @@ -475,8 +473,8 @@ void populateTelemetrySourcesComboBox(AutoComboBox * cb, const ModelData * model { cb->clear(); if (negative) { - for (int i=-CPN_MAX_SENSORS; i<0; ++i) { - const SensorData& sensor = model->sensorData[-i-1]; + for (int i = -CPN_MAX_SENSORS; i < 0; ++i) { + const SensorData& sensor = model->sensorData[-i - 1]; if (sensor.isAvailable()) { if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) cb->addItem(QString("-%1 (%2)").arg(sensor.label, sensor.getOrigin(model)), i); @@ -486,7 +484,7 @@ void populateTelemetrySourcesComboBox(AutoComboBox * cb, const ModelData * model } } cb->addItem("---", 0); - for (unsigned i=1; i<=CPN_MAX_SENSORS; ++i) { + for (unsigned i = 1; i <= CPN_MAX_SENSORS; ++i) { const SensorData& sensor = model->sensorData[i-1]; if (sensor.isAvailable()) { if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) @@ -572,6 +570,11 @@ void TelemetrySensorPanel::on_customContextMenuRequested(QPoint pos) contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"),this,SLOT(cmPaste()))->setEnabled(hasClipboardData()); contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"),this,SLOT(cmClear())); contextMenu.addSeparator(); + contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"),this,SLOT(cmInsert()))->setEnabled(insertAllowed()); + contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"),this,SLOT(cmDelete())); + contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(cmMoveUp()))->setEnabled(moveUpAllowed()); + contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(cmMoveDown()))->setEnabled(moveDownAllowed()); + contextMenu.addSeparator(); contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"),this,SLOT(cmClearAll())); contextMenu.exec(globalPos); @@ -589,6 +592,21 @@ bool TelemetrySensorPanel::hasClipboardData(QByteArray * data) const return false; } +bool TelemetrySensorPanel::insertAllowed() const +{ + return ((selectedIndex < sensorCapability - 1) && (model->sensorData[sensorCapability - 1].isEmpty())); +} + +bool TelemetrySensorPanel::moveDownAllowed() const +{ + return selectedIndex < sensorCapability - 1; +} + +bool TelemetrySensorPanel::moveUpAllowed() const +{ + return selectedIndex > 0; +} + void TelemetrySensorPanel::cmCopy() { QByteArray data; @@ -600,8 +618,11 @@ void TelemetrySensorPanel::cmCopy() void TelemetrySensorPanel::cmCut() { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Cut Telemetry Sensor. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + cmCopy(); - cmClear(); + cmClear(false); } void TelemetrySensorPanel::cmPaste() @@ -614,12 +635,15 @@ void TelemetrySensorPanel::cmPaste() } } -void TelemetrySensorPanel::cmClear() +void TelemetrySensorPanel::cmClear(bool prompt) { - if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Telemetry Sensor. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) - return; + if (prompt) { + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Telemetry Sensor. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + } sensor.clear(); + model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, selectedIndex); emit dataModified(); emit modified(); } @@ -632,6 +656,26 @@ void TelemetrySensorPanel::cmClearAll() emit clearAllSensors(); } +void TelemetrySensorPanel::cmInsert() +{ + emit insertSensor(selectedIndex); +} + +void TelemetrySensorPanel::cmDelete() +{ + emit deleteSensor(selectedIndex); +} + +void TelemetrySensorPanel::cmMoveUp() +{ + emit moveUpSensor(selectedIndex); +} + +void TelemetrySensorPanel::cmMoveDown() +{ + emit moveDownSensor(selectedIndex); +} + /******************************************************/ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware): @@ -640,6 +684,10 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin { ui->setupUi(this); + sensorCapability = firmware->getCapability(Sensors); + if (sensorCapability > CPN_MAX_SENSORS) // TODO should be role of getCapability + sensorCapability = CPN_MAX_SENSORS; + if (firmware->getCapability(NoTelemetryProtocol)) { model.frsky.usrProto = 1; } @@ -648,13 +696,17 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin ui->varioCenterSilent->setField(model.frsky.varioCenterSilent, this); ui->A1GB->hide(); ui->A2GB->hide(); - for (unsigned i= 0; i < CPN_MAX_SENSORS; ++i) { - TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, model, generalSettings, firmware); + for (int i = 0; i < sensorCapability; ++i) { + TelemetrySensorPanel * panel = new TelemetrySensorPanel(this, model.sensorData[i], i, sensorCapability, model, generalSettings, firmware); ui->sensorsLayout->addWidget(panel); sensorPanels[i] = panel; connect(panel, SIGNAL(dataModified()), this, SLOT(update())); connect(panel, SIGNAL(modified()), this, SLOT(onModified())); connect(panel, SIGNAL(clearAllSensors()), this, SLOT(on_clearAllSensors())); + connect(panel, SIGNAL(insertSensor(int)), this, SLOT(on_insertSensor(int))); + connect(panel, SIGNAL(deleteSensor(int)), this, SLOT(on_deleteSensor(int))); + connect(panel, SIGNAL(moveUpSensor(int)), this, SLOT(on_moveUpSensor(int))); + connect(panel, SIGNAL(moveDownSensor(int)), this, SLOT(on_moveDownSensor(int))); } if (IS_TARANIS_X9(firmware->getBoard())) { @@ -670,7 +722,7 @@ TelemetryPanel::TelemetryPanel(QWidget *parent, ModelData & model, GeneralSettin for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) { TelemetryCustomScreen * tab = new TelemetryCustomScreen(this, model, model.frsky.screens[i], generalSettings, firmware, srcModel); - ui->customScreens->addTab(tab, tr("Telemetry screen %1").arg(i+1)); + ui->customScreens->addTab(tab, tr("Telemetry screen %1").arg(i + 1)); telemetryCustomScreens[i] = tab; connect(tab, &TelemetryCustomScreen::modified, this, &TelemetryPanel::onModified); connect(this, &TelemetryPanel::updated, tab, &TelemetryCustomScreen::update); @@ -703,7 +755,7 @@ void TelemetryPanel::update() populateTelemetrySourcesComboBox(ui->varioSource, model, false); } - for (unsigned i=0; iupdate(); } @@ -761,10 +813,10 @@ void TelemetryPanel::setup() ui->VarioLabel_1->hide(); ui->VarioLabel_2->hide(); } - ui->varioLimitMin_DSB->setValue(model->frsky.varioMin-10); - ui->varioLimitMax_DSB->setValue(model->frsky.varioMax+10); - ui->varioLimitCenterMax_DSB->setValue((model->frsky.varioCenterMax/10.0)+0.5); - ui->varioLimitCenterMin_DSB->setValue((model->frsky.varioCenterMin/10.0)-0.5); + ui->varioLimitMin_DSB->setValue(model->frsky.varioMin - 10); + ui->varioLimitMax_DSB->setValue(model->frsky.varioMax + 10); + ui->varioLimitCenterMax_DSB->setValue((model->frsky.varioCenterMax / 10.0) + 0.5); + ui->varioLimitCenterMin_DSB->setValue((model->frsky.varioCenterMin / 10.0) - 0.5); } ui->altimetryGB->setVisible(firmware->getCapability(HasVario)), @@ -842,7 +894,7 @@ void TelemetryPanel::on_frskyProtoCB_currentIndexChanged(int index) { if (!lock) { model->frsky.usrProto = index; - for (int i=0; igetCapability(TelemetryCustomScreens); i++) + for (int i = 0; i < firmware->getCapability(TelemetryCustomScreens); i++) telemetryCustomScreens[i]->update(); emit modified(); } @@ -862,23 +914,23 @@ void TelemetryPanel::on_rssiAlarmCriticalSB_editingFinished() void TelemetryPanel::on_varioLimitMin_DSB_editingFinished() { - model->frsky.varioMin = round(ui->varioLimitMin_DSB->value()+10); + model->frsky.varioMin = round(ui->varioLimitMin_DSB->value() + 10); emit modified(); } void TelemetryPanel::on_varioLimitMax_DSB_editingFinished() { - model->frsky.varioMax = round(ui->varioLimitMax_DSB->value()-10); + model->frsky.varioMax = round(ui->varioLimitMax_DSB->value() - 10); emit modified(); } void TelemetryPanel::on_varioLimitCenterMin_DSB_editingFinished() { if (!lock) { - if (ui->varioLimitCenterMin_DSB->value()>ui->varioLimitCenterMax_DSB->value()) { + if (ui->varioLimitCenterMin_DSB->value() > ui->varioLimitCenterMax_DSB->value()) { ui->varioLimitCenterMax_DSB->setValue(ui->varioLimitCenterMin_DSB->value()); } - model->frsky.varioCenterMin = round((ui->varioLimitCenterMin_DSB->value()+0.5)*10); + model->frsky.varioCenterMin = round((ui->varioLimitCenterMin_DSB->value() + 0.5) * 10); emit modified(); } } @@ -886,10 +938,10 @@ void TelemetryPanel::on_varioLimitCenterMin_DSB_editingFinished() void TelemetryPanel::on_varioLimitCenterMax_DSB_editingFinished() { if (!lock) { - if (ui->varioLimitCenterMin_DSB->value()>ui->varioLimitCenterMax_DSB->value()) { + if (ui->varioLimitCenterMin_DSB->value() > ui->varioLimitCenterMax_DSB->value()) { ui->varioLimitCenterMax_DSB->setValue(ui->varioLimitCenterMin_DSB->value()); } - model->frsky.varioCenterMax = round((ui->varioLimitCenterMax_DSB->value()-0.5)*10); + model->frsky.varioCenterMax = round((ui->varioLimitCenterMax_DSB->value() - 0.5) * 10); emit modified(); } } @@ -917,8 +969,56 @@ void TelemetryPanel::on_clearAllSensors() { for (int i = 0; i < CPN_MAX_SENSORS; i++) { model->sensorData[i].clear(); + model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_CLEAR, i); } update(); emit modified(); } + +void TelemetryPanel::on_insertSensor(int selectedIndex) +{ + memmove(&model->sensorData[selectedIndex + 1], &model->sensorData[selectedIndex], (CPN_MAX_SENSORS - (selectedIndex + 1)) * sizeof(SensorData)); + model->sensorData[selectedIndex].clear(); + model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1); + + update(); + emit modified(); +} + +void TelemetryPanel::on_deleteSensor(int selectedIndex) +{ + if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Sensor. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) + return; + + memmove(&model->sensorData[selectedIndex], &model->sensorData[selectedIndex + 1], (CPN_MAX_SENSORS - (selectedIndex + 1)) * sizeof(SensorData)); + model->sensorData[CPN_MAX_SENSORS - 1].clear(); + model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1); + + update(); + emit modified(); +} + +void TelemetryPanel::on_moveUpSensor(int selectedIndex) +{ + swapData(selectedIndex, selectedIndex - 1); +} + +void TelemetryPanel::on_moveDownSensor(int selectedIndex) +{ + swapData(selectedIndex, selectedIndex + 1); +} + +void TelemetryPanel::swapData(int idx1, int idx2) +{ + if ((idx1 != idx2) && (!model->sensorData[idx1].isEmpty() || !model->sensorData[idx2].isEmpty())) { + SensorData sdtmp = model->sensorData[idx2]; + SensorData *sd1 = &model->sensorData[idx1]; + SensorData *sd2 = &model->sensorData[idx2]; + memcpy(sd2, sd1, sizeof(SensorData)); + memcpy(sd1, &sdtmp, sizeof(SensorData)); + model->updateAllReferences(ModelData::REF_UPD_TYPE_SENSOR, ModelData::REF_UPD_ACT_SWAP, idx1, idx2); + update(); + emit modified(); + } +} diff --git a/companion/src/modeledit/telemetry.h b/companion/src/modeledit/telemetry.h index 28dc7643c..cddade217 100644 --- a/companion/src/modeledit/telemetry.h +++ b/companion/src/modeledit/telemetry.h @@ -71,13 +71,18 @@ class TelemetrySensorPanel: public ModelPanel Q_OBJECT public: - TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); + TelemetrySensorPanel(QWidget *parent, SensorData & sensor, int sensorIndex, int sensorCapability, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware); ~TelemetrySensorPanel(); void update(); signals: void dataModified(); void clearAllSensors(); + void insertSensor(int index); + void deleteSensor(int index); + void moveUpSensor(int index); + void moveDownSensor(int index); + protected slots: void on_name_editingFinished(); @@ -90,8 +95,12 @@ class TelemetrySensorPanel: public ModelPanel void cmCopy(); void cmCut(); void cmPaste(); - void cmClear(); + void cmClear(bool prompt = true); void cmClearAll(); + void cmInsert(); + void cmDelete(); + void cmMoveUp(); + void cmMoveDown(); protected: void updateSourcesComboBox(AutoComboBox * cb, bool negative); @@ -102,6 +111,10 @@ class TelemetrySensorPanel: public ModelPanel bool lock = false; int sensorIndex = 0; int selectedIndex = 0; + int sensorCapability; + bool insertAllowed() const; + bool moveDownAllowed() const; + bool moveUpAllowed() const; }; class TelemetryPanel : public ModelPanel @@ -131,17 +144,23 @@ class TelemetryPanel : public ModelPanel void on_mahCount_SB_editingFinished(); void on_mahCount_ChkB_toggled(bool checked); void on_clearAllSensors(); + void on_insertSensor(int index); + void on_deleteSensor(int index); + void on_moveUpSensor(int index); + void on_moveDownSensor(int index); private: Ui::Telemetry *ui; TelemetryCustomScreen * telemetryCustomScreens[4]; TelemetrySensorPanel * sensorPanels[CPN_MAX_SENSORS]; + int sensorCapability; void setup(); void telBarUpdate(); void populateVoltsSource(); void populateCurrentSource(); void populateVarioSource(); + void swapData(int idx1, int idx2); }; #endif // _TELEMETRY_H_