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(HasDisplayText
))
276 str
.append(printChecklist());
277 if (firmware
->getCapability(Timers
)) {
278 str
.append(printTimers());
280 str
.append(printModules());
281 if (firmware
->getCapability(Heli
))
282 str
.append(printHeliSetup());
283 if (firmware
->getCapability(FlightModes
))
284 str
.append(printFlightModes());
285 str
.append(printInputs());
286 str
.append(printMixers());
287 str
.append(printOutputs());
288 str
.append(printCurves(document
));
289 if (firmware
->getCapability(Gvars
) && !firmware
->getCapability(GvarsFlightModes
))
290 str
.append(printGvars());
291 str
.append(printLogicalSwitches());
292 if (firmware
->getCapability(GlobalFunctions
))
293 str
.append(printGlobalFunctions());
294 str
.append(printSpecialFunctions());
295 if (firmware
->getCapability(Telemetry
) & TM_HASTELEMETRY
) {
296 str
.append(printTelemetry());
297 str
.append(printSensors());
298 if (firmware
->getCapability(TelemetryCustomScreens
)) {
299 str
.append(printTelemetryScreens());
302 str
.append("</table>");
306 QString
MultiModelPrinter::printSetup()
308 QString str
= printTitle(tr("General"));
310 MultiColumns
columns(modelPrinterMap
.size());
311 columns
.appendSectionTableStart();
312 ROWLABELCOMPARECELL(tr("Name"), 20, model
->name
, 80);
313 ROWLABELCOMPARECELL(tr("EEprom Size"), 0, modelPrinter
->printEEpromSize(), 0);
314 if (firmware
->getCapability(ModelImage
)) {
315 ROWLABELCOMPARECELL(tr("Model Image"), 0, model
->bitmap
, 0);
317 ROWLABELCOMPARECELL(tr("Throttle"), 0, modelPrinter
->printThrottle(), 0);
318 ROWLABELCOMPARECELL(tr("Trims"), 0, modelPrinter
->printSettingsTrim(), 0);
319 ROWLABELCOMPARECELL(tr("Center Beep"), 0, modelPrinter
->printCenterBeep(), 0);
320 ROWLABELCOMPARECELL(tr("Switch Warnings"), 0, modelPrinter
->printSwitchWarnings(), 0);
321 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
322 ROWLABELCOMPARECELL(tr("Pot Warnings"), 0, modelPrinter
->printPotWarnings(), 0);
324 ROWLABELCOMPARECELL(tr("Other"), 0, modelPrinter
->printSettingsOther(), 0);
325 columns
.appendTableEnd();
326 str
.append(columns
.print());
330 QString
MultiModelPrinter::printTimers()
333 MultiColumns
columns(modelPrinterMap
.size());
334 columns
.appendSectionTableStart();
335 columns
.appendRowHeader(QStringList() << tr("Timers") << tr("Time") << tr("Switch") << tr("Countdown") << tr("Min.call") << tr("Persist"));
337 for (int i
=0; i
<firmware
->getCapability(Timers
); i
++) {
338 columns
.appendRowStart();
339 columns
.appendCellStart(20, true);
340 COMPARE(modelPrinter
->printTimerName(i
));
341 columns
.appendCellEnd(true);
342 COMPARECELLWIDTH(modelPrinter
->printTimerTimeValue(model
->timers
[i
].val
), 15);
343 COMPARECELLWIDTH(model
->timers
[i
].mode
.toString(), 15);
344 COMPARECELLWIDTH(modelPrinter
->printTimerCountdownBeep(model
->timers
[i
].countdownBeep
), 15);
345 COMPARECELLWIDTH(modelPrinter
->printTimerMinuteBeep(model
->timers
[i
].minuteBeep
), 15);
346 COMPARECELLWIDTH(modelPrinter
->printTimerPersistent(model
->timers
[i
].persistent
), 20);
347 columns
.appendRowEnd();
349 columns
.appendTableEnd();
350 str
.append(columns
.print());
354 QString
MultiModelPrinter::printModules()
356 QString str
= printTitle(tr("Modules"));
357 MultiColumns
columns(modelPrinterMap
.size());
358 columns
.appendSectionTableStart();
359 for (int i
=0; i
<firmware
->getCapability(NumModules
); i
++) {
360 columns
.appendRowStart();
361 columns
.appendCellStart(20, true);
362 COMPARE(modelPrinter
->printModuleType(i
));
363 columns
.appendCellEnd(true);
364 COMPARECELLWIDTH(modelPrinter
->printModule(i
), 80);
365 columns
.appendRowEnd();
367 if (firmware
->getCapability(ModelTrainerEnable
))
368 columns
.appendRowStart(tr("Trainer port"));
369 COMPARECELL(modelPrinter
->printModule(-1));
370 columns
.appendRowEnd();
371 columns
.appendTableEnd();
372 str
.append(columns
.print());
376 QString
MultiModelPrinter::printHeliSetup()
378 bool heliEnabled
= false;
379 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
380 heliEnabled
= heliEnabled
|| modelPrinterMap
.value(k
).first
->swashRingData
.type
!= HELI_SWASH_TYPE_NONE
;
386 QString str
= printTitle(tr("Helicopter"));
387 MultiColumns
columns(modelPrinterMap
.size());
388 columns
.appendSectionTableStart();
389 columns
.appendRowStart(tr("Swash"), 20);
390 LABELCOMPARECELL(tr("Type"), modelPrinter
->printHeliSwashType(), 20);
391 LABELCOMPARECELL(tr("Ring"), model
->swashRingData
.value
, 20);
392 columns
.appendRowEnd();
394 columns
.appendRowBlank();
395 columns
.appendRowHeader(QStringList() << "" << tr("Input") << tr("Weight"));
396 columns
.appendRowStart(tr("Long. cyc"));
397 COMPARECELL(model
->swashRingData
.elevatorSource
.toString(model
));
398 COMPARECELL(model
->swashRingData
.elevatorWeight
);
399 columns
.appendRowEnd();
401 columns
.appendRowStart(tr("Lateral cyc"));
402 COMPARECELL(model
->swashRingData
.aileronSource
.toString(model
));
403 COMPARECELL(model
->swashRingData
.aileronWeight
)
404 columns
.appendRowEnd();
406 columns
.appendRowStart(tr("Collective"));
407 COMPARECELL(model
->swashRingData
.collectiveSource
.toString(model
));
408 COMPARECELL(model
->swashRingData
.collectiveWeight
)
409 columns
.appendRowEnd();
411 columns
.appendTableEnd();
412 str
.append(columns
.print());
416 QString
MultiModelPrinter::printFlightModes()
418 QString str
= printTitle(tr("Flight modes"));
421 MultiColumns
columns(modelPrinterMap
.size());
422 columns
.appendSectionTableStart();
423 QStringList hd
= QStringList() << tr("Flight mode") << tr("Switch") << tr("F.In") << tr("F.Out");
424 for (int i
=0; i
< getBoardCapability(getCurrentBoard(), Board::NumTrims
); i
++) {
425 hd
<< RawSource(SOURCE_TYPE_TRIM
, i
).toString();
427 columns
.appendRowHeader(hd
);
428 int wd
= 80/(getBoardCapability(getCurrentBoard(), Board::NumTrims
) + 3);
429 for (int i
=0; i
<firmware
->getCapability(FlightModes
); i
++) {
430 columns
.appendRowStart();
431 columns
.appendCellStart(20,true);
432 COMPARE(modelPrinter
->printFlightModeName(i
));
433 columns
.appendCellEnd(true);
434 COMPARECELLWIDTH(modelPrinter
->printFlightModeSwitch(model
->flightModeData
[i
].swtch
), wd
);
435 COMPARECELLWIDTH(model
->flightModeData
[i
].fadeIn
, wd
);
436 COMPARECELLWIDTH(model
->flightModeData
[i
].fadeOut
, wd
);
437 for (int k
=0; k
< getBoardCapability(getCurrentBoard(), Board::NumTrims
); k
++) {
438 COMPARECELLWIDTH(modelPrinter
->printTrim(i
, k
), wd
);
440 columns
.appendRowEnd();
443 columns
.appendTableEnd();
444 str
.append(columns
.print());
447 // GVars and Rotary Encoders
448 int gvars
= firmware
->getCapability(Gvars
);
449 if ((gvars
&& firmware
->getCapability(GvarsFlightModes
)) || firmware
->getCapability(RotaryEncoders
)) {
450 MultiColumns
columns(modelPrinterMap
.size());
451 columns
.appendSectionTableStart();
452 QStringList hd
= QStringList() << tr("Global vars");
453 if (firmware
->getCapability(GvarsFlightModes
)) {
454 for (int i
=0; i
<gvars
; i
++) {
455 hd
<< tr("GV%1").arg(i
+1);
458 for (int i
=0; i
<firmware
->getCapability(RotaryEncoders
); i
++) {
459 hd
<< tr("RE%1").arg(i
+1);
461 columns
.appendRowHeader(hd
);
463 if (firmware
->getCapability(GvarsFlightModes
)) {
464 columns
.appendRowStart(tr("Name"), 20);
465 for (int i
=0; i
<gvars
; i
++) {
466 COMPARECELLWIDTH(model
->gvarData
[i
].name
, wd
);
468 columns
.appendRowEnd();
469 columns
.appendRowStart(tr("Unit"));
470 for (int i
=0; i
<gvars
; i
++) {
471 COMPARECELL(modelPrinter
->printGlobalVarUnit(i
));
473 columns
.appendRowEnd();
474 columns
.appendRowStart(tr("Prec"));
475 for (int i
=0; i
<gvars
; i
++) {
476 COMPARECELL(modelPrinter
->printGlobalVarPrec(i
));
478 columns
.appendRowEnd();
479 columns
.appendRowStart(tr("Min"));
480 for (int i
=0; i
<gvars
; i
++) {
481 COMPARECELL(modelPrinter
->printGlobalVarMin(i
));
483 columns
.appendRowEnd();
484 columns
.appendRowStart(tr("Max"));
485 for (int i
=0; i
<gvars
; i
++) {
486 COMPARECELL(modelPrinter
->printGlobalVarMax(i
));
488 columns
.appendRowEnd();
489 columns
.appendRowStart(tr("Popup"));
490 for (int i
=0; i
<gvars
; i
++) {
491 COMPARECELL(modelPrinter
->printGlobalVarPopup(i
));
493 columns
.appendRowEnd();
496 columns
.appendRowHeader(QStringList() << tr("Flight mode"));
498 for (int i
=0; i
<firmware
->getCapability(FlightModes
); i
++) {
499 columns
.appendRowStart();
500 columns
.appendCellStart(0,true);
501 COMPARE(modelPrinter
->printFlightModeName(i
));
502 columns
.appendCellEnd(true);
503 if (firmware
->getCapability(GvarsFlightModes
)) {
504 for (int k
=0; k
<gvars
; k
++) {
505 COMPARECELL(modelPrinter
->printGlobalVar(i
, k
));
508 for (int k
=0; k
<firmware
->getCapability(RotaryEncoders
); k
++) {
509 COMPARECELL(modelPrinter
->printRotaryEncoder(i
, k
));
511 columns
.appendRowEnd();
513 columns
.appendTableEnd();
514 str
.append(columns
.print());
520 QString
MultiModelPrinter::printOutputs()
522 QString str
= printTitle(tr("Outputs"));
523 MultiColumns
columns(modelPrinterMap
.size());
524 columns
.appendSectionTableStart();
525 QStringList hd
= QStringList() << tr("Channel") << tr("Subtrim") << tr("Min") << tr("Max") << tr("Direct");
526 if (IS_HORUS_OR_TARANIS(firmware
->getBoard()))
528 if (firmware
->getCapability(PPMCenter
))
530 if (firmware
->getCapability(SYMLimits
))
532 columns
.appendRowHeader(hd
);
534 if (IS_HORUS_OR_TARANIS(firmware
->getBoard()))
536 if (firmware
->getCapability(PPMCenter
))
538 if (firmware
->getCapability(SYMLimits
))
541 for (int i
=0; i
<firmware
->getCapability(Outputs
); i
++) {
543 for (int k
=0; k
< modelPrinterMap
.size(); k
++)
544 count
= std::max(count
, modelPrinterMap
.value(k
).first
->mixes(i
).size());
547 columns
.appendRowStart();
548 columns
.appendCellStart(20, true);
549 COMPARE(modelPrinter
->printChannelName(i
));
550 columns
.appendCellEnd(true);
551 COMPARECELLWIDTH(modelPrinter
->printOutputOffset(i
), wd
);
552 COMPARECELLWIDTH(modelPrinter
->printOutputMin(i
), wd
);
553 COMPARECELLWIDTH(modelPrinter
->printOutputMax(i
), wd
);
554 COMPARECELLWIDTH(modelPrinter
->printOutputRevert(i
), wd
);
555 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
556 COMPARECELLWIDTH(modelPrinter
->printOutputCurve(i
), wd
);
558 if (firmware
->getCapability(PPMCenter
)) {
559 COMPARECELLWIDTH(modelPrinter
->printOutputPpmCenter(i
), wd
);
561 if (firmware
->getCapability(SYMLimits
)) {
562 COMPARECELLWIDTH(modelPrinter
->printOutputSymetrical(i
), wd
);
564 columns
.appendRowEnd();
566 columns
.appendTableEnd();
567 str
.append(columns
.print());
571 QString
MultiModelPrinter::printGvars()
573 QString str
= printTitle(tr("Global Variables"));
574 int gvars
= firmware
->getCapability(Gvars
);
575 MultiColumns
columns(modelPrinterMap
.size());
576 columns
.appendSectionTableStart();
578 for (int i
=0; i
<gvars
; i
++) {
579 hd
<< tr("GV%1").arg(i
+1);
581 columns
.appendRowHeader(hd
);
583 for (int i
=0; i
<gvars
; i
++) {
584 COMPARECELL(model
->flightModeData
[0].gvars
[i
]);
586 columns
.appendRowEnd();
587 columns
.appendTableEnd();
588 str
.append(columns
.print());
592 QString
MultiModelPrinter::printInputs()
594 QString str
= printTitle(tr("Inputs"));
595 MultiColumns
columns(modelPrinterMap
.size());
596 columns
.appendSectionTableStart();
597 for (int i
=0; i
<std::max(4, firmware
->getCapability(VirtualInputs
)); i
++) {
599 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
600 count
= std::max(count
, modelPrinterMap
.value(k
).first
->expos(i
).size());
603 columns
.appendRowStart();
604 columns
.appendCellStart(20, true);
605 COMPARE(modelPrinter
->printInputName(i
));
606 columns
.appendCellEnd(true);
607 columns
.appendCellStart(80);
608 for (int j
=0; j
<count
; j
++) {
610 columns
.appendLineBreak();
611 COMPARE(j
<model
->expos(i
).size() ? modelPrinter
->printInputLine(*model
->expos(i
)[j
]) : "");
613 columns
.appendCellEnd();
614 columns
.appendRowEnd();
617 columns
.appendTableEnd();
618 str
.append(columns
.print());
622 QString
MultiModelPrinter::printMixers()
624 QString str
= printTitle(tr("Mixers"));
625 MultiColumns
columns(modelPrinterMap
.size());
626 columns
.appendSectionTableStart();
627 for (int i
=0; i
<firmware
->getCapability(Outputs
); i
++) {
629 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
630 count
= std::max(count
, modelPrinterMap
.value(k
).first
->mixes(i
).size());
633 columns
.appendRowStart();
634 columns
.appendCellStart(20, true);
635 COMPARE(modelPrinter
->printChannelName(i
));
636 columns
.appendCellEnd(true);
637 columns
.appendCellStart(80);
638 for (int j
=0; j
<count
; j
++) {
640 columns
.appendLineBreak();
641 COMPARE((j
< model
->mixes(i
).size()) ? modelPrinter
->printMixerLine(*model
->mixes(i
)[j
], (j
>0)) : " ");
643 columns
.appendCellEnd();
644 columns
.appendRowEnd();
647 columns
.appendTableEnd();
648 str
.append(columns
.print());
652 QString
MultiModelPrinter::printCurves(QTextDocument
* document
)
655 MultiColumns
columns(modelPrinterMap
.size());
657 columns
.appendSectionTableStart();
658 for (int i
=0; i
<firmware
->getCapability(NumCurves
); i
++) {
659 bool curveEmpty
= true;
660 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
661 if (!modelPrinterMap
.value(k
).first
->curves
[i
].isEmpty()) {
668 columns
.appendRowStart();
669 columns
.appendCellStart(20, true);
670 COMPARE(modelPrinter
->printCurveName(i
));
671 columns
.appendCellEnd(true);
672 COMPARECELL(modelPrinter
->printCurve(i
));
673 columns
.appendRowEnd();
674 columns
.appendRowStart("", 20);
675 columns
.appendCellStart();
676 for (int k
=0; k
< modelPrinterMap
.size(); k
++)
677 columns
.append(k
, QString("<br/><img src='%1' border='0' /><br/>").arg(modelPrinterMap
.value(k
).second
->createCurveImage(i
, document
)));
678 columns
.appendCellEnd();
679 columns
.appendRowEnd();
682 columns
.appendTableEnd();
684 str
.append(printTitle(tr("Curves")));
685 str
.append(columns
.print());
690 QString
MultiModelPrinter::printLogicalSwitches()
693 MultiColumns
columns(modelPrinterMap
.size());
694 columns
.appendSectionTableStart();
696 for (int i
=0; i
<firmware
->getCapability(LogicalSwitches
); i
++) {
698 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
699 if (!modelPrinterMap
.value(k
).first
->logicalSw
[i
].isEmpty()) {
706 columns
.appendRowStart(tr("L%1").arg(i
+1), 20);
707 COMPARECELL(modelPrinter
->printLogicalSwitchLine(i
));
708 columns
.appendRowEnd();
711 columns
.appendTableEnd();
713 str
.append(printTitle(tr("Logical Switches")));
714 str
.append(columns
.print());
719 QString
MultiModelPrinter::printSpecialFunctions()
722 MultiColumns
columns(modelPrinterMap
.size());
724 columns
.appendSectionTableStart();
725 for (int i
=0; i
< firmware
->getCapability(CustomFunctions
); i
++) {
727 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
728 if (!modelPrinterMap
.value(k
).first
->customFn
[i
].isEmpty()) {
735 columns
.appendRowStart(tr("SF%1").arg(i
+1), 20);
736 COMPARECELL(modelPrinter
->printCustomFunctionLine(i
));
737 columns
.appendRowEnd();
740 columns
.appendTableEnd();
742 str
.append(printTitle(tr("Special Functions")));
743 str
.append(columns
.print());
748 QString
MultiModelPrinter::printTelemetry()
750 QString str
= printTitle(tr("Telemetry"));
751 MultiColumns
columns(modelPrinterMap
.size());
752 columns
.appendSectionTableStart();
754 // Analogs on non ARM boards
755 if (!IS_ARM(firmware
->getBoard())) {
756 columns
.appendRowHeader(QStringList() << tr("Analogs") << tr("Unit") << tr("Scale") << tr("Offset"));
757 for (int i
=0; i
<2; i
++) {
758 columns
.appendRowStart(QString("A%1").arg(i
+1), 20);
759 COMPARECELLWIDTH(FrSkyChannelData::unitString(model
->frsky
.channels
[i
].type
), 20);
760 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);
761 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);
762 columns
.appendRowEnd();
767 columns
.appendRowStart(tr("Protocol"), 20);
768 COMPARECELL(modelPrinter
->printTelemetryProtocol(model
->telemetryProtocol
));
769 columns
.appendRowEnd();
774 columns
.appendRowStart(tr("RSSI Alarms"), 20);
775 columns
.appendCellStart(80);
776 COMPARESTRING("", (IS_ARM(getCurrentBoard()) ? tr("Low") : FrSkyAlarmData::alarmLevelName(model
->rssiAlarms
.level
[0])), false);
777 columns
.append(": ");
778 COMPARESTRING("", QString("< %1").arg(QString::number(model
->rssiAlarms
.warning
, 10)), true);
779 COMPARESTRING("", (IS_ARM(getCurrentBoard()) ? tr("Critical") : FrSkyAlarmData::alarmLevelName(model
->rssiAlarms
.level
[1])), false);
780 columns
.append(": ");
781 COMPARESTRING("", QString("< %1").arg(QString::number(model
->rssiAlarms
.critical
, 10)), true);
782 COMPARESTRING(tr("Telemetry audio"), modelPrinter
->printRssiAlarmsDisabled(model
->rssiAlarms
.disabled
), false);
783 columns
.appendCellEnd();
784 columns
.appendRowEnd();
788 if (firmware
->getCapability(HasVario
)) {
789 columns
.appendRowStart(tr("Altimetry"), 20);
790 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
791 LABELCOMPARECELL(tr("Vario source"), modelPrinter
->printTelemetrySource(model
->frsky
.varioSource
), 80);
794 LABELCOMPARECELL(tr("Vario source"), modelPrinter
->printVarioSource(model
->frsky
.varioSource
), 80);
796 columns
.appendRowEnd();
797 columns
.appendRowStart("", 20);
798 columns
.appendCellStart(80);
799 columns
.appendTitle(tr("Vario limits >"));
800 if (firmware
->getCapability(HasVarioSink
)) {
801 COMPARESTRING(tr("Sink max"), QString::number(model
->frsky
.varioMin
- 10), true);
802 COMPARESTRING(tr("Sink min"), QString::number((float(model
->frsky
.varioCenterMin
) / 10.0) - 0.5), true);
804 COMPARESTRING(tr("Climb min"), QString::number((float(model
->frsky
.varioCenterMax
) / 10.0) + 0.5), true);
805 COMPARESTRING(tr("Climb max"), QString::number(model
->frsky
.varioMax
+ 10), true);
806 COMPARESTRING(tr("Center silent"), modelPrinter
->printVarioCenterSilent(model
->frsky
.varioCenterSilent
), false);
807 columns
.appendCellEnd();
808 columns
.appendRowEnd();
812 if (IS_HORUS_OR_TARANIS(firmware
->getBoard())) {
813 columns
.appendRowStart(tr("Top Bar"), 20);
814 columns
.appendCellStart(80);
815 COMPARESTRING(tr("Volts source"), modelPrinter
->printTelemetrySource(model
->frsky
.voltsSource
), true);
816 COMPARESTRING(tr("Altitude source"), modelPrinter
->printTelemetrySource(model
->frsky
.altitudeSource
), false);
817 columns
.appendCellEnd();
818 columns
.appendRowEnd();
821 if (IS_ARM(firmware
->getBoard())) {
822 ROWLABELCOMPARECELL("Multi sensors", 0, modelPrinter
->printIgnoreSensorIds(!model
->frsky
.ignoreSensorIds
), 0);
826 if (!IS_ARM(firmware
->getBoard())) {
827 columns
.appendRowHeader(QStringList() << tr("Various"));
828 if (!firmware
->getCapability(NoTelemetryProtocol
)) {
829 columns
.appendRowStart("", 20);
830 LABELCOMPARECELL(tr("Serial protocol"), modelPrinter
->printTelemetrySource(model
->frsky
.voltsSource
), 80);
831 columns
.appendRowEnd();
833 columns
.appendRowStart("", 20);
834 columns
.appendCellStart(80);
835 QString firmware_id
= g
.profile
[g
.id()].fwType();
836 if (firmware
->getCapability(HasFasOffset
) && firmware_id
.contains("fasoffset")) {
837 COMPARESTRING(tr("FAS offset"), QString("%1 A").arg(model
->frsky
.fasOffset
/10.0), true);
839 if (firmware
->getCapability(HasMahPersistent
)) {
840 COMPARESTRING(tr("mAh count"), QString("%1 mAh").arg(model
->frsky
.storedMah
), true);
841 COMPARESTRING(tr("Persistent mAh"), modelPrinter
->printMahPersistent(model
->frsky
.mAhPersistent
), false);
843 columns
.appendRowEnd();
844 columns
.appendRowStart("", 20);
845 columns
.appendCellStart(80);
846 COMPARESTRING(tr("Volts source"), modelPrinter
->printVoltsSource(model
->frsky
.voltsSource
), true);
847 COMPARESTRING(tr("Current source"), modelPrinter
->printCurrentSource(model
->frsky
.currentSource
), false);
848 columns
.appendCellEnd();
849 columns
.appendRowEnd();
850 columns
.appendRowStart("", 20);
851 LABELCOMPARECELL(tr("Blades"), model
->frsky
.blades
, 80);
852 columns
.appendRowEnd();
854 columns
.appendTableEnd();
855 str
.append(columns
.print());
859 QString
MultiModelPrinter::printSensors()
861 MultiColumns
columns(modelPrinterMap
.size());
864 columns
.appendSectionTableStart();
865 columns
.appendRowHeader(QStringList() << tr("Name") << tr("Type") << tr("Parameters"));
866 for (unsigned i
=0; i
<CPN_MAX_SENSORS
; ++i
) {
868 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
869 if (modelPrinterMap
.value(k
).first
->sensorData
[i
].isAvailable()) {
876 columns
.appendRowStart();
877 columns
.appendCellStart(20, true);
878 COMPARE(model
->sensorData
[i
].nameToString(i
));
879 columns
.appendCellEnd(true);
880 COMPARECELLWIDTH(modelPrinter
->printSensorTypeCond(i
), 15);
881 COMPARECELLWIDTH(modelPrinter
->printSensorParams(i
), 65);
882 columns
.appendRowEnd();
885 columns
.appendTableEnd();
887 str
.append(printTitle(tr("Telemetry Sensors")));
888 str
.append(columns
.print());
893 QString
MultiModelPrinter::printTelemetryScreens()
895 MultiColumns
columns(modelPrinterMap
.size());
898 columns
.appendSectionTableStart();
899 for (int i
=0; i
<firmware
->getCapability(TelemetryCustomScreens
); ++i
) {
901 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
902 if (!(modelPrinterMap
.value(k
).first
->frsky
.screens
[i
].type
== TELEMETRY_SCREEN_NONE
)) {
909 columns
.appendRowStart();
910 LABELCOMPARECELL(QString("%1").arg(i
+1), modelPrinter
->printTelemetryScreenType(model
->frsky
.screens
[i
].type
), 20);
911 columns
.appendRowEnd();
912 for (int l
=0; l
<4; l
++) {
913 COMPARE(modelPrinter
->printTelemetryScreen(i
, l
, 80));
917 columns
.appendTableEnd();
919 str
.append(printTitle(tr("Telemetry Screens")));
920 str
.append(columns
.print());
925 QString
MultiModelPrinter::printGlobalFunctions()
931 MultiColumns
columns(modelPrinterMap
.size());
932 columns
.appendSectionTableStart();
934 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
935 if (!modelPrinterMap
.value(k
).first
->noGlobalFunctions
) {
942 ModelPrinter
* modelPrinter
= modelPrinterMap
.value(idx
).second
;
943 (void)(modelPrinter
);
945 for (int i
=0; i
< firmware
->getCapability(GlobalFunctions
); i
++) {
946 txt
= modelPrinter
->printCustomFunctionLine(i
, true);
947 if (!txt
.isEmpty()) {
949 ROWLABELCOMPARECELL(tr("GF%1").arg(i
+1), 20, modelPrinter
->printCustomFunctionLine(i
, true), 80);
952 columns
.appendTableEnd();
954 str
.append(printTitle(tr("Global Functions")));
955 str
.append(columns
.print());
961 QString
MultiModelPrinter::printChecklist()
964 MultiColumns
columns(modelPrinterMap
.size());
965 bool isChecklist
= false;
966 for (int k
=0; k
< modelPrinterMap
.size(); k
++) {
967 if (modelPrinterMap
.value(k
).first
->displayChecklist
) {
973 columns
.appendSectionTableStart();
974 ROWLABELCOMPARECELL(tr("Checklist"), 20, modelPrinter
->printChecklist(), 80);
975 columns
.appendTableEnd();
976 str
.append(columns
.print());