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 "helpers_html.h"
23 #include "multimodelprinter.h"
27 MultiModelPrinter::MultiColumns::MultiColumns(int count
):
31 columns
= new QString
[count
];
34 MultiModelPrinter::MultiColumns::~MultiColumns()
39 void MultiModelPrinter::MultiColumns::append(const QString
& str
)
41 for (int i
=0; i
<count
; i
++) {
46 void MultiModelPrinter::MultiColumns::appendTitle(const QString
& name
)
48 append("<b>" + name
+ "</b> ");
51 void MultiModelPrinter::MultiColumns::append(int idx
, const QString
& str
)
54 compareColumns
[idx
].append(str
);
56 columns
[idx
].append(str
);
59 void MultiModelPrinter::MultiColumns::beginCompare()
61 compareColumns
= new QString
[count
];
64 void MultiModelPrinter::MultiColumns::endCompare()
66 for (int i
=0; i
<count
; i
++) {
68 if (i
==0 && count
>1 && compareColumns
[0]!=compareColumns
[1])
70 else if (i
>0 && compareColumns
[i
]!=compareColumns
[0])
73 columns
[i
].append(QString("<span class='%1'>%2</span>").arg(style
).arg(compareColumns
[i
]));
75 columns
[i
].append(compareColumns
[i
]);
77 delete[] compareColumns
;
78 compareColumns
= NULL
;
82 void MultiModelPrinter::MultiColumns::append(int idx
, T val
)
84 append(idx
, QString("%1").arg(val
));
87 QString
MultiModelPrinter::MultiColumns::print()
89 QString result
= "<tr>";
90 for (int i
=0; i
<count
; i
++) {
91 result
.append(QString("<td width='%1%'>%2</td>").arg(100.0/count
).arg(columns
[i
]));
93 result
.append("</tr>");
97 bool MultiModelPrinter::MultiColumns::isEmpty()
99 for (int i
=0; i
<count
; i
++) {
100 if (!columns
[i
].isEmpty())
106 void MultiModelPrinter::MultiColumns::appendLineBreak()
111 void MultiModelPrinter::MultiColumns::appendSectionTableStart()
113 append("<table cellspacing='0' cellpadding='1' width='100%' border='0' style='border-collapse:collapse'>");
116 void MultiModelPrinter::MultiColumns::appendTableEnd()
121 void MultiModelPrinter::MultiColumns::appendRowStart(const QString
& title
, const unsigned int titlewidth
)
124 if (!(title
.isEmpty()) || (titlewidth
))
125 appendLabelCell(QString(title
), titlewidth
);
128 void MultiModelPrinter::MultiColumns::appendRowEnd()
133 void MultiModelPrinter::MultiColumns::appendCellStart(const unsigned int width
, const bool bold
)
137 str
.append(QString(" width='%1%'").arg(QString::number(width
)));
139 str
.append(bold
? "<b>" : "");
143 void MultiModelPrinter::MultiColumns::appendCellEnd(const bool bold
)
146 str
.append(bold
? "</b>" : "");
151 void MultiModelPrinter::MultiColumns::appendLabelCell(const QString
& str
, const unsigned int width
, const QString
& align
, const QString
& color
)
153 append(doTableCell(str
, width
, align
, color
, true));
156 void MultiModelPrinter::MultiColumns::appendValueCell(const QString
& str
, const unsigned int width
, const QString
& align
, const QString
& color
)
158 append(doTableCell(str
, width
, align
, color
, false));
161 void MultiModelPrinter::MultiColumns::appendRow(const QStringList
& strl
, const unsigned int width
, const QString
& align
, const QString
& color
)
163 append(doTableRow(strl
, width
, align
, color
, false));
166 void MultiModelPrinter::MultiColumns::appendRowHeader(const QStringList
& strl
, const unsigned int width
, const QString
& align
, const QString
& color
)
168 append(doTableRow(strl
, width
, align
, color
, true));
171 void MultiModelPrinter::MultiColumns::appendRowBlank()
173 append(doTableBlankRow());
176 void MultiModelPrinter::MultiColumns::appendFieldLabel(const QString
& lbl
)
179 appendTitle(QString("%1:").arg(lbl
));
182 void MultiModelPrinter::MultiColumns::appendFieldSeparator(const bool sep
)
188 #define COMPARE(what) \
189 columns.beginCompare(); \
190 for (int cc=0; cc < modelPrinterMap.size(); cc++) { \
191 ModelPrinter * modelPrinter = modelPrinterMap.value(cc).second; \
192 const ModelData * model = modelPrinterMap.value(cc).first; \
193 (void)(model); (void)(modelPrinter); \
194 columns.append(cc, (what)); \
196 columns.endCompare();
198 #define COMPARECELL(what) \
199 columns.appendCellStart(); \
201 columns.appendCellEnd();
203 #define COMPARECELLWIDTH(what, width) \
204 columns.appendCellStart(width); \
206 columns.appendCellEnd();
208 #define LABELCOMPARECELL(lbl, what, width) \
209 columns.appendCellStart(width); \
210 columns.appendFieldLabel(lbl); \
212 columns.appendCellEnd();
214 #define ROWLABELCOMPARECELL(lbl, lblw, what, width) \
215 columns.appendRowStart(lbl, lblw); \
216 columns.appendCellStart(width); \
218 columns.appendCellEnd(); \
219 columns.appendRowEnd();
221 #define COMPARESTRING(lbl, what, sep) \
222 columns.appendFieldLabel(lbl); \
224 columns.appendFieldSeparator(sep);
226 QString
MultiModelPrinter::printTitle(const QString
& label
)
228 return QString("<tr><td class=mpc-section-title colspan='%1'>").arg(modelPrinterMap
.count()) + label
+ "</td></tr>";
231 MultiModelPrinter::MultiModelPrinter(Firmware
* firmware
):
236 MultiModelPrinter::~MultiModelPrinter()
241 void MultiModelPrinter::setModel(int idx
, const ModelData
* model
, const GeneralSettings
* generalSettings
)
243 if (modelPrinterMap
.contains(idx
) && modelPrinterMap
.value(idx
).second
) {
244 // free existing model printer
245 delete modelPrinterMap
.value(idx
).second
;
246 modelPrinterMap
[idx
].second
= NULL
;
249 QPair
<const ModelData
*, ModelPrinter
*> pair(model
, new ModelPrinter(firmware
, *generalSettings
, *model
));
250 modelPrinterMap
.insert(idx
, pair
); // QMap.insert will replace any existing key
253 void MultiModelPrinter::setModel(int idx
, const ModelData
* model
)
255 setModel(idx
, model
, &defaultSettings
);
258 void MultiModelPrinter::clearModels()
260 for(int i
=0; i
< modelPrinterMap
.size(); i
++) {
261 if (modelPrinterMap
.value(i
).second
)
262 delete modelPrinterMap
.value(i
).second
;
264 modelPrinterMap
.clear();
267 QString
MultiModelPrinter::print(QTextDocument
* document
)
269 if (document
) document
->clear();
270 Stylesheet
css(MODEL_PRINT_CSS
);
271 if (css
.load(Stylesheet::StyleType::STYLE_TYPE_EFFECTIVE
))
272 document
->setDefaultStyleSheet(css
.text());
273 QString str
= "<table cellspacing='0' cellpadding='3' width='100%'>"; // attributes not settable via QT stylesheet
274 str
.append(printSetup());
275 if (firmware
->getCapability(Timers
)) {
276 str
.append(printTimers());
278 str
.append(printModules());
279 if (firmware
->getCapability(Heli
))
280 str
.append(printHeliSetup());
281 if (firmware
->getCapability(FlightModes
))
282 str
.append(printFlightModes());
283 str
.append(printInputs());
284 str
.append(printMixers());
285 str
.append(printOutputs());
286 str
+= printCurves(document
);
287 if (firmware
->getCapability(Gvars
) && !firmware
->getCapability(GvarsFlightModes
))
288 str
.append(printGvars());
289 str
.append(printLogicalSwitches());
290 str
.append(printSpecialFunctions());
291 if (firmware
->getCapability(Telemetry
) & TM_HASTELEMETRY
) {
292 str
.append(printTelemetry());
293 str
.append(printSensors());
294 if (firmware
->getCapability(TelemetryCustomScreens
)) {
295 str
.append(printTelemetryScreens());
298 str
.append("</table>");
302 QString
MultiModelPrinter::printSetup()
304 QString str
= printTitle(tr("General"));
306 MultiColumns
columns(modelPrinterMap
.size());
307 columns
.appendSectionTableStart();
308 ROWLABELCOMPARECELL(tr("Name"), 20, model
->name
, 80);
309 ROWLABELCOMPARECELL(tr("EEprom Size"), 0, modelPrinter
->printEEpromSize(), 0);
310 if (firmware
->getCapability(ModelImage
)) {
311 ROWLABELCOMPARECELL(tr("Model Image"), 0, model
->bitmap
, 0);
313 ROWLABELCOMPARECELL(tr("Throttle"), 0, modelPrinter
->printThrottle(), 0);
314 ROWLABELCOMPARECELL(tr("Trims"), 0, modelPrinter
->printSettingsTrim(), 0);
315 ROWLABELCOMPARECELL(tr("Center Beep"), 0, modelPrinter
->printCenterBeep(), 0);
316 ROWLABELCOMPARECELL(tr("Switch Warnings"), 0, modelPrinter
->printSwitchWarnings(), 0);
317 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
318 ROWLABELCOMPARECELL(tr("Pot Warnings"), 0, modelPrinter
->printPotWarnings(), 0);
320 ROWLABELCOMPARECELL(tr("Other"), 0, modelPrinter
->printSettingsOther(), 0);
321 columns
.appendTableEnd();
322 str
.append(columns
.print());
326 QString
MultiModelPrinter::printTimers()
329 MultiColumns
columns(modelPrinterMap
.size());
330 columns
.appendSectionTableStart();
331 columns
.appendRowHeader(QStringList() << tr("Timers") << tr("Time") << tr("Switch") << tr("Countdown") << tr("Min.call") << tr("Persist"));
333 for (int i
=0; i
<firmware
->getCapability(Timers
); i
++) {
334 columns
.appendRowStart();
335 columns
.appendCellStart(20, true);
336 COMPARE(modelPrinter
->printTimerName(i
));
337 columns
.appendCellEnd(true);
338 COMPARECELLWIDTH(modelPrinter
->printTimerTimeValue(model
->timers
[i
].val
), 15);
339 COMPARECELLWIDTH(model
->timers
[i
].mode
.toString(), 15);
340 COMPARECELLWIDTH(modelPrinter
->printTimerCountdownBeep(model
->timers
[i
].countdownBeep
), 15);
341 COMPARECELLWIDTH(modelPrinter
->printTimerMinuteBeep(model
->timers
[i
].minuteBeep
), 15);
342 COMPARECELLWIDTH(modelPrinter
->printTimerPersistent(model
->timers
[i
].persistent
), 20);
343 columns
.appendRowEnd();
345 columns
.appendTableEnd();
346 str
.append(columns
.print());
350 QString
MultiModelPrinter::printModules()
352 QString str
= printTitle(tr("Modules"));
353 MultiColumns
columns(modelPrinterMap
.size());
354 columns
.appendSectionTableStart();
355 for (int i
=0; i
<firmware
->getCapability(NumModules
); i
++) {
356 columns
.appendRowStart();
357 columns
.appendCellStart(20, true);
358 COMPARE(modelPrinter
->printModuleType(i
));
359 columns
.appendCellEnd(true);
360 COMPARECELLWIDTH(modelPrinter
->printModule(i
), 80);
361 columns
.appendRowEnd();
363 if (firmware
->getCapability(ModelTrainerEnable
))
364 columns
.appendRowStart(tr("Trainer port"));
365 COMPARECELL(modelPrinter
->printModule(-1));
366 columns
.appendRowEnd();
367 columns
.appendTableEnd();
368 str
.append(columns
.print());
372 QString
MultiModelPrinter::printHeliSetup()
374 bool heliEnabled
= false;
375 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
376 heliEnabled
= heliEnabled
|| modelPrinterMap
.value(k
).first
->swashRingData
.type
!= HELI_SWASH_TYPE_NONE
;
382 QString str
= printTitle(tr("Helicopter"));
383 MultiColumns
columns(modelPrinterMap
.size());
384 columns
.appendSectionTableStart();
385 columns
.appendRowStart(tr("Swash"), 20);
386 LABELCOMPARECELL(tr("Type"), modelPrinter
->printHeliSwashType(), 20);
387 LABELCOMPARECELL(tr("Ring"), model
->swashRingData
.value
, 20);
388 columns
.appendRowEnd();
390 columns
.appendRowBlank();
391 columns
.appendRowHeader(QStringList() << "" << tr("Input") << tr("Weight"));
392 columns
.appendRowStart(tr("Long. cyc"));
393 COMPARECELL(model
->swashRingData
.elevatorSource
.toString(model
));
394 COMPARECELL(model
->swashRingData
.elevatorWeight
);
395 columns
.appendRowEnd();
397 columns
.appendRowStart(tr("Lateral cyc"));
398 COMPARECELL(model
->swashRingData
.aileronSource
.toString(model
));
399 COMPARECELL(model
->swashRingData
.aileronWeight
)
400 columns
.appendRowEnd();
402 columns
.appendRowStart(tr("Collective"));
403 COMPARECELL(model
->swashRingData
.collectiveSource
.toString(model
));
404 COMPARECELL(model
->swashRingData
.collectiveWeight
)
405 columns
.appendRowEnd();
407 columns
.appendTableEnd();
408 str
.append(columns
.print());
412 QString
MultiModelPrinter::printFlightModes()
414 QString str
= printTitle(tr("Flight modes"));
417 MultiColumns
columns(modelPrinterMap
.size());
418 columns
.appendSectionTableStart();
419 QStringList hd
= QStringList() << tr("Flight mode") << tr("Switch") << tr("F.In") << tr("F.Out");
420 for (int i
=0; i
< getBoardCapability(getCurrentBoard(), Board::NumTrims
); i
++) {
421 hd
<< RawSource(SOURCE_TYPE_TRIM
, i
).toString();
423 columns
.appendRowHeader(hd
);
424 int wd
= 80/(getBoardCapability(getCurrentBoard(), Board::NumTrims
) + 3);
425 for (int i
=0; i
<firmware
->getCapability(FlightModes
); i
++) {
426 columns
.appendRowStart();
427 columns
.appendCellStart(20,true);
428 COMPARE(modelPrinter
->printFlightModeName(i
));
429 columns
.appendCellEnd(true);
430 COMPARECELLWIDTH(modelPrinter
->printFlightModeSwitch(model
->flightModeData
[i
].swtch
), wd
);
431 COMPARECELLWIDTH(model
->flightModeData
[i
].fadeIn
, wd
);
432 COMPARECELLWIDTH(model
->flightModeData
[i
].fadeOut
, wd
);
433 for (int k
=0; k
< getBoardCapability(getCurrentBoard(), Board::NumTrims
); k
++) {
434 COMPARECELLWIDTH(modelPrinter
->printTrim(i
, k
), wd
);
436 columns
.appendRowEnd();
439 columns
.appendTableEnd();
440 str
.append(columns
.print());
443 // GVars and Rotary Encoders
444 int gvars
= firmware
->getCapability(Gvars
);
445 if ((gvars
&& firmware
->getCapability(GvarsFlightModes
)) || firmware
->getCapability(RotaryEncoders
)) {
446 MultiColumns
columns(modelPrinterMap
.size());
447 columns
.appendSectionTableStart();
448 QStringList hd
= QStringList() << tr("Global vars");
449 if (firmware
->getCapability(GvarsFlightModes
)) {
450 for (int i
=0; i
<gvars
; i
++) {
451 hd
<< tr("GV%1").arg(i
+1);
454 for (int i
=0; i
<firmware
->getCapability(RotaryEncoders
); i
++) {
455 hd
<< tr("RE%1").arg(i
+1);
457 columns
.appendRowHeader(hd
);
459 if (firmware
->getCapability(GvarsFlightModes
)) {
460 columns
.appendRowStart(tr("Name"), 20);
461 for (int i
=0; i
<gvars
; i
++) {
462 COMPARECELLWIDTH(model
->gvarData
[i
].name
, wd
);
464 columns
.appendRowEnd();
465 columns
.appendRowStart(tr("Unit"));
466 for (int i
=0; i
<gvars
; i
++) {
467 COMPARECELL(modelPrinter
->printGlobalVarUnit(i
));
469 columns
.appendRowEnd();
470 columns
.appendRowStart(tr("Prec"));
471 for (int i
=0; i
<gvars
; i
++) {
472 COMPARECELL(modelPrinter
->printGlobalVarPrec(i
));
474 columns
.appendRowEnd();
475 columns
.appendRowStart(tr("Min"));
476 for (int i
=0; i
<gvars
; i
++) {
477 COMPARECELL(modelPrinter
->printGlobalVarMin(i
));
479 columns
.appendRowEnd();
480 columns
.appendRowStart(tr("Max"));
481 for (int i
=0; i
<gvars
; i
++) {
482 COMPARECELL(modelPrinter
->printGlobalVarMax(i
));
484 columns
.appendRowEnd();
485 columns
.appendRowStart(tr("Popup"));
486 for (int i
=0; i
<gvars
; i
++) {
487 COMPARECELL(modelPrinter
->printGlobalVarPopup(i
));
489 columns
.appendRowEnd();
492 columns
.appendRowHeader(QStringList() << tr("Flight mode"));
494 for (int i
=0; i
<firmware
->getCapability(FlightModes
); i
++) {
495 columns
.appendRowStart();
496 columns
.appendCellStart(0,true);
497 COMPARE(modelPrinter
->printFlightModeName(i
));
498 columns
.appendCellEnd(true);
499 if (firmware
->getCapability(GvarsFlightModes
)) {
500 for (int k
=0; k
<gvars
; k
++) {
501 COMPARECELL(modelPrinter
->printGlobalVar(i
, k
));
504 for (int k
=0; k
<firmware
->getCapability(RotaryEncoders
); k
++) {
505 COMPARECELL(modelPrinter
->printRotaryEncoder(i
, k
));
507 columns
.appendRowEnd();
509 columns
.appendTableEnd();
510 str
.append(columns
.print());
516 QString
MultiModelPrinter::printOutputs()
518 QString str
= printTitle(tr("Outputs"));
519 MultiColumns
columns(modelPrinterMap
.size());
520 columns
.appendSectionTableStart();
521 QStringList hd
= QStringList() << tr("Channel") << tr("Subtrim") << tr("Min") << tr("Max") << tr("Direct");
522 if (IS_HORUS_OR_TARANIS(firmware
->getBoard()))
524 if (firmware
->getCapability(PPMCenter
))
526 if (firmware
->getCapability(SYMLimits
))
528 columns
.appendRowHeader(hd
);
530 if (IS_HORUS_OR_TARANIS(firmware
->getBoard()))
532 if (firmware
->getCapability(PPMCenter
))
534 if (firmware
->getCapability(SYMLimits
))
537 for (int i
=0; i
<firmware
->getCapability(Outputs
); i
++) {
539 for (int k
=0; k
< modelPrinterMap
.size(); k
++)
540 count
= std::max(count
, modelPrinterMap
.value(k
).first
->mixes(i
).size());
543 columns
.appendRowStart();
544 columns
.appendCellStart(20, true);
545 COMPARE(modelPrinter
->printChannelName(i
));
546 columns
.appendCellEnd(true);
547 COMPARECELLWIDTH(modelPrinter
->printOutputOffset(i
), wd
);
548 COMPARECELLWIDTH(modelPrinter
->printOutputMin(i
), wd
);
549 COMPARECELLWIDTH(modelPrinter
->printOutputMax(i
), wd
);
550 COMPARECELLWIDTH(modelPrinter
->printOutputRevert(i
), wd
);
551 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
552 COMPARECELLWIDTH(modelPrinter
->printOutputCurve(i
), wd
);
554 if (firmware
->getCapability(PPMCenter
)) {
555 COMPARECELLWIDTH(modelPrinter
->printOutputPpmCenter(i
), wd
);
557 if (firmware
->getCapability(SYMLimits
)) {
558 COMPARECELLWIDTH(modelPrinter
->printOutputSymetrical(i
), wd
);
560 columns
.appendRowEnd();
562 columns
.appendTableEnd();
563 str
.append(columns
.print());
567 QString
MultiModelPrinter::printGvars()
569 QString str
= printTitle(tr("Global Variables"));
570 int gvars
= firmware
->getCapability(Gvars
);
571 MultiColumns
columns(modelPrinterMap
.size());
572 columns
.appendSectionTableStart();
574 for (int i
=0; i
<gvars
; i
++) {
575 hd
<< tr("GV%1").arg(i
+1);
577 columns
.appendRowHeader(hd
);
579 for (int i
=0; i
<gvars
; i
++) {
580 COMPARECELL(model
->flightModeData
[0].gvars
[i
]);
582 columns
.appendRowEnd();
583 columns
.appendTableEnd();
584 str
.append(columns
.print());
588 QString
MultiModelPrinter::printInputs()
590 QString str
= printTitle(tr("Inputs"));
591 MultiColumns
columns(modelPrinterMap
.size());
592 columns
.appendSectionTableStart();
593 for (int i
=0; i
<std::max(4, firmware
->getCapability(VirtualInputs
)); i
++) {
595 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
596 count
= std::max(count
, modelPrinterMap
.value(k
).first
->expos(i
).size());
599 columns
.appendRowStart();
600 columns
.appendCellStart(20, true);
601 COMPARE(modelPrinter
->printInputName(i
));
602 columns
.appendCellEnd(true);
603 columns
.appendCellStart(80);
604 for (int j
=0; j
<count
; j
++) {
606 columns
.appendLineBreak();
607 COMPARE(j
<model
->expos(i
).size() ? modelPrinter
->printInputLine(*model
->expos(i
)[j
]) : "");
609 columns
.appendCellEnd();
610 columns
.appendRowEnd();
613 columns
.appendTableEnd();
614 str
.append(columns
.print());
618 QString
MultiModelPrinter::printMixers()
620 QString str
= printTitle(tr("Mixers"));
621 MultiColumns
columns(modelPrinterMap
.size());
622 columns
.appendSectionTableStart();
623 for (int i
=0; i
<firmware
->getCapability(Outputs
); i
++) {
625 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
626 count
= std::max(count
, modelPrinterMap
.value(k
).first
->mixes(i
).size());
629 columns
.appendRowStart();
630 columns
.appendCellStart(20, true);
631 COMPARE(modelPrinter
->printChannelName(i
));
632 columns
.appendCellEnd(true);
633 columns
.appendCellStart(80);
634 for (int j
=0; j
<count
; j
++) {
636 columns
.appendLineBreak();
637 COMPARE((j
< model
->mixes(i
).size()) ? modelPrinter
->printMixerLine(*model
->mixes(i
)[j
], (j
>0)) : " ");
639 columns
.appendCellEnd();
640 columns
.appendRowEnd();
643 columns
.appendTableEnd();
644 str
.append(columns
.print());
648 QString
MultiModelPrinter::printCurves(QTextDocument
* document
)
651 MultiColumns
columns(modelPrinterMap
.size());
653 columns
.appendSectionTableStart();
654 for (int i
=0; i
<firmware
->getCapability(NumCurves
); i
++) {
655 bool curveEmpty
= true;
656 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
657 if (!modelPrinterMap
.value(k
).first
->curves
[i
].isEmpty()) {
664 columns
.appendRowStart();
665 columns
.appendCellStart(20, true);
666 COMPARE(modelPrinter
->printCurveName(i
));
667 columns
.appendCellEnd(true);
668 COMPARECELL(modelPrinter
->printCurve(i
));
669 columns
.appendRowEnd();
670 columns
.appendRowStart("", 20);
671 columns
.appendCellStart();
672 for (int k
=0; k
< modelPrinterMap
.size(); k
++)
673 columns
.append(k
, QString("<br/><img src='%1' border='0' /><br/>").arg(modelPrinterMap
.value(k
).second
->createCurveImage(i
, document
)));
674 columns
.appendCellEnd();
675 columns
.appendRowEnd();
678 columns
.appendTableEnd();
680 str
.append(printTitle(tr("Curves")));
681 str
.append(columns
.print());
686 QString
MultiModelPrinter::printLogicalSwitches()
689 MultiColumns
columns(modelPrinterMap
.size());
690 columns
.appendSectionTableStart();
692 for (int i
=0; i
<firmware
->getCapability(LogicalSwitches
); i
++) {
694 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
695 if (!modelPrinterMap
.value(k
).first
->logicalSw
[i
].isEmpty()) {
702 columns
.appendRowStart(tr("L%1").arg(i
+1), 20);
703 COMPARECELL(modelPrinter
->printLogicalSwitchLine(i
));
704 columns
.appendRowEnd();
707 columns
.appendTableEnd();
709 str
.append(printTitle(tr("Logical Switches")));
710 str
.append(columns
.print());
715 QString
MultiModelPrinter::printSpecialFunctions()
718 MultiColumns
columns(modelPrinterMap
.size());
720 columns
.appendSectionTableStart();
721 for (int i
=0; i
< firmware
->getCapability(CustomFunctions
); i
++) {
723 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
724 if (!modelPrinterMap
.value(k
).first
->customFn
[i
].isEmpty()) {
731 columns
.appendRowStart(tr("SF%1").arg(i
+1), 20);
732 COMPARECELL(modelPrinter
->printCustomFunctionLine(i
));
733 columns
.appendRowEnd();
736 columns
.appendTableEnd();
738 str
.append(printTitle(tr("Special Functions")));
739 str
.append(columns
.print());
744 QString
MultiModelPrinter::printTelemetry()
746 QString str
= printTitle(tr("Telemetry"));
747 MultiColumns
columns(modelPrinterMap
.size());
748 columns
.appendSectionTableStart();
750 // Analogs on non ARM boards
751 if (!IS_ARM(firmware
->getBoard())) {
752 columns
.appendRowHeader(QStringList() << tr("Analogs") << tr("Unit") << tr("Scale") << tr("Offset"));
753 for (int i
=0; i
<2; i
++) {
754 columns
.appendRowStart(QString("A%1").arg(i
+1), 20);
755 COMPARECELLWIDTH(FrSkyChannelData::unitString(model
->frsky
.channels
[i
].type
), 20);
756 COMPARECELLWIDTH(QString::number((model
->frsky
.channels
[i
].ratio
/ (model
->frsky
.channels
[i
].type
==0 ? 10.0 : 1)), 10, (model
->frsky
.channels
[i
].type
==0 ? 1 : 0)), 20);
757 COMPARECELLWIDTH(QString::number((model
->frsky
.channels
[i
].offset
*(model
->frsky
.channels
[i
].ratio
/ (model
->frsky
.channels
[i
].type
==0 ?10.0 : 1)))/255, 10, (model
->frsky
.channels
[i
].type
==0 ? 1 : 0)), 40);
758 columns
.appendRowEnd();
763 columns
.appendRowStart(tr("Protocol"), 20);
764 COMPARECELL(modelPrinter
->printTelemetryProtocol(model
->telemetryProtocol
));
765 columns
.appendRowEnd();
770 columns
.appendRowStart(tr("RSSI Alarms"), 20);
771 columns
.appendCellStart(80);
772 COMPARESTRING("", (IS_ARM(getCurrentBoard()) ? tr("Low") : FrSkyAlarmData::alarmLevelName(model
->rssiAlarms
.level
[0])), false);
773 columns
.append(": ");
774 COMPARESTRING("", QString("< %1").arg(QString::number(model
->rssiAlarms
.warning
, 10)), true);
775 COMPARESTRING("", (IS_ARM(getCurrentBoard()) ? tr("Critical") : FrSkyAlarmData::alarmLevelName(model
->rssiAlarms
.level
[1])), false);
776 columns
.append(": ");
777 COMPARESTRING("", QString("< %1").arg(QString::number(model
->rssiAlarms
.critical
, 10)), true);
778 COMPARESTRING(tr("Telemetry audio"), modelPrinter
->printRssiAlarmsDisabled(model
->rssiAlarms
.disabled
), false);
779 columns
.appendCellEnd();
780 columns
.appendRowEnd();
784 if (firmware
->getCapability(HasVario
)) {
785 columns
.appendRowStart(tr("Altimetry"), 20);
786 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
787 LABELCOMPARECELL(tr("Vario source"), modelPrinter
->printTelemetrySource(model
->frsky
.varioSource
), 80);
790 LABELCOMPARECELL(tr("Vario source"), modelPrinter
->printVarioSource(model
->frsky
.varioSource
), 80);
792 columns
.appendRowEnd();
793 columns
.appendRowStart("", 20);
794 columns
.appendCellStart(80);
795 columns
.appendTitle(tr("Vario limits >"));
796 if (firmware
->getCapability(HasVarioSink
)) {
797 COMPARESTRING(tr("Sink max"), QString::number(model
->frsky
.varioMin
- 10), true);
798 COMPARESTRING(tr("Sink min"), QString::number((float(model
->frsky
.varioCenterMin
) / 10.0) - 0.5), true);
800 COMPARESTRING(tr("Climb min"), QString::number((float(model
->frsky
.varioCenterMax
) / 10.0) + 0.5), true);
801 COMPARESTRING(tr("Climb max"), QString::number(model
->frsky
.varioMax
+ 10), true);
802 COMPARESTRING(tr("Center silent"), modelPrinter
->printVarioCenterSilent(model
->frsky
.varioCenterSilent
), false);
803 columns
.appendCellEnd();
804 columns
.appendRowEnd();
808 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
809 columns
.appendRowStart(tr("Top Bar"), 20);
810 columns
.appendCellStart(80);
811 COMPARESTRING(tr("Volts source"), modelPrinter
->printTelemetrySource(model
->frsky
.voltsSource
), true);
812 COMPARESTRING(tr("Altitude source"), modelPrinter
->printTelemetrySource(model
->frsky
.altitudeSource
), false);
813 columns
.appendCellEnd();
814 columns
.appendRowEnd();
817 if (IS_ARM(firmware
->getBoard())) {
818 ROWLABELCOMPARECELL("Multi sensors", 0, modelPrinter
->printIgnoreSensorIds(!model
->frsky
.ignoreSensorIds
), 0);
822 if (!IS_ARM(firmware
->getBoard())) {
823 columns
.appendRowHeader(QStringList() << tr("Various"));
824 if (!firmware
->getCapability(NoTelemetryProtocol
)) {
825 columns
.appendRowStart("", 20);
826 LABELCOMPARECELL(tr("Serial protocol"), modelPrinter
->printTelemetrySource(model
->frsky
.voltsSource
), 80);
827 columns
.appendRowEnd();
829 columns
.appendRowStart("", 20);
830 columns
.appendCellStart(80);
831 QString firmware_id
= g
.profile
[g
.id()].fwType();
832 if (firmware
->getCapability(HasFasOffset
) && firmware_id
.contains("fasoffset")) {
833 COMPARESTRING(tr("FAS offset"), QString("%1 A").arg(model
->frsky
.fasOffset
/10.0), true);
835 if (firmware
->getCapability(HasMahPersistent
)) {
836 COMPARESTRING(tr("mAh count"), QString("%1 mAh").arg(model
->frsky
.storedMah
), true);
837 COMPARESTRING(tr("Persistent mAh"), modelPrinter
->printMahPersistent(model
->frsky
.mAhPersistent
), false);
839 columns
.appendRowEnd();
840 columns
.appendRowStart("", 20);
841 columns
.appendCellStart(80);
842 COMPARESTRING(tr("Volts source"), modelPrinter
->printVoltsSource(model
->frsky
.voltsSource
), true);
843 COMPARESTRING(tr("Current source"), modelPrinter
->printCurrentSource(model
->frsky
.currentSource
), false);
844 columns
.appendCellEnd();
845 columns
.appendRowEnd();
846 columns
.appendRowStart("", 20);
847 LABELCOMPARECELL(tr("Blades"), model
->frsky
.blades
, 80);
848 columns
.appendRowEnd();
850 columns
.appendTableEnd();
851 str
.append(columns
.print());
855 QString
MultiModelPrinter::printSensors()
857 MultiColumns
columns(modelPrinterMap
.size());
860 columns
.appendSectionTableStart();
861 columns
.appendRowHeader(QStringList() << tr("Name") << tr("Type") << tr("Parameters"));
862 for (int i
=0; i
<CPN_MAX_SENSORS
; ++i
) {
864 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
865 if (modelPrinterMap
.value(k
).first
->sensorData
[i
].isAvailable()) {
872 columns
.appendRowStart();
873 columns
.appendCellStart(20, true);
874 COMPARE(model
->sensorData
[i
].nameToString(i
));
875 columns
.appendCellEnd(true);
876 COMPARECELLWIDTH(modelPrinter
->printSensorTypeCond(i
), 15);
877 COMPARECELLWIDTH(modelPrinter
->printSensorParams(i
), 65);
878 columns
.appendRowEnd();
881 columns
.appendTableEnd();
883 str
.append(printTitle(tr("Telemetry Sensors")));
884 str
.append(columns
.print());
889 QString
MultiModelPrinter::printTelemetryScreens()
891 MultiColumns
columns(modelPrinterMap
.size());
894 columns
.appendSectionTableStart();
895 for (int i
=0; i
<firmware
->getCapability(TelemetryCustomScreens
); ++i
) {
897 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
898 if (!(modelPrinterMap
.value(k
).first
->frsky
.screens
[i
].type
== TELEMETRY_SCREEN_NONE
)) {
905 columns
.appendRowStart();
906 LABELCOMPARECELL(QString("%1").arg(i
+1), modelPrinter
->printTelemetryScreenType(model
->frsky
.screens
[i
].type
), 20);
907 columns
.appendRowEnd();
908 for (int l
=0; l
<4; l
++) {
909 COMPARE(modelPrinter
->printTelemetryScreen(i
, l
, 80));
913 columns
.appendTableEnd();
915 str
.append(printTitle(tr("Telemetry Screens")));
916 str
.append(columns
.print());