5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
22 #include "modelprinter.h"
23 #include "multiprotocols.h"
25 #include "helpers_html.h"
26 #include "multiprotocols.h"
28 #include <QApplication>
33 QString
changeColor(const QString
& input
, const QString
& to
, const QString
& from
)
35 QString result
= input
;
36 return result
.replace("color="+from
, "color="+to
);
39 ModelPrinter::ModelPrinter(Firmware
* firmware
, const GeneralSettings
& generalSettings
, const ModelData
& model
):
41 generalSettings(generalSettings
),
46 ModelPrinter::~ModelPrinter()
50 QString
formatTitle(const QString
& name
)
52 return QString("<b>" + name
+ "</b> ");
55 void debugHtml(const QString
& html
)
57 QFile
file("foo.html");
58 file
.open(QIODevice::Truncate
| QIODevice::WriteOnly
);
59 file
.write(html
.toUtf8());
63 QString
addFont(const QString
& input
, const QString
& color
, const QString
& size
, const QString
& face
)
66 if (!color
.isEmpty()) {
67 colorStr
= "color=" + color
;
70 if (!size
.isEmpty()) {
71 sizeStr
= "size=" + size
;
74 if (!face
.isEmpty()) {
75 faceStr
= "face='" + face
+ "'";
77 return "<font " + sizeStr
+ " " + faceStr
+ " " + colorStr
+ ">" + input
+ "</font>";
80 QString
ModelPrinter::printLabelValue(const QString
& lbl
, const QString
& val
, const bool sep
) {
81 return QString("<b>%1:</b> %2%3 ").arg(lbl
, val
, (sep
? ";" : ""));
84 QString
ModelPrinter::printLabelValues(const QString
& lbl
, const QStringList
& vals
, const bool sep
) {
88 for (int i
=0;i
<vals
.count();i
++) {
89 str
.append(vals
.at(i
));
90 if (i
<(vals
.count()-1))
96 return printLabelValue(lbl
, str
, sep
);
99 #define MASK_TIMEVALUE_HRSMINS 1
100 #define MASK_TIMEVALUE_ZEROHRS 2
101 #define MASK_TIMEVALUE_PADSIGN 3
103 QString
ModelPrinter::printTimeValue(const int value
, const unsigned int mask
)
112 result
= (sign
< 0 ? QString("-") : ((mask
& MASK_TIMEVALUE_PADSIGN
) ? QString(" ") : QString("")));
113 if (mask
& MASK_TIMEVALUE_HRSMINS
) {
114 int hours
= val
/ 3600;
115 if (hours
> 0 || (mask
& MASK_TIMEVALUE_ZEROHRS
)) {
117 result
.append(QString("%1:").arg(hours
, 2, 10, QLatin1Char('0')));
120 int minutes
= val
/ 60;
121 int seconds
= val
% 60;
122 result
.append(QString("%1:%2").arg(minutes
, 2, 10, QLatin1Char('0')).arg(seconds
, 2, 10, QLatin1Char('0')));
126 #define BOOLEAN_ENABLEDISABLE 1
127 #define BOOLEAN_TRUEFALSE 2
128 #define BOOLEAN_YESNO 3
130 #define BOOLEAN_ONOFF 5
132 QString
ModelPrinter::printBoolean(const bool val
, const int typ
)
135 case BOOLEAN_ENABLEDISABLE
:
136 return (val
? tr("Enable") : tr("Disable"));
137 case BOOLEAN_TRUEFALSE
:
138 return (val
? tr("True") : tr("False"));
140 return (val
? tr("Yes") : tr("No"));
142 return (val
? tr("Y") : tr("N"));
144 return (val
? tr("ON") : tr("OFF"));
146 return CPN_STR_UNKNOWN_ITEM
;
150 QString
ModelPrinter::printEEpromSize()
152 return QString("%1 ").arg(getCurrentEEpromInterface()->getSize(model
)) + tr("bytes");
155 QString
ModelPrinter::printChannelName(int idx
)
157 QString str
= RawSource(SOURCE_TYPE_CH
, idx
).toString(&model
, &generalSettings
);
158 if (firmware
->getCapability(ChannelsName
)) {
159 str
= str
.leftJustified(firmware
->getCapability(ChannelsName
) + 5, ' ', false);
162 return str
.toHtmlEscaped();
165 QString
ModelPrinter::printTrimIncrementMode()
167 switch (model
.trimInc
) {
169 return tr("Exponential");
171 return tr("Extra Fine");
179 return tr("Unknown");
183 QString
ModelPrinter::printModule(int idx
)
187 ModuleData module
= model
.moduleData
[(idx
<0 ? CPN_MAX_MODULES
: idx
)];
189 str
<< printLabelValue(tr("Mode"), printTrainerMode());
190 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
191 if (model
.trainerMode
== TRAINER_SLAVE_JACK
) {
192 str
<< printLabelValue(tr("Channels"), QString("%1-%2").arg(module
.channelsStart
+ 1).arg(module
.channelsStart
+ module
.channelsCount
));
193 str
<< printLabelValue(tr("Frame length"), QString("%1ms").arg(printPPMFrameLength(module
.ppm
.frameLength
)));
194 str
<< printLabelValue(tr("PPM delay"), QString("%1us").arg(module
.ppm
.delay
));
195 str
<< printLabelValue(tr("Polarity"), module
.polarityToString());
198 result
= str
.join(" ");
201 str
<< printLabelValue(tr("Protocol"), ModuleData::protocolToString(module
.protocol
));
202 if (module
.protocol
) {
203 str
<< printLabelValue(tr("Channels"), QString("%1-%2").arg(module
.channelsStart
+ 1).arg(module
.channelsStart
+ module
.channelsCount
));
204 if (module
.protocol
== PULSES_PPM
|| module
.protocol
== PULSES_SBUS
) {
205 str
<< printLabelValue(tr("Frame length"), QString("%1ms").arg(printPPMFrameLength(module
.ppm
.frameLength
)));
206 str
<< printLabelValue(tr("Polarity"), module
.polarityToString());
207 if (module
.protocol
== PULSES_PPM
)
208 str
<< printLabelValue(tr("Delay"), QString("%1us").arg(module
.ppm
.delay
));
211 if (!(module
.protocol
== PULSES_PXX_XJT_D8
|| module
.protocol
== PULSES_CROSSFIRE
|| module
.protocol
== PULSES_SBUS
)) {
212 str
<< printLabelValue(tr("Receiver"), QString::number(module
.modelId
));
214 if (module
.protocol
== PULSES_MULTIMODULE
) {
215 str
<< printLabelValue(tr("Radio protocol"), module
.rfProtocolToString());
216 str
<< printLabelValue(tr("Subtype"), module
.subTypeToString());
217 str
<< printLabelValue(tr("Option value"), QString::number(module
.multi
.optionValue
));
219 if (module
.protocol
== PULSES_PXX_R9M
) {
220 str
<< printLabelValue(tr("Sub Type"), module
.subTypeToString());
221 str
<< printLabelValue(tr("RF Output Power"), module
.powerValueToString(firmware
));
222 str
<< printLabelValue(tr("Telemetry"), printBoolean(module
.pxx
.sport_out
, BOOLEAN_ENABLEDISABLE
));
226 result
= str
.join(" ");
227 if (((PulsesProtocol
)module
.protocol
== PulsesProtocol::PULSES_PXX_XJT_X16
|| (PulsesProtocol
)module
.protocol
== PulsesProtocol::PULSES_PXX_R9M
)
228 && firmware
->getCapability(HasFailsafe
))
229 result
.append("<br/>" + printFailsafe(idx
));
234 QString
ModelPrinter::printTrainerMode()
237 switch (model
.trainerMode
) {
238 case TRAINER_MASTER_JACK
:
239 result
= tr("Master/Jack");
241 case TRAINER_SLAVE_JACK
:
242 result
= tr("Slave/Jack");
244 case TRAINER_MASTER_SBUS_MODULE
:
245 result
= tr("Master/SBUS Module");
247 case TRAINER_MASTER_CPPM_MODULE
:
248 result
= tr("Master/CPPM Module");
250 case TRAINER_MASTER_SBUS_BATT_COMPARTMENT
:
251 result
= tr("Master/SBUS in battery compartment");
254 result
= CPN_STR_UNKNOWN_ITEM
;
259 QString
ModelPrinter::printHeliSwashType ()
261 switch (model
.swashRingData
.type
) {
262 case HELI_SWASH_TYPE_90
:
264 case HELI_SWASH_TYPE_120
:
266 case HELI_SWASH_TYPE_120X
:
268 case HELI_SWASH_TYPE_140
:
270 case HELI_SWASH_TYPE_NONE
:
273 return CPN_STR_UNKNOWN_ITEM
;
277 QString
ModelPrinter::printCenterBeep()
280 if (model
.beepANACenter
& 0x01)
281 strl
<< tr("Rudder");
282 if (model
.beepANACenter
& 0x02)
283 strl
<< tr("Elevator");
284 if (model
.beepANACenter
& 0x04)
285 strl
<< tr("Throttle");
286 if (model
.beepANACenter
& 0x08)
287 strl
<< tr("Aileron");
288 if (IS_HORUS(firmware
->getBoard())) {
290 qDebug() << "ModelPrinter::printCenterBeep() TODO";
292 else if (IS_TARANIS(firmware
->getBoard())) {
293 if (model
.beepANACenter
& 0x10)
295 if (model
.beepANACenter
& 0x20)
297 if (model
.beepANACenter
& 0x40)
299 if (model
.beepANACenter
& 0x80)
301 if (model
.beepANACenter
& 0x100)
305 if (model
.beepANACenter
& 0x10)
307 if (model
.beepANACenter
& 0x20)
309 if (model
.beepANACenter
& 0x40)
312 return (strl
.isEmpty() ? tr("None") : strl
.join(" "));
315 QString
ModelPrinter::printTimer(int idx
)
317 return printTimer(model
.timers
[idx
]);
320 QString
ModelPrinter::printTimer(const TimerData
& timer
)
323 if (firmware
->getCapability(TimersName
) && timer
.name
[0])
324 result
+= tr("Name") + QString("(%1)").arg(timer
.name
);
325 result
+= printTimeValue(timer
.val
, MASK_TIMEVALUE_HRSMINS
| MASK_TIMEVALUE_ZEROHRS
);
326 result
+= timer
.mode
.toString();
327 if (timer
.countdownBeep
)
328 result
+= tr("Countdown") + QString("(%1)").arg(printTimerCountdownBeep(timer
.countdownBeep
));
329 if (timer
.minuteBeep
)
330 result
+= tr("Minute call");
331 if (timer
.persistent
)
332 result
+= tr("Persistent") + QString("(%1)").arg(printTimerPersistent(timer
.persistent
));
333 return result
.join(", ");
336 QString
ModelPrinter::printTrim(int flightModeIndex
, int stickIndex
)
338 const FlightModeData
& fm
= model
.flightModeData
[flightModeIndex
];
340 if (fm
.trimMode
[stickIndex
] == -1) {
344 if (fm
.trimRef
[stickIndex
] == flightModeIndex
) {
345 return QString("%1").arg(fm
.trim
[stickIndex
]);
348 if (fm
.trimMode
[stickIndex
] == 0) {
349 return tr("FM%1").arg(fm
.trimRef
[stickIndex
]);
352 if (fm
.trim
[stickIndex
] < 0)
353 return tr("FM%1%2").arg(fm
.trimRef
[stickIndex
]).arg(fm
.trim
[stickIndex
]);
355 return tr("FM%1+%2").arg(fm
.trimRef
[stickIndex
]).arg(fm
.trim
[stickIndex
]);
361 QString
ModelPrinter::printGlobalVar(int flightModeIndex
, int gvarIndex
)
363 const FlightModeData
& fm
= model
.flightModeData
[flightModeIndex
];
365 if (fm
.gvars
[gvarIndex
] <= 1024) {
366 return QString("%1").arg(fm
.gvars
[gvarIndex
] * model
.gvarData
[gvarIndex
].multiplierGet());
369 int num
= fm
.gvars
[gvarIndex
] - 1025;
370 if (num
>= flightModeIndex
) num
++;
371 return tr("FM%1").arg(num
);
375 QString
ModelPrinter::printRotaryEncoder(int flightModeIndex
, int reIndex
)
377 const FlightModeData
& fm
= model
.flightModeData
[flightModeIndex
];
379 if (fm
.rotaryEncoders
[reIndex
] <= 1024) {
380 return QString("%1").arg(fm
.rotaryEncoders
[reIndex
]);
383 int num
= fm
.rotaryEncoders
[reIndex
] - 1025;
384 if (num
>= flightModeIndex
) num
++;
385 return tr("FM%1").arg(num
);
389 QString
ModelPrinter::printInputName(int idx
)
391 RawSourceType srcType
= (firmware
->getCapability(VirtualInputs
) ? SOURCE_TYPE_VIRTUAL_INPUT
: SOURCE_TYPE_STICK
);
392 return RawSource(srcType
, idx
).toString(&model
, &generalSettings
).toHtmlEscaped();
395 QString
ModelPrinter::printInputLine(int idx
)
397 return printInputLine(model
.expoData
[idx
]);
400 QString
ModelPrinter::printInputLine(const ExpoData
& input
)
402 QString str
= " ";
404 switch (input
.mode
) {
405 case (1): str
+= "<- "; break;
406 case (2): str
+= "-> "; break;
407 default: str
+= " "; break;
410 if (firmware
->getCapability(VirtualInputs
)) {
411 str
+= input
.srcRaw
.toString(&model
, &generalSettings
).toHtmlEscaped();
414 str
+= " " + tr("Weight").toHtmlEscaped() + QString("(%1)").arg(Helpers::getAdjustmentString(input
.weight
, &model
, true).toHtmlEscaped());
415 if (input
.curve
.value
)
416 str
+= " " + input
.curve
.toString(&model
).toHtmlEscaped();
418 QString flightModesStr
= printFlightModes(input
.flightModes
);
419 if (!flightModesStr
.isEmpty())
420 str
+= " " + flightModesStr
.toHtmlEscaped();
422 if (input
.swtch
.type
!= SWITCH_TYPE_NONE
)
423 str
+= " " + tr("Switch").toHtmlEscaped() + QString("(%1)").arg(input
.swtch
.toString(getCurrentBoard(), &generalSettings
)).toHtmlEscaped();
426 if (firmware
->getCapability(VirtualInputs
)) {
427 if (input
.carryTrim
>0)
428 str
+= " " + tr("NoTrim").toHtmlEscaped();
429 else if (input
.carryTrim
<0)
430 str
+= " " + RawSource(SOURCE_TYPE_TRIM
, (-(input
.carryTrim
)-1)).toString(&model
, &generalSettings
).toHtmlEscaped();
434 str
+= " " + tr("Offset(%1)").arg(Helpers::getAdjustmentString(input
.offset
, &model
)).toHtmlEscaped();
436 if (firmware
->getCapability(HasExpoNames
) && input
.name
[0])
437 str
+= QString(" [%1]").arg(input
.name
).toHtmlEscaped();
442 QString
ModelPrinter::printMixerLine(const MixData
& mix
, bool showMultiplex
, int highlightedSource
)
444 QString str
= " ";
448 case (1): str
+= "*="; break;
449 case (2): str
+= ":="; break;
450 default: str
+= "+="; break;
454 str
+= " ";
456 // highlight source if needed
457 QString source
= mix
.srcRaw
.toString(&model
, &generalSettings
).toHtmlEscaped();
458 if ( (mix
.srcRaw
.type
== SOURCE_TYPE_CH
) && (mix
.srcRaw
.index
+1 == (int)highlightedSource
) ) {
459 source
= "<b>" + source
+ "</b>";
461 str
+= " " + source
;
463 if (mix
.mltpx
== MLTPX_MUL
&& !showMultiplex
)
464 str
+= " " + tr("MULT!").toHtmlEscaped();
466 str
+= " " + tr("Weight") + QString("(%1)").arg(Helpers::getAdjustmentString(mix
.weight
, &model
, true)).toHtmlEscaped();
468 QString flightModesStr
= printFlightModes(mix
.flightModes
);
469 if (!flightModesStr
.isEmpty())
470 str
+= " " + flightModesStr
.toHtmlEscaped();
472 if (mix
.swtch
.type
!= SWITCH_TYPE_NONE
)
473 str
+= " " + tr("Switch") + QString("(%1)").arg(mix
.swtch
.toString(getCurrentBoard(), &generalSettings
)).toHtmlEscaped();
475 if (mix
.carryTrim
> 0)
476 str
+= " " + tr("NoTrim").toHtmlEscaped();
477 else if (mix
.carryTrim
< 0)
478 str
+= " " + RawSource(SOURCE_TYPE_TRIM
, (-(mix
.carryTrim
)-1)).toString(&model
, &generalSettings
);
480 if (firmware
->getCapability(HasNoExpo
) && mix
.noExpo
)
481 str
+= " " + tr("No DR/Expo").toHtmlEscaped();
483 str
+= " " + tr("Offset") + QString("(%1)").arg(Helpers::getAdjustmentString(mix
.sOffset
, &model
)).toHtmlEscaped();
485 str
+= " " + mix
.curve
.toString(&model
).toHtmlEscaped();
486 int scale
= firmware
->getCapability(SlowScale
);
489 if (mix
.delayDown
|| mix
.delayUp
)
490 str
+= " " + tr("Delay") + QString("(u%1:d%2)").arg((double)mix
.delayUp
/scale
).arg((double)mix
.delayDown
/scale
).toHtmlEscaped();
491 if (mix
.speedDown
|| mix
.speedUp
)
492 str
+= " " + tr("Slow") + QString("(u%1:d%2)").arg((double)mix
.speedUp
/scale
).arg((double)mix
.speedDown
/scale
).toHtmlEscaped();
494 str
+= " " + tr("Warn") + QString("(%1)").arg(mix
.mixWarn
).toHtmlEscaped();
495 if (firmware
->getCapability(HasMixerNames
) && mix
.name
[0])
496 str
+= QString(" [%1]").arg(mix
.name
).toHtmlEscaped();
500 QString
ModelPrinter::printFlightModeSwitch(const RawSwitch
& swtch
)
502 return swtch
.toString(getCurrentBoard(), &generalSettings
);
505 QString
ModelPrinter::printFlightModeName(int index
)
507 return model
.flightModeData
[index
].nameToString(index
);
510 QString
ModelPrinter::printFlightModes(unsigned int flightModes
)
512 int numFlightModes
= firmware
->getCapability(FlightModes
);
513 if (numFlightModes
&& flightModes
) {
514 if (flightModes
== (unsigned int)(1<<numFlightModes
) - 1) {
515 return tr("Disabled in all flight modes");
519 for (int i
=0; i
<numFlightModes
; i
++) {
520 if (!(flightModes
& (1<<i
))) {
521 list
<< printFlightModeName(i
);
524 return (list
.size() > 1 ? tr("Flight modes") : tr("Flight mode")) + QString("(%1)").arg(list
.join(", "));
531 QString
ModelPrinter::printInputFlightModes(unsigned int flightModes
)
533 int numFlightModes
= firmware
->getCapability(FlightModes
);
534 if (numFlightModes
&& flightModes
) {
535 if (flightModes
== (unsigned int)(1<<numFlightModes
) - 1) {
540 for (int i
=0; i
<numFlightModes
; i
++) {
541 if (!(flightModes
& (1<<i
))) {
542 list
<< printFlightModeName(i
);
545 return QString("%1").arg(list
.join(" "));
552 QString
ModelPrinter::printLogicalSwitchLine(int idx
)
555 const LogicalSwitchData
& ls
= model
.logicalSw
[idx
];
556 const QString sw1Name
= RawSwitch(ls
.val1
).toString(getCurrentBoard(), &generalSettings
);
557 const QString sw2Name
= RawSwitch(ls
.val2
).toString(getCurrentBoard(), &generalSettings
);
565 switch (ls
.getFunctionFamily()) {
567 result
+= tr("Edge") + QString("(%1, [%2:%3])").arg(sw1Name
).arg(ValToTim(ls
.val2
)).arg(ls
.val3
<0 ? tr("instant") : QString("%1").arg(ValToTim(ls
.val2
+ls
.val3
)));
569 case LS_FAMILY_STICKY
:
570 result
+= tr("Sticky") + QString("(%1, %2)").arg(sw1Name
).arg(sw2Name
);
572 case LS_FAMILY_TIMER
:
573 result
+= tr("Timer") + QString("(%1, %2)").arg(ValToTim(ls
.val1
)).arg(ValToTim(ls
.val2
));
575 case LS_FAMILY_VOFS
: {
576 RawSource source
= RawSource(ls
.val1
);
577 RawSourceRange range
= source
.getRange(&model
, generalSettings
);
580 res
+= source
.toString(&model
, &generalSettings
);
584 if (ls
.func
== LS_FN_APOS
|| ls
.func
== LS_FN_ANEG
)
585 res
= "|" + res
+ "|";
586 else if (ls
.func
== LS_FN_DAPOS
)
587 res
= "|d(" + res
+ ")|";
588 else if (ls
.func
== LS_FN_DPOS
)
589 result
= "d(" + res
+ ")";
591 if (ls
.func
== LS_FN_VEQUAL
)
593 else if (ls
.func
== LS_FN_APOS
|| ls
.func
== LS_FN_VPOS
|| ls
.func
== LS_FN_DPOS
|| ls
.func
== LS_FN_DAPOS
)
595 else if (ls
.func
== LS_FN_ANEG
|| ls
.func
== LS_FN_VNEG
)
597 else if (ls
.func
== LS_FN_VALMOSTEQUAL
)
600 result
+= tr(" missing");
601 result
+= QString::number(range
.step
* (ls
.val2
/*TODO+ source.getRawOffset(model)*/) + range
.offset
);
604 case LS_FAMILY_VBOOL
:
623 case LS_FAMILY_VCOMP
:
625 result
+= RawSource(ls
.val1
).toString(&model
, &generalSettings
);
653 result
+= RawSource(ls
.val2
).toString(&model
, &generalSettings
);
661 result
+= RawSwitch(ls
.andsw
).toString(getCurrentBoard(), &generalSettings
);
664 if (firmware
->getCapability(LogicalSwitchesExt
)) {
666 result
+= " " + tr("Duration") + QString("(%1s)").arg(ls
.duration
/10.0);
668 result
+= " " + tr("Delay") + QString("(%1s)").arg(ls
.delay
/10.0);
674 QString
ModelPrinter::printCustomFunctionLine(int idx
)
677 const CustomFunctionData
& cf
= model
.customFn
[idx
];
678 if (cf
.swtch
.type
== SWITCH_TYPE_NONE
)
681 result
+= cf
.swtch
.toString(getCurrentBoard(), &generalSettings
) + " - ";
682 result
+= cf
.funcToString(&model
) + " (";
683 result
+= cf
.paramToString(&model
) + ")";
684 if (!cf
.repeatToString().isEmpty())
685 result
+= " " + cf
.repeatToString();
686 if (!cf
.enabledToString().isEmpty())
687 result
+= " " + cf
.enabledToString();
691 QString
ModelPrinter::printCurveName(int idx
)
693 return model
.curves
[idx
].nameToString(idx
).toHtmlEscaped();
696 QString
ModelPrinter::printCurve(int idx
)
699 const CurveData
& curve
= model
.curves
[idx
];
700 result
+= (curve
.type
== CurveData::CURVE_TYPE_CUSTOM
) ? tr("Custom") : tr("Standard");
702 if (curve
.type
== CurveData::CURVE_TYPE_CUSTOM
) {
703 for (int j
=0; j
<curve
.count
; j
++) {
706 result
+= QString("(%1, %2)").arg(curve
.points
[j
].x
).arg(curve
.points
[j
].y
);
710 for (int j
=0; j
<curve
.count
; j
++) {
713 result
+= QString("%1").arg(curve
.points
[j
].y
);
720 CurveImage::CurveImage():
722 image(size
+1, size
+1, QImage::Format_RGB32
),
725 painter
.setBrush(QBrush("#FFFFFF"));
726 painter
.setPen(QColor(0, 0, 0));
727 painter
.drawRect(0, 0, size
, size
);
729 painter
.setPen(QColor(0, 0, 0));
730 painter
.drawLine(0, size
/2, size
, size
/2);
731 painter
.drawLine(size
/2, 0, size
/2, size
);
732 for (int i
=0; i
<21; i
++) {
733 painter
.drawLine(size
/2-5, (size
*i
)/(20), size
/2+5, (size
*i
)/(20));
734 painter
.drawLine((size
*i
)/(20), size
/2-5, (size
*i
)/(20), size
/2+5);
738 void CurveImage::drawCurve(const CurveData
& curve
, QColor color
)
740 painter
.setPen(QPen(color
, 2, Qt::SolidLine
));
741 for (int j
=1; j
<curve
.count
; j
++) {
742 if (curve
.type
== CurveData::CURVE_TYPE_CUSTOM
)
743 painter
.drawLine(size
/2+(size
*curve
.points
[j
-1].x
)/200, size
/2-(size
*curve
.points
[j
-1].y
)/200, size
/2+(size
*curve
.points
[j
].x
)/200, size
/2-(size
*curve
.points
[j
].y
)/200);
745 painter
.drawLine(size
*(j
-1)/(curve
.count
-1), size
/2-(size
*curve
.points
[j
-1].y
)/200, size
*(j
)/(curve
.count
-1), size
/2-(size
*curve
.points
[j
].y
)/200);
749 QString
ModelPrinter::createCurveImage(int idx
, QTextDocument
* document
)
752 image
.drawCurve(model
.curves
[idx
], colors
[idx
]);
753 QString filename
= QString("mydata://curve-%1-%2.png").arg((uint64_t)this).arg(idx
);
755 document
->addResource(QTextDocument::ImageResource
, QUrl(filename
), image
.get());
756 // qDebug() << "ModelPrinter::createCurveImage()" << idx << filename;
760 QString
ModelPrinter::printGlobalVarUnit(int idx
)
762 return model
.gvarData
[idx
].unitToString().toHtmlEscaped();
765 QString
ModelPrinter::printGlobalVarPrec(int idx
)
767 return model
.gvarData
[idx
].precToString().toHtmlEscaped();
770 QString
ModelPrinter::printGlobalVarMin(int idx
)
772 return QString::number(model
.gvarData
[idx
].getMinPrec());
775 QString
ModelPrinter::printGlobalVarMax(int idx
)
777 return QString::number(model
.gvarData
[idx
].getMaxPrec());
780 QString
ModelPrinter::printGlobalVarPopup(int idx
)
782 return printBoolean(model
.gvarData
[idx
].popup
, BOOLEAN_YN
);
785 QString
ModelPrinter::printOutputValueGVar(int val
)
788 if (abs(val
) > 10000) {
791 result
.append(RawSource(SOURCE_TYPE_GVAR
, abs(val
)-10001).toString(&model
));
796 result
.append(QString::number((qreal
)val
/10, 'f', 1) + "%");
801 QString
ModelPrinter::printOutputOffset(int idx
)
803 return printOutputValueGVar(model
.limitData
[idx
].offset
);
806 QString
ModelPrinter::printOutputMin(int idx
)
808 return printOutputValueGVar(model
.limitData
[idx
].min
);
811 QString
ModelPrinter::printOutputMax(int idx
)
813 return printOutputValueGVar(model
.limitData
[idx
].max
);
816 QString
ModelPrinter::printOutputRevert(int idx
)
818 return model
.limitData
[idx
].revertToString();
821 QString
ModelPrinter::printOutputPpmCenter(int idx
)
823 return QString::number(model
.limitData
[idx
].ppmCenter
+ 1500);
826 QString
ModelPrinter::printOutputCurve(int idx
)
828 return CurveReference(CurveReference::CURVE_REF_CUSTOM
, model
.limitData
[idx
].curve
.value
).toString(&model
, false);
831 QString
ModelPrinter::printOutputSymetrical(int idx
)
833 return printBoolean(model
.limitData
[idx
].symetrical
, BOOLEAN_YN
);
836 QString
ModelPrinter::printSettingsOther()
839 str
<< printLabelValue(tr("Extended Limits"), printBoolean(model
.extendedLimits
, BOOLEAN_YESNO
));
840 if (firmware
->getCapability(HasDisplayText
))
841 str
<< printLabelValue(tr("Display Checklist"), printBoolean(model
.displayChecklist
, BOOLEAN_YESNO
));
842 if (firmware
->getCapability(GlobalFunctions
))
843 str
<< printLabelValue(tr("Global Functions"), printBoolean(!model
.noGlobalFunctions
, BOOLEAN_YESNO
));
844 return str
.join(" ");
847 QString
ModelPrinter::printSwitchWarnings()
850 Boards board
= firmware
->getBoard();
851 uint64_t switchStates
= model
.switchWarningStates
;
854 for (int idx
=0; idx
<board
.getCapability(Board::Switches
); idx
++) {
855 Board::SwitchInfo switchInfo
= Boards::getSwitchInfo(board
.getBoardType(), idx
);
856 switchInfo
.config
= Board::SwitchType(generalSettings
.switchConfig
[idx
]);
857 if (switchInfo
.config
== Board::SWITCH_NOT_AVAILABLE
|| switchInfo
.config
== Board::SWITCH_TOGGLE
) {
860 if (!(model
.switchWarningEnable
& (1 << idx
))) {
861 if (IS_HORUS_OR_TARANIS(board
.getBoardType())) {
862 value
= (switchStates
>> (2*idx
)) & 0x03;
865 value
= (idx
==0 ? switchStates
& 0x3 : switchStates
& 0x1);
866 switchStates
>>= (idx
==0 ? 2 : 1);
868 str
+= RawSwitch(SWITCH_TYPE_SWITCH
, 1+idx
*3+value
).toString(board
.getBoardType(), &generalSettings
, &model
);
871 return (str
.isEmpty() ? tr("None") : str
.join(" ")) ;
874 QString
ModelPrinter::printPotWarnings()
878 Boards board
= firmware
->getBoard();
879 if (model
.potsWarningMode
) {
880 for (int i
=0; i
<board
.getCapability(Board::Pots
)+board
.getCapability(Board::Sliders
); i
++) {
881 RawSource
src(SOURCE_TYPE_STICK
, CPN_MAX_STICKS
+ i
);
882 if ((src
.isPot(&genAryIdx
) && generalSettings
.isPotAvailable(genAryIdx
)) || (src
.isSlider(&genAryIdx
) && generalSettings
.isSliderAvailable(genAryIdx
))) {
883 if (!model
.potsWarningEnabled
[i
])
884 str
+= src
.toString(&model
, &generalSettings
);
888 str
<< printLabelValue(tr("Mode"), printPotsWarningMode());
889 return str
.join(" ");
892 QString
ModelPrinter::printPotsWarningMode()
894 switch (model
.potsWarningMode
) {
902 return CPN_STR_UNKNOWN_ITEM
;
906 QString
ModelPrinter::printFailsafe(int idx
)
909 ModuleData module
= model
.moduleData
[idx
];
910 strl
<< printLabelValue(tr("Failsafe Mode"), printFailsafeMode(module
.failsafeMode
));
911 if (module
.failsafeMode
== FAILSAFE_CUSTOM
) {
912 for (int i
=0; i
<module
.channelsCount
; i
++) {
913 //strl << QString("%1(%2)").arg(printChannelName(module.channelsStart + i).trimmed()).arg(printFailsafeValue(module.failsafeChannels[i]));
914 strl
<< printLabelValue(printChannelName(module
.channelsStart
+ i
).trimmed(), printFailsafeValue(module
.failsafeChannels
[i
]));
917 return strl
.join(" ");
920 QString
ModelPrinter::printFailsafeValue(int val
)
926 return tr("No Pulse");
928 return QString("%1%").arg(QString::number(divRoundClosest(val
* 1000, 1024) / 10.0));
932 QString
ModelPrinter::printFailsafeMode(unsigned int fsmode
)
935 case FAILSAFE_NOT_SET
:
936 return tr("Not set");
939 case FAILSAFE_CUSTOM
:
941 case FAILSAFE_NOPULSES
:
942 return tr("No pulses");
943 case FAILSAFE_RECEIVER
:
944 return tr("Receiver");
946 return CPN_STR_UNKNOWN_ITEM
;
950 QString
ModelPrinter::printTimerCountdownBeep(unsigned int countdownBeep
)
952 switch (countdownBeep
) {
953 case TimerData::COUNTDOWN_SILENT
:
955 case TimerData::COUNTDOWN_BEEPS
:
957 case TimerData::COUNTDOWN_VOICE
:
959 case TimerData::COUNTDOWN_HAPTIC
:
962 return CPN_STR_UNKNOWN_ITEM
;
966 QString
ModelPrinter::printTimerPersistent(unsigned int persistent
)
968 switch (persistent
) {
974 return tr("Manual reset");
976 return CPN_STR_UNKNOWN_ITEM
;
980 QString
ModelPrinter::printSettingsTrim()
983 str
<< printLabelValue(tr("Step"), printTrimIncrementMode());
984 if (IS_ARM(firmware
->getBoard()))
985 str
<< printLabelValue(tr("Display"), printTrimsDisplayMode());
986 str
<< printLabelValue(tr("Extended"), printBoolean(model
.extendedTrims
, BOOLEAN_YESNO
));
987 return str
.join(" ");
990 QString
ModelPrinter::printThrottleSource(int idx
)
992 Boards board
= firmware
->getBoard();
993 int chnstart
= board
.getCapability(Board::Pots
)+board
.getCapability(Board::Sliders
);
996 else if (idx
< (chnstart
+1))
997 return firmware
->getAnalogInputName(idx
+board
.getCapability(Board::Sticks
)-1);
999 return RawSource(SOURCE_TYPE_CH
, idx
-chnstart
-1).toString(&model
, &generalSettings
);
1002 QString
ModelPrinter::printTrimsDisplayMode()
1004 switch (model
.trimsDisplay
) {
1008 return tr("On Change");
1010 return tr("Always");
1012 return CPN_STR_UNKNOWN_ITEM
;
1016 QString
ModelPrinter::printModuleType(int idx
)
1018 return ModuleData::indexToString(idx
, firmware
);
1021 QString
ModelPrinter::printPxxPower(int power
)
1023 static const char *strings
[] = {
1024 "10mW", "100mW", "500mW", "3W"
1026 return CHECK_IN_ARRAY(strings
, power
);
1029 QString
ModelPrinter::printThrottle()
1032 result
<< printLabelValue(tr("Source"), printThrottleSource(model
.thrTraceSrc
));
1033 result
<< printLabelValue(tr("Trim idle only"), printBoolean(model
.thrTrim
, BOOLEAN_YESNO
));
1034 result
<< printLabelValue(tr("Warning"), printBoolean(!model
.disableThrottleWarning
, BOOLEAN_YESNO
));
1035 result
<< printLabelValue(tr("Reversed"), printBoolean(model
.throttleReversed
, BOOLEAN_YESNO
));
1036 return result
.join(" ");
1039 QString
ModelPrinter::printPPMFrameLength(int ppmFL
)
1041 double result
= (((double)ppmFL
* 5) + 225) / 10;
1042 return QString::number(result
);
1045 QString
ModelPrinter::printTimerName(int idx
)
1048 result
= tr("Tmr") + QString("%1").arg(idx
+1);
1049 if (firmware
->getCapability(TimersName
) && model
.timers
[idx
].name
[0])
1050 result
.append(":" + QString(model
.timers
[idx
].name
));
1055 QString
ModelPrinter::printTimerTimeValue(unsigned int val
)
1057 return printTimeValue(val
, MASK_TIMEVALUE_HRSMINS
| MASK_TIMEVALUE_ZEROHRS
);
1060 QString
ModelPrinter::printTimerMinuteBeep(bool mb
)
1062 return printBoolean(mb
, BOOLEAN_YESNO
);
1065 QString
ModelPrinter::printTelemetryProtocol(unsigned int val
)
1069 return tr("FrSky S.PORT");
1071 return tr("FrSky D");
1073 return tr("FrSky D (cable)");
1075 return CPN_STR_UNKNOWN_ITEM
;
1079 QString
ModelPrinter::printRssiAlarmsDisabled(bool mb
)
1081 return printBoolean(!mb
, BOOLEAN_ENABLEDISABLE
);
1084 QString
ModelPrinter::printTelemetrySource(int val
)
1086 QStringList strings
= QStringList() << tr("None");
1088 for (int i
=1; i
<=CPN_MAX_SENSORS
; ++i
) {
1089 strings
<< QString("%1").arg(model
.sensorData
[i
-1].label
);
1092 return QString("%1%2").arg((val
< 0 ? "-" : "")).arg(strings
.value(abs(val
)));
1095 QString
ModelPrinter::printVarioSource(unsigned int val
)
1098 case TELEMETRY_VARIO_SOURCE_ALTI
:
1100 case TELEMETRY_VARIO_SOURCE_ALTI_PLUS
:
1102 case TELEMETRY_VARIO_SOURCE_VSPEED
:
1103 return tr("VSpeed");
1104 case TELEMETRY_VARIO_SOURCE_A1
:
1106 case TELEMETRY_VARIO_SOURCE_A2
:
1109 return CPN_STR_UNKNOWN_ITEM
;
1113 QString
ModelPrinter::printVarioCenterSilent(bool mb
)
1115 return printBoolean(mb
, BOOLEAN_YESNO
);
1118 QString
ModelPrinter::printVoltsSource(unsigned int val
)
1121 case TELEMETRY_VOLTS_SOURCE_A1
:
1123 case TELEMETRY_VOLTS_SOURCE_A2
:
1125 case TELEMETRY_VOLTS_SOURCE_A3
:
1127 case TELEMETRY_VOLTS_SOURCE_A4
:
1129 case TELEMETRY_VOLTS_SOURCE_FAS
:
1131 case TELEMETRY_VOLTS_SOURCE_CELLS
:
1134 return CPN_STR_UNKNOWN_ITEM
;
1138 QString
ModelPrinter::printCurrentSource(unsigned int val
)
1141 case TELEMETRY_CURRENT_SOURCE_NONE
:
1143 case TELEMETRY_CURRENT_SOURCE_A1
:
1145 case TELEMETRY_CURRENT_SOURCE_A2
:
1147 case TELEMETRY_CURRENT_SOURCE_A3
:
1149 case TELEMETRY_CURRENT_SOURCE_A4
:
1151 case TELEMETRY_CURRENT_SOURCE_FAS
:
1154 return CPN_STR_UNKNOWN_ITEM
;
1158 QString
ModelPrinter::printMahPersistent(bool mb
)
1160 return printBoolean(mb
, BOOLEAN_YESNO
);
1163 QString
ModelPrinter::printIgnoreSensorIds(bool mb
)
1165 return printBoolean(mb
, BOOLEAN_ENABLEDISABLE
);
1168 QString
ModelPrinter::printSensorType(unsigned int val
)
1171 case SensorData::TELEM_TYPE_CUSTOM
:
1172 return tr("Custom");
1173 case SensorData::TELEM_TYPE_CALCULATED
:
1174 return tr("Calculated");
1176 return CPN_STR_UNKNOWN_ITEM
;
1180 QString
ModelPrinter::printSensorFormula(unsigned int val
)
1183 case SensorData::TELEM_FORMULA_ADD
:
1185 case SensorData::TELEM_FORMULA_AVERAGE
:
1186 return tr("Average");
1187 case SensorData::TELEM_FORMULA_MIN
:
1189 case SensorData::TELEM_FORMULA_MAX
:
1191 case SensorData::TELEM_FORMULA_MULTIPLY
:
1192 return tr("Multiply");
1193 case SensorData::TELEM_FORMULA_TOTALIZE
:
1194 return tr("Totalise");
1195 case SensorData::TELEM_FORMULA_CELL
:
1197 case SensorData::TELEM_FORMULA_CONSUMPTION
:
1198 return tr("Consumption");
1199 case SensorData::TELEM_FORMULA_DIST
:
1200 return tr("Distance");
1202 return CPN_STR_UNKNOWN_ITEM
;
1206 QString
ModelPrinter::printSensorCells(unsigned int val
)
1208 QStringList strings
;
1210 strings
<< tr("Lowest");
1211 for (int i
=1; i
<=6; i
++)
1212 strings
<< tr("Cell %1").arg(i
);
1213 strings
<< tr("Highest") << tr("Delta");
1215 return strings
.value(val
);
1218 QString
ModelPrinter::printSensorTypeCond(unsigned int idx
)
1220 if (!model
.sensorData
[idx
].isAvailable())
1223 return printSensorType(model
.sensorData
[idx
].type
);
1226 QString
ModelPrinter::printSensorDetails(unsigned int idx
)
1229 SensorData sensor
= model
.sensorData
[idx
];
1231 if (!sensor
.isAvailable())
1234 bool isConfigurable
= false;
1235 bool gpsFieldsPrinted
= false;
1236 bool cellsFieldsPrinted
= false;
1237 bool consFieldsPrinted
= false;
1238 bool ratioFieldsPrinted
= false;
1239 bool totalizeFieldsPrinted
= false;
1240 bool sources12FieldsPrinted
= false;
1241 bool sources34FieldsPrinted
= false;
1243 str
.append(doTableCell(printSensorTypeCond(idx
)));
1246 if (sensor
.type
== SensorData::TELEM_TYPE_CALCULATED
) {
1247 isConfigurable
= (sensor
.formula
< SensorData::TELEM_FORMULA_CELL
);
1248 gpsFieldsPrinted
= (sensor
.formula
== SensorData::TELEM_FORMULA_DIST
);
1249 cellsFieldsPrinted
= (sensor
.formula
== SensorData::TELEM_FORMULA_CELL
);
1250 consFieldsPrinted
= (sensor
.formula
== SensorData::TELEM_FORMULA_CONSUMPTION
);
1251 sources12FieldsPrinted
= (sensor
.formula
<= SensorData::TELEM_FORMULA_MULTIPLY
);
1252 sources34FieldsPrinted
= (sensor
.formula
< SensorData::TELEM_FORMULA_MULTIPLY
);
1253 totalizeFieldsPrinted
= (sensor
.formula
== SensorData::TELEM_FORMULA_TOTALIZE
);
1255 tc
.append(printLabelValue(tr("Formula"), printSensorFormula(sensor
.formula
)));
1258 isConfigurable
= sensor
.unit
< SensorData::UNIT_FIRST_VIRTUAL
;
1259 ratioFieldsPrinted
= (sensor
.unit
< SensorData::UNIT_FIRST_VIRTUAL
);
1261 tc
.append(printLabelValue(tr("Id"), QString::number(sensor
.id
,16).toUpper()));
1262 tc
.append(printLabelValue(tr("Instance"), QString::number(sensor
.instance
)));
1264 if (cellsFieldsPrinted
) {
1265 tc
.append(printLabelValue(tr("Sensor"), QString("%1 > %2").arg(printTelemetrySource(sensor
.source
), false).arg(printSensorCells(sensor
.index
))));
1267 if (sources12FieldsPrinted
) {
1269 for (int i
=0;i
<4;i
++) {
1270 if (i
< 2 || sources34FieldsPrinted
) {
1271 srcs
<< printTelemetrySource(sensor
.sources
[i
]);
1274 tc
.append(printLabelValues(tr("Sources"), srcs
));
1276 if (consFieldsPrinted
|| totalizeFieldsPrinted
)
1277 tc
.append(printLabelValue(tr("Sensor"), printTelemetrySource(sensor
.amps
)));
1278 if (gpsFieldsPrinted
) {
1279 tc
.append(printLabelValue(tr("GPS"), printTelemetrySource(sensor
.gps
)));
1280 tc
.append(printLabelValue(tr("Alt."), printTelemetrySource(sensor
.alt
)));
1282 if (ratioFieldsPrinted
&& sensor
.unit
== SensorData::UNIT_RPMS
) {
1283 tc
.append(printLabelValue(tr("Blades"), QString::number(sensor
.ratio
)));
1284 tc
.append(printLabelValue(tr("Multi."), QString::number(sensor
.offset
)));
1286 str
.append(doTableCell(tc
));
1288 tc
= sensor
.unitString();
1289 tc
= tc
.trimmed() == "" ? "-" : tc
;
1290 str
.append(doTableCell(tc
));
1292 if (isConfigurable
&& sensor
.unit
!= SensorData::UNIT_FAHRENHEIT
)
1293 tc
= QString::number(sensor
.prec
);
1296 str
.append(doTableCell(tc
));
1298 if (!ratioFieldsPrinted
) {
1299 str
.append(doTableCell(""));
1300 str
.append(doTableCell(""));
1302 else if (sensor
.unit
!= SensorData::UNIT_RPMS
) {
1303 int prec
= sensor
.prec
== 0 ? 1 : pow(10, sensor
.prec
);
1304 str
.append(doTableCell(QString::number((float)sensor
.ratio
/ prec
)));
1305 str
.append(doTableCell(QString::number((float)sensor
.offset
/ prec
)));
1308 if (sensor
.unit
!= SensorData::UNIT_RPMS
&& isConfigurable
)
1309 str
.append(doTableCell(printBoolean(sensor
.autoOffset
, BOOLEAN_YN
)));
1311 str
.append(doTableCell(""));
1314 str
.append(doTableCell(printBoolean(sensor
.filter
, BOOLEAN_YN
)));
1316 str
.append(doTableCell(""));
1318 if (sensor
.type
== SensorData::TELEM_TYPE_CALCULATED
)
1319 str
.append(doTableCell(printBoolean(sensor
.persistent
, BOOLEAN_YN
)));
1321 str
.append(doTableCell(""));
1323 str
.append(doTableCell(printBoolean(sensor
.onlyPositive
, BOOLEAN_YN
)));
1324 str
.append(doTableCell(printBoolean(sensor
.logs
, BOOLEAN_YN
), false));
1328 QString
ModelPrinter::printSensorParams(unsigned int idx
)
1331 SensorData sensor
= model
.sensorData
[idx
];
1333 if (!sensor
.isAvailable())
1336 bool isConfigurable
= false;
1337 bool gpsFieldsPrinted
= false;
1338 bool cellsFieldsPrinted
= false;
1339 bool consFieldsPrinted
= false;
1340 bool ratioFieldsPrinted
= false;
1341 bool totalizeFieldsPrinted
= false;
1342 bool sources12FieldsPrinted
= false;
1343 bool sources34FieldsPrinted
= false;
1345 if (sensor
.type
== SensorData::TELEM_TYPE_CALCULATED
) {
1346 isConfigurable
= (sensor
.formula
< SensorData::TELEM_FORMULA_CELL
);
1347 gpsFieldsPrinted
= (sensor
.formula
== SensorData::TELEM_FORMULA_DIST
);
1348 cellsFieldsPrinted
= (sensor
.formula
== SensorData::TELEM_FORMULA_CELL
);
1349 consFieldsPrinted
= (sensor
.formula
== SensorData::TELEM_FORMULA_CONSUMPTION
);
1350 sources12FieldsPrinted
= (sensor
.formula
<= SensorData::TELEM_FORMULA_MULTIPLY
);
1351 sources34FieldsPrinted
= (sensor
.formula
< SensorData::TELEM_FORMULA_MULTIPLY
);
1352 totalizeFieldsPrinted
= (sensor
.formula
== SensorData::TELEM_FORMULA_TOTALIZE
);
1354 str
.append(printLabelValue(tr("F"), printSensorFormula(sensor
.formula
)));
1357 isConfigurable
= sensor
.unit
< SensorData::UNIT_FIRST_VIRTUAL
;
1358 ratioFieldsPrinted
= (sensor
.unit
< SensorData::UNIT_FIRST_VIRTUAL
);
1360 str
.append(printLabelValue(tr("Id"), QString::number(sensor
.id
,16).toUpper()));
1361 str
.append(printLabelValue(tr("Inst"), QString::number(sensor
.instance
)));
1363 if (cellsFieldsPrinted
) {
1364 str
.append(printLabelValue(tr("Sensor"), QString("%1 %2").arg(printTelemetrySource(sensor
.source
), false).arg(printSensorCells(sensor
.index
))));
1366 if (sources12FieldsPrinted
) {
1368 for (int i
=0;i
<4;i
++) {
1369 if (i
< 2 || sources34FieldsPrinted
) {
1370 srcs
<< printTelemetrySource(sensor
.sources
[i
]);
1373 str
.append(printLabelValues(tr("Sources"), srcs
));
1375 if (consFieldsPrinted
|| totalizeFieldsPrinted
)
1376 str
.append(printLabelValue(tr("Sensor"), printTelemetrySource(sensor
.amps
)));
1377 if (gpsFieldsPrinted
) {
1378 str
.append(printLabelValue(tr("GPS"), printTelemetrySource(sensor
.gps
)));
1379 str
.append(printLabelValue(tr("Alt"), printTelemetrySource(sensor
.alt
)));
1381 QString u
= sensor
.unitString();
1382 u
= u
.trimmed() == "" ? "-" : u
;
1383 str
.append(printLabelValue(tr("Unit"), u
));
1384 if (isConfigurable
&& sensor
.unit
!= SensorData::UNIT_FAHRENHEIT
)
1385 str
.append(printLabelValue(tr("Prec"), QString::number(sensor
.prec
)));
1386 if (ratioFieldsPrinted
) {
1387 if (sensor
.unit
!= SensorData::UNIT_RPMS
) {
1388 int prec
= sensor
.prec
== 0 ? 1 : pow(10, sensor
.prec
);
1389 str
.append(printLabelValue(tr("Ratio"), QString::number((float)sensor
.ratio
/ prec
)));
1390 str
.append(printLabelValue(tr("Offset"), QString::number((float)sensor
.offset
/ prec
)));
1392 else if (sensor
.unit
== SensorData::UNIT_RPMS
) {
1393 str
.append(printLabelValue(tr("Blades"), QString::number(sensor
.ratio
)));
1394 str
.append(printLabelValue(tr("Multi"), QString::number(sensor
.offset
)));
1397 if (sensor
.unit
!= SensorData::UNIT_RPMS
&& isConfigurable
)
1398 str
.append(printLabelValue(tr("A/Offset"), printBoolean(sensor
.autoOffset
, BOOLEAN_YN
)));
1400 str
.append(printLabelValue(tr("Filter"), printBoolean(sensor
.filter
, BOOLEAN_YN
)));
1401 if (sensor
.type
== SensorData::TELEM_TYPE_CALCULATED
)
1402 str
.append(printLabelValue(tr("Persist"), printBoolean(sensor
.persistent
, BOOLEAN_YN
)));
1403 str
.append(printLabelValue(tr("Positive"), printBoolean(sensor
.onlyPositive
, BOOLEAN_YN
)));
1404 str
.append(printLabelValue(tr("Log"), printBoolean(sensor
.logs
, BOOLEAN_YN
), false));
1408 QString
ModelPrinter::printTelemetryScreenType(unsigned int val
)
1411 case TelemetryScreenEnum::TELEMETRY_SCREEN_NONE
:
1413 case TelemetryScreenEnum::TELEMETRY_SCREEN_NUMBERS
:
1414 return tr("Numbers");
1415 case TelemetryScreenEnum::TELEMETRY_SCREEN_BARS
:
1417 case TelemetryScreenEnum::TELEMETRY_SCREEN_SCRIPT
:
1418 return tr("Script");
1420 return CPN_STR_UNKNOWN_ITEM
;
1424 QString
ModelPrinter::printTelemetryScreen(unsigned int idx
, unsigned int line
, unsigned int width
)
1428 FrSkyScreenData screen
= model
.frsky
.screens
[idx
];
1429 hd
<< ""; // blank 1st column
1431 if (screen
.type
== TelemetryScreenEnum::TELEMETRY_SCREEN_NUMBERS
) {
1433 for (int c
=0; c
<firmware
->getCapability(TelemetryCustomScreensFieldsPerLine
); c
++) {
1437 for (int c
=0; c
<firmware
->getCapability(TelemetryCustomScreensFieldsPerLine
); c
++) {
1438 RawSource source
= screen
.body
.lines
[line
].source
[c
];
1439 strl
<< source
.toString(&model
, &generalSettings
);
1442 else if (screen
.type
== TelemetryScreenEnum::TELEMETRY_SCREEN_BARS
) {
1444 hd
<< tr("Source") << tr("Min") << tr("Max");
1446 RawSource source
= screen
.body
.bars
[line
].source
;
1447 RawSourceRange range
= source
.getRange(&model
, generalSettings
);
1448 strl
<< source
.toString(&model
, &generalSettings
);
1452 if (source
.isTimeBased()){
1453 minstr
= printTimeValue((float)screen
.body
.bars
[line
].barMin
, MASK_TIMEVALUE_HRSMINS
);
1454 maxstr
= printTimeValue((float)screen
.body
.bars
[line
].barMax
, MASK_TIMEVALUE_HRSMINS
);
1457 minstr
= QString::number(range
.getValue(screen
.body
.bars
[line
].barMin
));
1458 maxstr
= QString::number(range
.getValue(screen
.body
.bars
[line
].barMax
));
1461 strl
<< QString("%1%2").arg(minstr
).arg(unit
);
1462 strl
<< QString("%1%2").arg(maxstr
).arg(unit
);
1464 else if (screen
.type
== TelemetryScreenEnum::TELEMETRY_SCREEN_SCRIPT
&& line
== 0) {
1465 hd
<< tr("Filename");
1466 strl
<< QString("%1.lua").arg(screen
.body
.script
.filename
);
1468 return (hd
.count() > 1 ? doTableRow(hd
, width
/ hd
.count(), "left", "", true) : "" ) + doTableRow(strl
, width
/ strl
.count());