@@ -7,6 +7,7 @@
|
||||
<option name="FUNCTION_BRACE_PLACEMENT" value="2" />
|
||||
<option name="SUPERCLASS_LIST_BEFORE_COLON" value="0" />
|
||||
<option name="SPACE_AFTER_POINTER_IN_DECLARATION" value="true" />
|
||||
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
||||
</Objective-C>
|
||||
<codeStyleSettings language="CMake">
|
||||
<option name="SPACE_BEFORE_IF_PARENTHESES" value="false" />
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
||||
@@ -16,6 +16,8 @@ addons:
|
||||
- libmpc3
|
||||
- libfox-1.6-dev
|
||||
- libgtest-dev
|
||||
- lib32stdc++6
|
||||
- libclang-common-6.0-dev
|
||||
- clang-6.0
|
||||
- python3-pip
|
||||
|
||||
@@ -44,6 +46,8 @@ before_install:
|
||||
- sudo ln -s /opt/gcc-arm-none-eabi/bin/arm-none-eabi-size /usr/bin/arm-none-eabi-size
|
||||
- sudo apt-get install --yes --force-yes -qq qt${QT_BASE}base qt${QT_BASE}multimedia qt${QT_BASE}svg qt${QT_BASE}tools; source /opt/qt${QT_BASE}/bin/qt${QT_BASE}-env.sh
|
||||
- sudo ln -sf /usr/bin/python3 /usr/bin/python
|
||||
- python3 -m pip install pip==20.3.3
|
||||
- sudo apt-get install python3-setuptools
|
||||
- python3 -m pip install pillow clang
|
||||
|
||||
script:
|
||||
|
||||
@@ -2,11 +2,11 @@ project(OpenTX)
|
||||
|
||||
set(VERSION_MAJOR "2")
|
||||
set(VERSION_MINOR "3")
|
||||
set(VERSION_REVISION "10")
|
||||
set(VERSION_REVISION "12")
|
||||
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
|
||||
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
|
||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})
|
||||
set(SDCARD_REVISION "0029")
|
||||
set(SDCARD_REVISION "0036")
|
||||
set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[Main developers]
|
||||
Bertrand Songis (bsongis)
|
||||
André Bernet (kilrah)
|
||||
JC D. (3djc)
|
||||
Michael Blandford
|
||||
Damjan Adamic (projectkk2glider)
|
||||
Franck Aguerre (jivarofad)
|
||||
@@ -9,6 +10,7 @@ Martin Hotař (mhotar)
|
||||
Maxim (Max) Paperno (mpaperno)
|
||||
Arne Schwabe (schwabe)
|
||||
Daniel Gorbea (dgatf)
|
||||
Neil Horne (elecpower)
|
||||
|
||||
[Translators]
|
||||
[fr] Sebastien Charpentier (LapinFou)
|
||||
@@ -32,6 +34,7 @@ Michael Byrne
|
||||
<a href="https://www.flysky-cn.com/home">FlySky (monthly)</a>
|
||||
<a href="https://www.jumper-rc.com">JumperRC (monthly)</a>
|
||||
<a href="https://www.radiomasterrc.com">RadioMaster (monthly)</a>
|
||||
<a href="http://www.happymodel.cn">HappyModel (monthly)</a>
|
||||
<a href="https://alofthobbies.com">Aloft Hobbies</a>
|
||||
<a href="https://jonathan.it">Jonathan Modellismo</a>
|
||||
<a href="http://wstech.de">WsTech</a>
|
||||
@@ -1838,3 +1841,400 @@ Laurence Gerrard
|
||||
Nico Wagner
|
||||
Christoph Rössner
|
||||
Ruben Flores
|
||||
Jim Cukla
|
||||
Lee Taylor
|
||||
Stefan Kuster
|
||||
Barry Wright
|
||||
Steven Gilley
|
||||
Lloyd Evans
|
||||
Nolan O'Hearne
|
||||
Jeffrey James N Buffie
|
||||
James Houck
|
||||
Andreas Arlt
|
||||
William Walker
|
||||
Salvador Munoz Vinas
|
||||
Chris Geiger Photography
|
||||
John F Smith
|
||||
Robert Zecha
|
||||
Fernando Martins
|
||||
Martin Brungard
|
||||
Paul Witko
|
||||
Michael Campbell
|
||||
Stuart Posnett
|
||||
PK Doddema
|
||||
Leonard MacKey
|
||||
Andrew Peterson
|
||||
Dominik Sedlacek
|
||||
Ronald Hellstern
|
||||
Vicente Suarez
|
||||
Patrick Geerts
|
||||
Rossi Giampaolo
|
||||
Jose Luis Franco Torres
|
||||
Bart Sillen
|
||||
Antonio Moreno
|
||||
Carolina Carcione
|
||||
Lonnie Misner
|
||||
John Eppling
|
||||
Phillip Elliott
|
||||
Robin Bayer
|
||||
Jurij Peternel
|
||||
George Aandahl
|
||||
Guy Dangerfield
|
||||
Thomas Limpert
|
||||
Ismael G Zapater
|
||||
Alan Hall
|
||||
Bradley Goodwin
|
||||
Paul Dittman
|
||||
John Johnson
|
||||
Liam Mahoney
|
||||
Joseph Carr
|
||||
Fiorenzo Agnelli
|
||||
Brian Ramsey
|
||||
Angelo Movio
|
||||
Weldon Parks
|
||||
Simon Brink
|
||||
Weldon Parks
|
||||
Ralf Herzenbruch
|
||||
Ashley Pearce
|
||||
SneakIT
|
||||
Soaring Stuff
|
||||
Jörg Lemnitz
|
||||
Johann Gross
|
||||
Mark Gibson
|
||||
Rendall Assoc
|
||||
Cozyn Holdings Pty Ltd
|
||||
Tim Karsten
|
||||
Nick Hesson
|
||||
Laurent Lapassade
|
||||
Peter Deacon
|
||||
Gilles Dando
|
||||
Philippe Desrichard
|
||||
Jón Haase
|
||||
Michael Hansen
|
||||
Sylvain Vanston
|
||||
Helmut Nemecek
|
||||
Alexander Mathis
|
||||
Jay Watkins
|
||||
Patrice Oudjaoudi
|
||||
Didier Hochedez
|
||||
Robert Hunter
|
||||
Christophe Gilsoul
|
||||
Lincoln Roberts
|
||||
Johan Jurriens
|
||||
Michael Ledward
|
||||
Dave Waldesbuehl
|
||||
Dale Rhoads
|
||||
Denis Kelly
|
||||
SBEurope LTD
|
||||
Jean-Louis Mouche
|
||||
Grant Mills
|
||||
Fernando Rimoldi
|
||||
Jim Cukla
|
||||
Tomas Kirnak
|
||||
Raymond Henderson
|
||||
James Jewitt
|
||||
Martin Sauter
|
||||
Philip Hawkey
|
||||
Lonnie Misner
|
||||
Michael Hirschauer
|
||||
Brian Bracken
|
||||
Stuart Olson
|
||||
Terry McKinley
|
||||
Miklos Turcsin
|
||||
Edward Skerness
|
||||
Stefano Perinetti
|
||||
Toni Marchante
|
||||
Stuart Olson
|
||||
Peter Campbell
|
||||
Keith Wood
|
||||
Leo Duflou
|
||||
Michael Florey
|
||||
Gerhard Weixelbaumer
|
||||
Peter K Lehotsky
|
||||
Elisha Jones
|
||||
Joerg Sattler
|
||||
paul42
|
||||
Pascal Heg
|
||||
Bjorn Sorenssen
|
||||
Chris Payne
|
||||
Pascal Afflard
|
||||
Robert Boboryko
|
||||
Chris Whitehead
|
||||
David Bradley
|
||||
Ian Lever
|
||||
Phillip Barber
|
||||
Jan Bronee
|
||||
N Haasnoot
|
||||
Rick Smith
|
||||
Randall Grant
|
||||
Patrick Degouy
|
||||
Piotr Zdanowski
|
||||
David Gardner
|
||||
TMac FPV
|
||||
Bernard Thompson
|
||||
Mark Sutton
|
||||
Darren J Crane
|
||||
Michael Keyes
|
||||
Magnus Borg
|
||||
David Lorentzen
|
||||
Antony Smith
|
||||
Aleksandr Sarkisov
|
||||
Johannes Kuhne
|
||||
Kathleen Cilluffo
|
||||
David Hoffmann
|
||||
Alan Porter
|
||||
Arlé Mooldijk
|
||||
Tenbones
|
||||
Kim Bitsch Lauridsen
|
||||
Arthur Costerus
|
||||
Peter Harvey
|
||||
John Simpson
|
||||
Landy de los Santos
|
||||
Graham Ridley
|
||||
Schenk Peter
|
||||
Joseph Rex
|
||||
Richard Honeywell
|
||||
Roy Nixon
|
||||
Andrew Shewan
|
||||
David Bradley
|
||||
Alan Micklethwaite
|
||||
Susan Siegel
|
||||
Stephen Evans
|
||||
William Hallman
|
||||
Franck Michel
|
||||
László Gajcsi (monthly)
|
||||
Danny Koch
|
||||
Robert Martin
|
||||
Gavin Meerwald
|
||||
Frédéric Maix
|
||||
Frank Steinberg
|
||||
Kevin Berkefeld
|
||||
Marccos Colon
|
||||
Kerry Reynolds
|
||||
Kim Jeppesen
|
||||
Arthur Peters
|
||||
Andrew Lowes
|
||||
Anthony Hallo
|
||||
Bill Hill
|
||||
Gerard Falaise
|
||||
Kevin Raynor
|
||||
Lorenzo gh
|
||||
Jan Landeweer
|
||||
David Bland
|
||||
Manuel Spoerri
|
||||
Jeff Jacobs
|
||||
David Thorne
|
||||
Maddox Philip
|
||||
James Jewitt
|
||||
Justin Digby
|
||||
John Magnuson (monthly)
|
||||
Holger Lippert
|
||||
Hubert Huber
|
||||
David Blum
|
||||
Noam Kfir
|
||||
Mats gårdstad friberg
|
||||
Jesper Frickmann
|
||||
Alan Bunker
|
||||
Emanuel Kircher
|
||||
Barry Andersen
|
||||
Gabriel Formanek
|
||||
Timothy Justiniano
|
||||
Kelvin Garcia Urbina
|
||||
Jan Lau
|
||||
Choon Wei Jonathan Tan
|
||||
Daniel Navas
|
||||
Ray Moss
|
||||
Markus Frielingsdorf
|
||||
Michael Hirschauer
|
||||
Jesse Frey
|
||||
Philipp Koch
|
||||
Robert Rubio
|
||||
Dennis G Miller
|
||||
Leonardo Garcia Osuna
|
||||
Antonio Carrasco Pastor
|
||||
Musa Pinar
|
||||
Jens Moder
|
||||
Josef de Beer
|
||||
Chad Mofford
|
||||
Pim Pouw
|
||||
Kenth Jonsson
|
||||
Gordon Westfall
|
||||
Jean-Michel Saves
|
||||
Roberto Orsello
|
||||
Luboš Konvalinka
|
||||
Lawrence Dorn
|
||||
Michael Dittmann
|
||||
Bernd Schmiedel
|
||||
Raoul Piccioli
|
||||
Uwe Probst
|
||||
Glendon Satchell
|
||||
Trevor Collins
|
||||
Horst Grashauser
|
||||
Miguel José Cárdenas Herrera
|
||||
Mike Jennings
|
||||
José Bernardo
|
||||
Carlos Dangle
|
||||
Gordon Evans
|
||||
Pablo Peinado Abad
|
||||
Carl Payne
|
||||
Adam Sosnowski
|
||||
Гасак Сергей
|
||||
SaltCtyRacingFPV
|
||||
Georg Bernhardt
|
||||
James Mildenhall
|
||||
Dave Plummer
|
||||
Ivan Mokris
|
||||
Patrick Daniels
|
||||
Stuart Olson
|
||||
Cory Znebel
|
||||
Andrey Yarovoy
|
||||
Christian Pons
|
||||
Burt Pickard-Richardson
|
||||
Michal Mesaros
|
||||
Conrad Young
|
||||
Martin Mathes
|
||||
Jens Rainer Hansen
|
||||
Mark Trible
|
||||
Marc Dubois
|
||||
Alan Wilkins
|
||||
Daniel Hryciuk
|
||||
Thomas Fox
|
||||
Sidney B Harden
|
||||
Augustas Sereika
|
||||
David Belletete
|
||||
Karl-Heinz Behn
|
||||
Lena Hjort
|
||||
Jan Langhorst
|
||||
Alberto Scotti
|
||||
John Rock
|
||||
Adam Kouse
|
||||
Ricardo Martins
|
||||
Noel Irwin
|
||||
Christoph Rausch
|
||||
Anthony Hrabusicky
|
||||
Sergio Tondini
|
||||
Aldo Visentin
|
||||
Greg Wilson
|
||||
Mark Sutton
|
||||
Lukas Kana
|
||||
Peter Newman
|
||||
Kevin Cave
|
||||
Arold Reinders
|
||||
Jason Plant
|
||||
John Beech
|
||||
Ian Parris
|
||||
Danny Music
|
||||
Eric Bissonnette
|
||||
Riso LTD
|
||||
William Booth
|
||||
Ferenc Kunkli
|
||||
Offer Shmuely
|
||||
Troy Atneosen
|
||||
Long Technologies
|
||||
John Jaugilas
|
||||
Jan-Hinrich Klee
|
||||
Hans-Reinhard Mette
|
||||
Alejandro Casals Oliver
|
||||
David Homewood
|
||||
John Dunning
|
||||
Konrad Helbach
|
||||
Bernard Delpy
|
||||
Raymond Ellsworth
|
||||
Bogdan Musial
|
||||
Гасак Сергей
|
||||
Philip Garcia
|
||||
Helder Simoes
|
||||
Thomas Blanchin
|
||||
Jean-Luc Mesnier
|
||||
Michael Bajer
|
||||
David Homewood
|
||||
Marc Sanders
|
||||
Буров Александр
|
||||
Rudy T'Jolleyn
|
||||
Jay Watkins
|
||||
Blaz Vodopivec
|
||||
David De Salvo
|
||||
Willem Verschoren
|
||||
Dennis Kathrens
|
||||
Alan Aucote
|
||||
Richard Jerome Danstrom
|
||||
David Garcia-Mendia
|
||||
Mark Jones
|
||||
John Zseleczky
|
||||
Xiao Sun
|
||||
Glenn Harvey
|
||||
Albrecht Friebel
|
||||
Gunter Klemke
|
||||
Travis McCarthy
|
||||
Franz Zier
|
||||
Ian Contessa
|
||||
Sean Sadler
|
||||
Richard F Janczak
|
||||
Mateusz Dziadosz
|
||||
Thomas Merchant
|
||||
M L Perkins
|
||||
Stefano Boggia
|
||||
Новоселов Юрий
|
||||
James Rhodes
|
||||
Peter Gaskill
|
||||
Jacques Temey
|
||||
Anthony Challis
|
||||
Gerard Falaise
|
||||
George McGinnis
|
||||
Antoine Soulie
|
||||
Tjeerd Jager
|
||||
Bertold Van den Bergh
|
||||
Stefanie Zerbe
|
||||
James Mandelbaum
|
||||
Javier J. Cordovez
|
||||
Jess Barkley
|
||||
Schneider Modell
|
||||
Michael Hasselgaard
|
||||
Thomas Young
|
||||
Непочатов Алексей
|
||||
Thomas Goebel
|
||||
Joseph Macias
|
||||
Paw Melin-Nielsen
|
||||
Liam O'Brien
|
||||
Ronald B Backman
|
||||
Corvus Inspection Services Inc
|
||||
Stuart Posnett
|
||||
Clark Emerick
|
||||
Helmut Sippel
|
||||
Jhon Lennon Silva do Nascimento
|
||||
Peter McCarthy
|
||||
Bob Brown
|
||||
Claude Lawyer
|
||||
Peter Fithern
|
||||
Michael Hoffman
|
||||
Tim Smith
|
||||
OpenSki Institute
|
||||
Simon Melov
|
||||
Richard Podolsky
|
||||
James Wilson
|
||||
John Norrbin
|
||||
James Goins
|
||||
Phillip Nguyen
|
||||
Jeffrey M Engel
|
||||
Richard Marotto
|
||||
Greg Bell
|
||||
Scott Geer
|
||||
Thomas Abshier
|
||||
Ernst Camenzind
|
||||
Radomir Sterba
|
||||
Ignacio Barrio
|
||||
Bradley Murchie
|
||||
Emmanuel Balintec
|
||||
Rowell Torres
|
||||
Christopher Kokis
|
||||
Ken Bryan
|
||||
Eric Yoder
|
||||
Olav Roth
|
||||
Rowell Torres
|
||||
Christopher Kokis
|
||||
Ken Bryan
|
||||
Glenn Noonan
|
||||
Michael Jakob
|
||||
Dean Berg
|
||||
David Hankins
|
||||
Gary Cripps
|
||||
|
||||
@@ -343,6 +343,12 @@ if(PCB STREQUAL X7 AND PCBREV STREQUAL ACCESS)
|
||||
set(FLAVOUR x7access)
|
||||
elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T12)
|
||||
set(FLAVOUR t12)
|
||||
elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TLITE)
|
||||
set(FLAVOUR tlite)
|
||||
elseif(PCB STREQUAL X7 AND PCBREV STREQUAL TX12)
|
||||
set(FLAVOUR tx12)
|
||||
elseif(PCB STREQUAL X7 AND PCBREV STREQUAL T8)
|
||||
set(FLAVOUR t8)
|
||||
elseif(PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019)
|
||||
set(FLAVOUR x9d+2019)
|
||||
elseif(PCB STREQUAL X10 AND PCBREV STREQUAL EXPRESS)
|
||||
@@ -513,6 +519,8 @@ IF(APPLE)
|
||||
# Use a non standard Info.plist that adds Retina support flags
|
||||
set_target_properties(${COMPANION_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/companion/targets/mac/MacOSXBundleInfo.plist.in)
|
||||
set_target_properties(${SIMULATOR_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/companion/targets/mac/MacOSXBundleInfo.plist.in)
|
||||
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.opentx.companion")
|
||||
|
||||
INSTALL(TARGETS ${COMPANION_NAME}
|
||||
BUNDLE DESTINATION . COMPONENT Runtime
|
||||
|
||||
@@ -179,6 +179,39 @@
|
||||
<file>images/simulator/JumperT12/JumperT12-x.png</file>
|
||||
<file>images/simulator/JumperT12/JumperT12-center.png</file>
|
||||
<file>images/simulator/JumperT12/JumperT12-top.png</file>
|
||||
<file>images/simulator/JumperTLITE/bottom.png</file>
|
||||
<file>images/simulator/JumperTLITE/bottom_right.png</file>
|
||||
<file>images/simulator/JumperTLITE/bottom_left.png</file>
|
||||
<file>images/simulator/JumperTLITE/left.png</file>
|
||||
<file>images/simulator/JumperTLITE/left_top.png</file>
|
||||
<file>images/simulator/JumperTLITE/left_bottom.png</file>
|
||||
<file>images/simulator/JumperTLITE/right.png</file>
|
||||
<file>images/simulator/JumperTLITE/right_top.png</file>
|
||||
<file>images/simulator/JumperTLITE/right_bottom.png</file>
|
||||
<file>images/simulator/JumperTLITE/top.png</file>
|
||||
<file>images/simulator/TX12/left.png</file>
|
||||
<file>images/simulator/TX12/left-pageup.png</file>
|
||||
<file>images/simulator/TX12/left-pagedn.png</file>
|
||||
<file>images/simulator/TX12/left-rtn.png</file>
|
||||
<file>images/simulator/TX12/left-sys.png</file>
|
||||
<file>images/simulator/TX12/left-tele.png</file>
|
||||
<file>images/simulator/TX12/right.png</file>
|
||||
<file>images/simulator/TX12/right-ent.png</file>
|
||||
<file>images/simulator/TX12/right-mdl.png</file>
|
||||
<file>images/simulator/TX12/bottom.png</file>
|
||||
<file>images/simulator/TX12/top.png</file>
|
||||
<file>images/simulator/T8/left.png</file>
|
||||
<file>images/simulator/T8/left-pageup.png</file>
|
||||
<file>images/simulator/T8/left-pagedn.png</file>
|
||||
<file>images/simulator/T8/left-rtn.png</file>
|
||||
<file>images/simulator/T8/left-sys.png</file>
|
||||
<file>images/simulator/T8/right.png</file>
|
||||
<file>images/simulator/T8/right-ent.png</file>
|
||||
<file>images/simulator/T8/right-mdl.png</file>
|
||||
<file>images/simulator/T8/right-up.png</file>
|
||||
<file>images/simulator/T8/right-dn.png</file>
|
||||
<file>images/simulator/T8/bottom.png</file>
|
||||
<file>images/simulator/T8/top.png</file>
|
||||
<file>images/simulator/JumperT16/left.png</file>
|
||||
<file>images/simulator/JumperT16/right.png</file>
|
||||
<file>images/simulator/JumperT16/top.png</file>
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#define CPN_STR_APP_SETTINGS_FILTER CPN_STR_APP_SETTINGS_FILES % " (*.ini)"
|
||||
|
||||
#define CPN_STR_UNKNOWN_ITEM "???"
|
||||
#define CPN_STR_NONE_ITEM "----"
|
||||
|
||||
#define CPN_STR_SW_INDICATOR_UP QCoreApplication::translate("RawSwitch", "\xE2\x86\x91") // Switch up position indicator: Up arrow, or similar.
|
||||
#define CPN_STR_SW_INDICATOR_DN QCoreApplication::translate("RawSwitch", "\xE2\x86\x93") // Switch down position indicator: Down arrow, or similar.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
|
||||
set(datamodels_SRCS
|
||||
rawitemdatamodels.cpp
|
||||
rawitemfilteredmodel.cpp
|
||||
compounditemmodels.cpp
|
||||
filtereditemmodels.cpp
|
||||
)
|
||||
|
||||
set(datamodels_HDRS
|
||||
rawitemdatamodels.h
|
||||
rawitemfilteredmodel.h
|
||||
compounditemmodels.h
|
||||
filtereditemmodels.h
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(datamodels_SRCS ${datamodels_HDRS})
|
||||
|
||||
@@ -0,0 +1,758 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "compounditemmodels.h"
|
||||
#include "generalsettings.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "modeldata.h"
|
||||
#include "adjustmentreference.h"
|
||||
|
||||
// static
|
||||
QString AbstractItemModel::idToString(const int value)
|
||||
{
|
||||
switch (value) {
|
||||
case IMID_Unknown:
|
||||
return "Unknown";
|
||||
case IMID_RawSource:
|
||||
return "RawSource";
|
||||
case IMID_RawSwitch:
|
||||
return "RawSwitch";
|
||||
case IMID_Curve:
|
||||
return "Curve";
|
||||
case IMID_GVarRef:
|
||||
return "GVarRef";
|
||||
case IMID_ThrSource:
|
||||
return "ThrSource";
|
||||
case IMID_CustomFuncAction:
|
||||
return "CustomFuncAction";
|
||||
case IMID_CustomFuncResetParam:
|
||||
return "CustomFuncResetParam";
|
||||
case IMID_TeleSource:
|
||||
return "TeleSource";
|
||||
case IMID_RssiSource:
|
||||
return "RssiSource";
|
||||
case IMID_CurveRefType:
|
||||
return "CurveRefType";
|
||||
case IMID_CurveRefFunc:
|
||||
return "CurveRefFunc";
|
||||
default:
|
||||
return "Custom";
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void AbstractItemModel::dumpItemModelContents(AbstractItemModel * itemModel)
|
||||
{
|
||||
if (itemModel) {
|
||||
qDebug() << "id:" << itemModel->getId() << "name:" << itemModel->getName();
|
||||
|
||||
for (int i = 0; i < itemModel->rowCount(); ++i) {
|
||||
qDebug() << "row:" << i
|
||||
<< "text:" << itemModel->data(itemModel->index(i, 0), Qt::DisplayRole).toString()
|
||||
<< "id:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Id).toInt()
|
||||
<< "avail:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Available).toBool()
|
||||
<< "flags:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Flags).toInt()
|
||||
<< "type:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Type).toInt();
|
||||
}
|
||||
}
|
||||
else
|
||||
qDebug() << "Error: model not of class AbstractItemModel";
|
||||
}
|
||||
|
||||
//
|
||||
// AbstractStaticItemModel
|
||||
//
|
||||
|
||||
void AbstractStaticItemModel::loadItemList()
|
||||
{
|
||||
foreach (const ListItem *item, itemList) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setText(item->text);
|
||||
modelItem->setData(item->id, IMDR_Id);
|
||||
modelItem->setData(item->type, IMDR_Type);
|
||||
modelItem->setData(item->flags, IMDR_Flags);
|
||||
modelItem->setData(item->isAvailable, IMDR_Available);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
|
||||
itemList.clear();
|
||||
};
|
||||
|
||||
//
|
||||
// RawSourceItemModel
|
||||
//
|
||||
|
||||
RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_RawSource);
|
||||
setUpdateMask(IMUE_All &~ (IMUE_Curves | IMUE_Scripts));
|
||||
|
||||
addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1);
|
||||
for (int i = 0; i < firmware->getCapability(LuaScripts); i++)
|
||||
addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, firmware->getCapability(LuaOutputsPerScript), i * 16);
|
||||
addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, firmware->getCapability(VirtualInputs));
|
||||
addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board->getCapability(Board::MaxAnalogs));
|
||||
addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board->getCapability(Board::NumTrims));
|
||||
addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1);
|
||||
addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board->getCapability(Board::Switches));
|
||||
addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, firmware->getCapability(LogicalSwitches));
|
||||
addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC);
|
||||
addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, firmware->getCapability(TrainerInputs));
|
||||
addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, firmware->getCapability(Outputs));
|
||||
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5);
|
||||
addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, firmware->getCapability(Sensors) * 3);
|
||||
addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, firmware->getCapability(Gvars));
|
||||
}
|
||||
|
||||
void RawSourceItemModel::setDynamicItemData(QStandardItem * item, const RawSource & src) const
|
||||
{
|
||||
item->setText(src.toString(modelData, generalSettings, boardType));
|
||||
item->setData(src.isAvailable(modelData, generalSettings, boardType), IMDR_Available);
|
||||
}
|
||||
|
||||
void RawSourceItemModel::addItems(const RawSourceType & type, const int group, const int count, const int start)
|
||||
{
|
||||
for (int i = start; i < start + count; i++) {
|
||||
const RawSource src = RawSource(type, i);
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(src.toValue(), IMDR_Id);
|
||||
modelItem->setData(type, IMDR_Type);
|
||||
modelItem->setData(group, IMDR_Flags);
|
||||
setDynamicItemData(modelItem, src);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RawSourceItemModel::update(const int event)
|
||||
{
|
||||
if (doUpdate(event)) {
|
||||
emit aboutToBeUpdated();
|
||||
|
||||
for (int i = 0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), RawSource(item(i)->data(IMDR_Id).toInt()));
|
||||
|
||||
emit updateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// RawSwitchItemModel
|
||||
//
|
||||
|
||||
RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_RawSwitch);
|
||||
setUpdateMask(IMUE_FlightModes | IMUE_LogicalSwitches | IMUE_TeleSensors);
|
||||
|
||||
// Descending switch direction: NOT (!) switches
|
||||
addItems(SWITCH_TYPE_ACT, -1);
|
||||
addItems(SWITCH_TYPE_SENSOR, -firmware->getCapability(Sensors));
|
||||
addItems(SWITCH_TYPE_TELEMETRY, -1);
|
||||
addItems(SWITCH_TYPE_FLIGHT_MODE, -firmware->getCapability(FlightModes));
|
||||
addItems(SWITCH_TYPE_VIRTUAL, -firmware->getCapability(LogicalSwitches));
|
||||
addItems(SWITCH_TYPE_TRIM, -board->getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, -(board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions)));
|
||||
addItems(SWITCH_TYPE_SWITCH, -board->getCapability(Board::SwitchPositions));
|
||||
|
||||
// Ascending switch direction (including zero)
|
||||
addItems(SWITCH_TYPE_TIMER_MODE, 5);
|
||||
addItems(SWITCH_TYPE_NONE, 1);
|
||||
addItems(SWITCH_TYPE_SWITCH, board->getCapability(Board::SwitchPositions));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, board->getCapability(Board::MultiposPots) * board->getCapability(Board::MultiposPotsPositions));
|
||||
addItems(SWITCH_TYPE_TRIM, board->getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_VIRTUAL, firmware->getCapability(LogicalSwitches));
|
||||
addItems(SWITCH_TYPE_FLIGHT_MODE, firmware->getCapability(FlightModes));
|
||||
addItems(SWITCH_TYPE_TELEMETRY, 1);
|
||||
addItems(SWITCH_TYPE_SENSOR, firmware->getCapability(Sensors));
|
||||
addItems(SWITCH_TYPE_ON, 1);
|
||||
addItems(SWITCH_TYPE_ONE, 1);
|
||||
addItems(SWITCH_TYPE_ACT, 1);
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const
|
||||
{
|
||||
item->setText(rsw.toString(boardType, generalSettings, modelData));
|
||||
item->setData(rsw.isAvailable(modelData, generalSettings, boardType), IMDR_Available);
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::addItems(const RawSwitchType & type, int count)
|
||||
{
|
||||
// Most RawSwitch() indices are one-based (vs. typical zero); these are exceptions to the rule:
|
||||
const static QVector<int> rawSwitchIndexBaseZeroTypes = QVector<int>() << SWITCH_TYPE_NONE << SWITCH_TYPE_ON << SWITCH_TYPE_OFF << SWITCH_TYPE_TIMER_MODE;
|
||||
// handle exceptions in RawSwitch() index values
|
||||
const short rawIdxAdj = rawSwitchIndexBaseZeroTypes.contains(type) ? -1 : 0;
|
||||
|
||||
// determine cotext flags
|
||||
int context = RawSwitch::AllSwitchContexts;
|
||||
switch (type) {
|
||||
case SWITCH_TYPE_FLIGHT_MODE:
|
||||
context &= ~RawSwitch::MixesContext;
|
||||
// fallthrough
|
||||
case SWITCH_TYPE_VIRTUAL:
|
||||
case SWITCH_TYPE_SENSOR:
|
||||
context &= ~RawSwitch::GlobalFunctionsContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_TIMER_MODE:
|
||||
context = RawSwitch::TimersContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_NONE:
|
||||
context &= ~RawSwitch::TimersContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_ON:
|
||||
case SWITCH_TYPE_ONE:
|
||||
context = RawSwitch::SpecialFunctionsContext | RawSwitch::GlobalFunctionsContext;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int i = (count < 0 ? count : 1);
|
||||
count = (i < 0 ? 0 : count + i);
|
||||
for ( ; i < count; ++i) {
|
||||
RawSwitch rs(type, i + rawIdxAdj);
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(rs.toValue(), IMDR_Id);
|
||||
modelItem->setData(type, IMDR_Type);
|
||||
modelItem->setData(context, IMDR_Flags);
|
||||
setDynamicItemData(modelItem, rs);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::update(const int event)
|
||||
{
|
||||
if (doUpdate(event)) {
|
||||
emit aboutToBeUpdated();
|
||||
|
||||
for (int i = 0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), RawSwitch(item(i)->data(IMDR_Id).toInt()));
|
||||
|
||||
emit updateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CurveItemModel
|
||||
//
|
||||
|
||||
CurveItemModel::CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_Curve);
|
||||
|
||||
if (!modelData)
|
||||
return;
|
||||
|
||||
setUpdateMask(IMUE_Curves);
|
||||
|
||||
const int count = firmware->getCapability(NumCurves);
|
||||
|
||||
for (int i = -count ; i <= count; ++i) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(i, IMDR_Id);
|
||||
modelItem->setData(i < 0 ? IMDG_Negative : i > 0 ? IMDG_Positive : IMDG_None, IMDR_Flags);
|
||||
setDynamicItemData(modelItem, i);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void CurveItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
||||
{
|
||||
CurveReference cr = CurveReference(CurveReference::CURVE_REF_CUSTOM, value);
|
||||
item->setText(cr.toString(modelData, false));
|
||||
item->setData(cr.isAvailable(), IMDR_Available);
|
||||
}
|
||||
|
||||
void CurveItemModel::update(const int event)
|
||||
{
|
||||
if (doUpdate(event)) {
|
||||
emit aboutToBeUpdated();
|
||||
|
||||
for (int i = 0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
|
||||
|
||||
emit updateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// GVarReferenceItemModel
|
||||
//
|
||||
|
||||
GVarReferenceItemModel::GVarReferenceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_GVarRef);
|
||||
|
||||
if (!modelData)
|
||||
return;
|
||||
|
||||
setUpdateMask(IMUE_GVars | IMUE_FlightModes | IMUE_LogicalSwitches);
|
||||
|
||||
const int count = firmware->getCapability(Gvars);
|
||||
|
||||
if (count > 0) {
|
||||
addItems(-count);
|
||||
addItems(count);
|
||||
}
|
||||
}
|
||||
|
||||
void GVarReferenceItemModel::addItems(int count)
|
||||
{
|
||||
int i = (count < 0 ? count : 1);
|
||||
count = (i < 0 ? 0 : count + i);
|
||||
for ( ; i < count; ++i) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
AdjustmentReference ar(AdjustmentReference::ADJUST_REF_GVAR, i);
|
||||
modelItem->setData(ar.toValue(), IMDR_Id);
|
||||
modelItem->setData(i < 0 ? IMDG_Negative : i > 0 ? IMDG_Positive : IMDG_None, IMDR_Flags);
|
||||
setDynamicItemData(modelItem, ar);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void GVarReferenceItemModel::setDynamicItemData(QStandardItem * item, const AdjustmentReference & ar) const
|
||||
{
|
||||
item->setText(ar.toString(modelData, false));
|
||||
item->setData(ar.isAvailable(), IMDR_Available);
|
||||
}
|
||||
|
||||
void GVarReferenceItemModel::update(const int event)
|
||||
{
|
||||
if (doUpdate(event)) {
|
||||
emit aboutToBeUpdated();
|
||||
|
||||
for (int i = 0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), AdjustmentReference(item(i)->data(IMDR_Id).toInt()));
|
||||
|
||||
emit updateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// ThrottleSourceItemModel
|
||||
//
|
||||
|
||||
ThrottleSourceItemModel::ThrottleSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_ThrSource);
|
||||
|
||||
if (!modelData)
|
||||
return;
|
||||
|
||||
setUpdateMask(IMUE_Timers | IMUE_Inputs | IMUE_TeleSensors);
|
||||
|
||||
for (int i = 0; i < modelData->thrTraceSrcCount(); i++) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(i, IMDR_Id);
|
||||
setDynamicItemData(modelItem, i);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void ThrottleSourceItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
||||
{
|
||||
item->setText(modelData->thrTraceSrcToString(value));
|
||||
item->setData(modelData->isThrTraceSrcAvailable(generalSettings, value), IMDR_Available);
|
||||
}
|
||||
|
||||
void ThrottleSourceItemModel::update(const int event)
|
||||
{
|
||||
if (doUpdate(event)) {
|
||||
emit aboutToBeUpdated();
|
||||
|
||||
for (int i = 0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
|
||||
|
||||
emit updateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CustomFuncActionItemModel
|
||||
//
|
||||
|
||||
CustomFuncActionItemModel::CustomFuncActionItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_CustomFuncAction);
|
||||
setUpdateMask(IMUE_All &~ (IMUE_Curves | IMUE_Scripts));
|
||||
|
||||
for (int i = 0; i < AssignFunc::FuncCount; i++) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(i, IMDR_Id);
|
||||
modelItem->setData(CustomFunctionData::funcContext(i), IMDR_Flags);
|
||||
setDynamicItemData(modelItem, i);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFuncActionItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
||||
{
|
||||
item->setText(CustomFunctionData::funcToString((AssignFunc)value, modelData));
|
||||
item->setData(CustomFunctionData::isFuncAvailable(value), IMDR_Available);
|
||||
}
|
||||
|
||||
void CustomFuncActionItemModel::update(const int event)
|
||||
{
|
||||
if (doUpdate(event)) {
|
||||
emit aboutToBeUpdated();
|
||||
|
||||
for (int i = 0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
|
||||
|
||||
emit updateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CustomFuncResetParamItemModel
|
||||
//
|
||||
|
||||
CustomFuncResetParamItemModel::CustomFuncResetParamItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_CustomFuncResetParam);
|
||||
setUpdateMask(IMUE_TeleSensors | IMUE_Timers);
|
||||
|
||||
for (int i = 0; i < CustomFunctionData::resetParamCount(); i++) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(i, IMDR_Id);
|
||||
setDynamicItemData(modelItem, i);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFuncResetParamItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
||||
{
|
||||
item->setText(CustomFunctionData::resetToString(value, modelData));
|
||||
item->setData(CustomFunctionData::isResetParamAvailable(value, modelData), IMDR_Available);
|
||||
}
|
||||
|
||||
void CustomFuncResetParamItemModel::update(const int event)
|
||||
{
|
||||
if (doUpdate(event)) {
|
||||
emit aboutToBeUpdated();
|
||||
|
||||
for (int i = 0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
|
||||
|
||||
emit updateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TelemetrySourceItemModel
|
||||
//
|
||||
|
||||
TelemetrySourceItemModel::TelemetrySourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_TeleSource);
|
||||
|
||||
if (!modelData)
|
||||
return;
|
||||
|
||||
setUpdateMask(IMUE_TeleSensors | IMUE_Modules);
|
||||
const int count = firmware->getCapability(Sensors);
|
||||
|
||||
for (int i = -count; i <= count; ++i) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(i, IMDR_Id);
|
||||
modelItem->setData(i < 0 ? IMDG_Negative : i > 0 ? IMDG_Positive : IMDG_None, IMDR_Flags);
|
||||
setDynamicItemData(modelItem, i);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void TelemetrySourceItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
||||
{
|
||||
item->setText(SensorData::sourceToString(modelData, value));
|
||||
item->setData(SensorData::isSourceAvailable(modelData, value), IMDR_Available);
|
||||
}
|
||||
|
||||
void TelemetrySourceItemModel::update(const int event)
|
||||
{
|
||||
if (doUpdate(event)) {
|
||||
emit aboutToBeUpdated();
|
||||
|
||||
for (int i = 0; i < rowCount(); ++i) {
|
||||
setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
|
||||
}
|
||||
|
||||
emit updateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// RssiSourceItemModel
|
||||
//
|
||||
|
||||
RssiSourceItemModel::RssiSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractDynamicItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_RssiSource);
|
||||
|
||||
if (!modelData)
|
||||
return;
|
||||
|
||||
setUpdateMask(IMUE_TeleSensors | IMUE_Modules);
|
||||
|
||||
for (int i = 0; i <= firmware->getCapability(Sensors); ++i) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(i, IMDR_Id);
|
||||
modelItem->setData(i < 0 ? IMDG_Negative : i > 0 ? IMDG_Positive : IMDG_None, IMDR_Flags);
|
||||
setDynamicItemData(modelItem, i);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RssiSourceItemModel::setDynamicItemData(QStandardItem * item, const int value) const
|
||||
{
|
||||
item->setText(SensorData::rssiSensorToString(modelData, value));
|
||||
item->setData(SensorData::isRssiSensorAvailable(modelData, value), IMDR_Available);
|
||||
}
|
||||
|
||||
void RssiSourceItemModel::update(const int event)
|
||||
{
|
||||
if (doUpdate(event)) {
|
||||
emit aboutToBeUpdated();
|
||||
|
||||
for (int i = 0; i < rowCount(); ++i) {
|
||||
setDynamicItemData(item(i), item(i)->data(IMDR_Id).toInt());
|
||||
}
|
||||
|
||||
emit updateComplete();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CurveRefTypeItemModel
|
||||
//
|
||||
|
||||
CurveRefTypeItemModel::CurveRefTypeItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractStaticItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_CurveRefType);
|
||||
|
||||
for (int i = 0; i <= CurveReference::MAX_CURVE_REF_TYPE; i++) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setText(CurveReference::typeToString((CurveReference::CurveRefType)i));
|
||||
modelItem->setData(i, IMDR_Id);
|
||||
modelItem->setData(CurveReference::isTypeAvailable((CurveReference::CurveRefType)i), IMDR_Available);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CurveRefFuncItemModel
|
||||
//
|
||||
|
||||
CurveRefFuncItemModel::CurveRefFuncItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractStaticItemModel(generalSettings, modelData, firmware, board, boardType)
|
||||
{
|
||||
setId(IMID_CurveRefFunc);
|
||||
|
||||
for (int i = 1; i <= CurveReference::functionCount(); i++) {
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setText(CurveReference::functionToString(i));
|
||||
modelItem->setData(i, IMDR_Id);
|
||||
modelItem->setData(CurveReference::isFunctionAvailable(i), IMDR_Available);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// PrecisionItemModel
|
||||
//
|
||||
|
||||
PrecisionItemModel::PrecisionItemModel(const int minDecimals, const int maxDecimals, const QString suffix, const bool placeholders) :
|
||||
AbstractStaticItemModel()
|
||||
{
|
||||
for (int i = minDecimals, j = maxDecimals; j >= 0; i++, j--) {
|
||||
QString str = QString("0.%1").arg(QString(i, '0'));
|
||||
if (placeholders)
|
||||
str.append(QString(j, '_'));
|
||||
if (!suffix.isEmpty())
|
||||
str.append(QString(" %1").arg(suffix));
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setText(str);
|
||||
modelItem->setData(i, IMDR_Id);
|
||||
modelItem->setData(true, IMDR_Available);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CompoundItemModelFactory
|
||||
//
|
||||
|
||||
CompoundItemModelFactory::CompoundItemModelFactory(const GeneralSettings * const generalSettings, const ModelData * const modelData) :
|
||||
generalSettings(generalSettings),
|
||||
modelData(modelData)
|
||||
{
|
||||
firmware = getCurrentFirmware();
|
||||
board = new Boards(getCurrentBoard());
|
||||
boardType = getCurrentBoard();
|
||||
}
|
||||
|
||||
CompoundItemModelFactory::~CompoundItemModelFactory()
|
||||
{
|
||||
unregisterItemModels();
|
||||
delete board;
|
||||
}
|
||||
|
||||
void CompoundItemModelFactory::addItemModel(const int id)
|
||||
{
|
||||
switch (id) {
|
||||
case AbstractItemModel::IMID_RawSource:
|
||||
registerItemModel(new RawSourceItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_RawSwitch:
|
||||
registerItemModel(new RawSwitchItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_Curve:
|
||||
registerItemModel(new CurveItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_GVarRef:
|
||||
registerItemModel(new GVarReferenceItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_ThrSource:
|
||||
registerItemModel(new ThrottleSourceItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_CustomFuncAction:
|
||||
registerItemModel(new CustomFuncActionItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_CustomFuncResetParam:
|
||||
registerItemModel(new CustomFuncResetParamItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_TeleSource:
|
||||
registerItemModel(new TelemetrySourceItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_RssiSource:
|
||||
registerItemModel(new RssiSourceItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_CurveRefType:
|
||||
registerItemModel(new CurveRefTypeItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
case AbstractItemModel::IMID_CurveRefFunc:
|
||||
registerItemModel(new CurveRefFuncItemModel(generalSettings, modelData, firmware, board, boardType));
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Error: unknown item model: id";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int CompoundItemModelFactory::registerItemModel(AbstractItemModel * itemModel)
|
||||
{
|
||||
if (itemModel) {
|
||||
if (!isItemModelRegistered(itemModel->getId())) {
|
||||
setSourceId(itemModel);
|
||||
registeredItemModels.append(itemModel);
|
||||
return itemModel->getId();
|
||||
}
|
||||
else
|
||||
return itemModel->getId();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CompoundItemModelFactory::unregisterItemModels()
|
||||
{
|
||||
foreach (AbstractItemModel *itemModel, registeredItemModels) {
|
||||
delete itemModel;
|
||||
}
|
||||
}
|
||||
|
||||
void CompoundItemModelFactory::unregisterItemModel(const int id)
|
||||
{
|
||||
AbstractItemModel * itemModel = getItemModel(id);
|
||||
if (itemModel)
|
||||
delete itemModel;
|
||||
}
|
||||
|
||||
AbstractItemModel * CompoundItemModelFactory::getItemModel(const int id) const
|
||||
{
|
||||
foreach (AbstractItemModel * itemModel, registeredItemModels) {
|
||||
if (itemModel->getId() == id)
|
||||
return itemModel;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AbstractItemModel * CompoundItemModelFactory::getItemModel(const QString name) const
|
||||
{
|
||||
foreach (AbstractItemModel * itemModel, registeredItemModels) {
|
||||
if (itemModel->getName() == name)
|
||||
return itemModel;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CompoundItemModelFactory::isItemModelRegistered(const int id) const
|
||||
{
|
||||
foreach (AbstractItemModel * itemModel, registeredItemModels) {
|
||||
if (itemModel->getId() == id)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CompoundItemModelFactory::update(const int event)
|
||||
{
|
||||
foreach (AbstractItemModel * itemModel, registeredItemModels) {
|
||||
itemModel->update(event);
|
||||
}
|
||||
}
|
||||
|
||||
void CompoundItemModelFactory::dumpAllItemModelContents() const
|
||||
{
|
||||
foreach (AbstractItemModel * itemModel, registeredItemModels) {
|
||||
AbstractItemModel::dumpItemModelContents(itemModel);
|
||||
}
|
||||
}
|
||||
|
||||
void CompoundItemModelFactory::setSourceId(AbstractItemModel * itemModel)
|
||||
{
|
||||
if (itemModel && itemModel->getId() == AbstractItemModel::IMID_Unknown)
|
||||
itemModel->setId(AbstractItemModel::IMID_ReservedCount + registeredItemModels.count());
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rawsource.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QStandardItemModel>
|
||||
|
||||
class GeneralSettings;
|
||||
class ModelData;
|
||||
class AdjustmentReference;
|
||||
|
||||
class AbstractItemModel: public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum ItemModelId {
|
||||
IMID_Unknown,
|
||||
IMID_RawSource,
|
||||
IMID_RawSwitch,
|
||||
IMID_Curve,
|
||||
IMID_GVarRef,
|
||||
IMID_ThrSource,
|
||||
IMID_CustomFuncAction,
|
||||
IMID_CustomFuncResetParam,
|
||||
IMID_TeleSource,
|
||||
IMID_RssiSource,
|
||||
IMID_CurveRefType,
|
||||
IMID_CurveRefFunc,
|
||||
IMID_ReservedCount,
|
||||
IMID_Custom
|
||||
};
|
||||
Q_ENUM(ItemModelId)
|
||||
|
||||
enum ItemModelDataRoles {
|
||||
IMDR_Id = Qt::UserRole,
|
||||
IMDR_Type,
|
||||
IMDR_Flags,
|
||||
IMDR_Available
|
||||
};
|
||||
Q_ENUM(ItemModelDataRoles)
|
||||
|
||||
enum ItemModelDataGroups {
|
||||
IMDG_None = 0x01,
|
||||
IMDG_Negative = 0x02,
|
||||
IMDG_Positive = 0x04
|
||||
};
|
||||
Q_ENUM(ItemModelDataGroups)
|
||||
|
||||
enum ItemModelUpdateEvent {
|
||||
IMUE_None = 0,
|
||||
IMUE_SystemRefresh = 1 << 0,
|
||||
IMUE_Channels = 1 << 1,
|
||||
IMUE_Curves = 1 << 2,
|
||||
IMUE_FlightModes = 1 << 3,
|
||||
IMUE_GVars = 1 << 4,
|
||||
IMUE_Inputs = 1 << 5,
|
||||
IMUE_LogicalSwitches = 1 << 6,
|
||||
IMUE_Scripts = 1 << 7,
|
||||
IMUE_TeleSensors = 1 << 8,
|
||||
IMUE_Timers = 1 << 9,
|
||||
IMUE_Modules = 1 << 10,
|
||||
IMUE_All = IMUE_SystemRefresh | IMUE_Channels | IMUE_Curves | IMUE_FlightModes | IMUE_GVars | IMUE_Inputs |
|
||||
IMUE_LogicalSwitches | IMUE_Scripts | IMUE_TeleSensors | IMUE_Timers | IMUE_Modules
|
||||
};
|
||||
Q_ENUM(ItemModelUpdateEvent)
|
||||
|
||||
explicit AbstractItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
QStandardItemModel(nullptr),
|
||||
generalSettings(generalSettings),
|
||||
modelData(modelData),
|
||||
firmware(firmware),
|
||||
board(board),
|
||||
boardType(boardType),
|
||||
m_id(IMID_Unknown),
|
||||
m_name(""),
|
||||
m_updateMask(IMUE_None)
|
||||
{}
|
||||
|
||||
virtual ~AbstractItemModel() {}
|
||||
|
||||
void setId(int id) { m_id = id; }
|
||||
int getId () const { return m_id; }
|
||||
bool isReservedModelId() const { return m_id > IMID_Unknown && m_id < IMID_ReservedCount; }
|
||||
void setName(QString name) { m_name = name; }
|
||||
QString getName() const { return isReservedModelId() ? idToString(m_id) : m_name; }
|
||||
void setUpdateMask(const int mask) { m_updateMask = mask; }
|
||||
int getUpdateMask() const { return m_updateMask; }
|
||||
|
||||
inline bool doUpdate(const int event) const { return m_updateMask & event; }
|
||||
|
||||
AbstractItemModel * getItemModel(const int id) const;
|
||||
|
||||
static void dumpItemModelContents(AbstractItemModel * itemModel);
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) = 0;
|
||||
|
||||
protected:
|
||||
const GeneralSettings * generalSettings;
|
||||
const ModelData * modelData;
|
||||
Firmware * firmware;
|
||||
const Boards * board;
|
||||
const Board::Type boardType;
|
||||
|
||||
private:
|
||||
int m_id = IMID_Unknown;
|
||||
QString m_name = "";
|
||||
int m_updateMask = IMUE_None;
|
||||
|
||||
static QString idToString(const int value);
|
||||
};
|
||||
|
||||
class AbstractStaticItemModel: public AbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AbstractStaticItemModel(const GeneralSettings * const generalSettings = nullptr, const ModelData * const modelData = nullptr,
|
||||
Firmware * firmware = nullptr, const Boards * const board = nullptr,
|
||||
const Board::Type boardType = Board::BOARD_UNKNOWN) :
|
||||
AbstractItemModel(generalSettings, modelData, firmware, board, boardType) {}
|
||||
virtual ~AbstractStaticItemModel() {};
|
||||
|
||||
inline void appendToItemList(QString text, int id, bool isAvailable = true, int type = 0, int flags = 0)
|
||||
{ itemList.append(new ListItem(text, id, isAvailable, type, flags)); }
|
||||
|
||||
void loadItemList();
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event) override final {}
|
||||
|
||||
protected:
|
||||
struct ListItem
|
||||
{
|
||||
QString text;
|
||||
int id;
|
||||
bool isAvailable;
|
||||
int type;
|
||||
int flags;
|
||||
|
||||
ListItem() {}
|
||||
ListItem(QString p_text, int p_id, bool p_isAvailable, int p_type, int p_flags) :
|
||||
text(p_text), id(p_id), isAvailable(p_isAvailable), type(p_type), flags(p_flags) {}
|
||||
};
|
||||
|
||||
QVector<ListItem *> itemList;
|
||||
};
|
||||
|
||||
class AbstractDynamicItemModel: public AbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AbstractDynamicItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType) :
|
||||
AbstractItemModel(generalSettings, modelData, firmware, board, boardType) {}
|
||||
virtual ~AbstractDynamicItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) {}
|
||||
|
||||
signals:
|
||||
void aboutToBeUpdated();
|
||||
void updateComplete();
|
||||
};
|
||||
|
||||
class RawSourceItemModel: public AbstractDynamicItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~RawSourceItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||
|
||||
protected:
|
||||
virtual void setDynamicItemData(QStandardItem * item, const RawSource & src) const;
|
||||
void addItems(const RawSourceType & type, const int group, const int count, const int start = 0);
|
||||
};
|
||||
|
||||
class RawSwitchItemModel: public AbstractDynamicItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~RawSwitchItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||
|
||||
protected:
|
||||
virtual void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const;
|
||||
void addItems(const RawSwitchType & type, int count);
|
||||
};
|
||||
|
||||
class CurveItemModel: public AbstractDynamicItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CurveItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~CurveItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||
|
||||
protected:
|
||||
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
|
||||
};
|
||||
|
||||
class GVarReferenceItemModel: public AbstractDynamicItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GVarReferenceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~GVarReferenceItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||
|
||||
protected:
|
||||
virtual void setDynamicItemData(QStandardItem * item, const AdjustmentReference & ar) const;
|
||||
void addItems(int count);
|
||||
};
|
||||
|
||||
class ThrottleSourceItemModel: public AbstractDynamicItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ThrottleSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~ThrottleSourceItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||
|
||||
protected:
|
||||
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
|
||||
};
|
||||
|
||||
class CustomFuncActionItemModel: public AbstractDynamicItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CustomFuncActionItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~CustomFuncActionItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||
|
||||
protected:
|
||||
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
|
||||
};
|
||||
|
||||
class CustomFuncResetParamItemModel: public AbstractDynamicItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CustomFuncResetParamItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~CustomFuncResetParamItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||
|
||||
protected:
|
||||
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
|
||||
};
|
||||
|
||||
class TelemetrySourceItemModel: public AbstractDynamicItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TelemetrySourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~TelemetrySourceItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||
|
||||
protected:
|
||||
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
|
||||
};
|
||||
|
||||
class RssiSourceItemModel: public AbstractDynamicItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RssiSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~RssiSourceItemModel() {};
|
||||
|
||||
public slots:
|
||||
virtual void update(const int event = IMUE_SystemRefresh) override;
|
||||
|
||||
protected:
|
||||
virtual void setDynamicItemData(QStandardItem * item, const int value) const;
|
||||
};
|
||||
|
||||
class CurveRefTypeItemModel : public AbstractStaticItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CurveRefTypeItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~CurveRefTypeItemModel() {};
|
||||
};
|
||||
|
||||
class CurveRefFuncItemModel : public AbstractStaticItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CurveRefFuncItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData,
|
||||
Firmware * firmware, const Boards * const board, const Board::Type boardType);
|
||||
virtual ~CurveRefFuncItemModel() {};
|
||||
};
|
||||
|
||||
class PrecisionItemModel : public AbstractStaticItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PrecisionItemModel(const int minDecimals, const int maxDecimals, const QString suffix = "", const bool placeholders = false);
|
||||
virtual ~PrecisionItemModel() {};
|
||||
};
|
||||
|
||||
//
|
||||
// CompoundItemModelFactory
|
||||
//
|
||||
|
||||
class CompoundItemModelFactory
|
||||
{
|
||||
public:
|
||||
CompoundItemModelFactory(const GeneralSettings * const generalSettings, const ModelData * const modelData);
|
||||
virtual ~CompoundItemModelFactory();
|
||||
|
||||
void addItemModel(const int id);
|
||||
int registerItemModel(AbstractItemModel * itemModel);
|
||||
void unregisterItemModels();
|
||||
void unregisterItemModel(const int id);
|
||||
bool isItemModelRegistered(const int id) const;
|
||||
AbstractItemModel * getItemModel(const int id) const;
|
||||
AbstractItemModel * getItemModel(const QString name) const;
|
||||
void update(const int event = AbstractItemModel::IMUE_SystemRefresh);
|
||||
void dumpAllItemModelContents() const;
|
||||
|
||||
protected:
|
||||
const GeneralSettings * generalSettings;
|
||||
const ModelData * modelData;
|
||||
Firmware * firmware;
|
||||
Boards * board;
|
||||
Board::Type boardType;
|
||||
QVector<AbstractItemModel *> registeredItemModels;
|
||||
|
||||
private:
|
||||
void setSourceId(AbstractItemModel * itemModel);
|
||||
};
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "filtereditemmodels.h"
|
||||
|
||||
FilteredItemModel::FilteredItemModel(AbstractItemModel * sourceModel, int flags) :
|
||||
QSortFilterProxyModel(nullptr),
|
||||
filterFlags(0),
|
||||
m_id(0),
|
||||
m_name("")
|
||||
{
|
||||
setFilterRole(AbstractItemModel::IMDR_Available);
|
||||
setFilterKeyColumn(0);
|
||||
setFilterFlags(flags);
|
||||
setDynamicSortFilter(true);
|
||||
setSourceModel(sourceModel);
|
||||
|
||||
AbstractDynamicItemModel * itemModel = qobject_cast<AbstractDynamicItemModel *>(sourceModel);
|
||||
if (itemModel) {
|
||||
connect(itemModel, &AbstractDynamicItemModel::aboutToBeUpdated, this, &FilteredItemModel::onAboutToBeUpdated);
|
||||
connect(itemModel, &AbstractDynamicItemModel::updateComplete, this, &FilteredItemModel::onUpdateComplete);
|
||||
}
|
||||
}
|
||||
|
||||
void FilteredItemModel::setFilterFlags(int flags)
|
||||
{
|
||||
if (filterFlags != flags) {
|
||||
filterFlags = flags;
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
bool FilteredItemModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
|
||||
{
|
||||
const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
if (!srcIdx.isValid() || !sourceModel()->data(srcIdx, filterRole()).toBool())
|
||||
return false;
|
||||
|
||||
if (!filterFlags)
|
||||
return true;
|
||||
|
||||
bool ok;
|
||||
const int flags = sourceModel()->data(srcIdx, AbstractItemModel::IMDR_Flags).toInt(&ok);
|
||||
return (ok && (!flags || (filterFlags & flags)));
|
||||
}
|
||||
|
||||
void FilteredItemModel::update() const
|
||||
{
|
||||
AbstractDynamicItemModel * itemModel = qobject_cast<AbstractDynamicItemModel *>(sourceModel());
|
||||
if (itemModel)
|
||||
itemModel->update();
|
||||
}
|
||||
|
||||
void FilteredItemModel::onAboutToBeUpdated()
|
||||
{
|
||||
emit aboutToBeUpdated();
|
||||
}
|
||||
|
||||
void FilteredItemModel::onUpdateComplete()
|
||||
{
|
||||
emit updateComplete();
|
||||
}
|
||||
|
||||
// static
|
||||
void FilteredItemModel::dumpItemModelContents(FilteredItemModel * itemModel)
|
||||
{
|
||||
if (itemModel) {
|
||||
qDebug() << "id:" << itemModel->getId() << "name:" << itemModel->getName();
|
||||
|
||||
for (int i = 0; i < itemModel->rowCount(); ++i) {
|
||||
qDebug() << "row:" << i
|
||||
<< "text:" << itemModel->data(itemModel->index(i, 0), Qt::DisplayRole).toString()
|
||||
<< "id:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Id).toInt()
|
||||
<< "avail:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Available).toBool()
|
||||
<< "flags:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Flags).toInt()
|
||||
<< "type:" << itemModel->data(itemModel->index(i, 0), AbstractItemModel::IMDR_Type).toInt();
|
||||
}
|
||||
}
|
||||
else
|
||||
qDebug() << "Error: model not of class FilteredItemModel";
|
||||
}
|
||||
|
||||
//
|
||||
// FilteredItemModelFactory
|
||||
//
|
||||
|
||||
FilteredItemModelFactory::FilteredItemModelFactory()
|
||||
{
|
||||
}
|
||||
|
||||
FilteredItemModelFactory::~FilteredItemModelFactory()
|
||||
{
|
||||
unregisterItemModels();
|
||||
}
|
||||
|
||||
int FilteredItemModelFactory::registerItemModel(FilteredItemModel * itemModel, const QString name, const int id)
|
||||
{
|
||||
if (itemModel) {
|
||||
if (isItemModelRegistered(name)) {
|
||||
qDebug() << "Error: item model already registered with name:" << name;
|
||||
return 0;
|
||||
}
|
||||
else if (id > -1 && isItemModelRegistered(id)) {
|
||||
qDebug() << "Error: item model already registered with id:" << id;
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
int fid = id;
|
||||
if (fid < 0) {
|
||||
fid = registeredItemModels.count() + 1;
|
||||
AbstractItemModel * mdl = qobject_cast<AbstractItemModel *>(itemModel->sourceModel());
|
||||
if (mdl) {
|
||||
fid += mdl->getId() * 128;
|
||||
}
|
||||
}
|
||||
itemModel->setId(fid);
|
||||
itemModel->setName(name);
|
||||
registeredItemModels.append(itemModel);
|
||||
return fid;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "Error: invalid filtered item model pointer";
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FilteredItemModelFactory::unregisterItemModels()
|
||||
{
|
||||
foreach (FilteredItemModel * itemModel, registeredItemModels) {
|
||||
delete itemModel;
|
||||
}
|
||||
}
|
||||
|
||||
void FilteredItemModelFactory::unregisterItemModel(const int id)
|
||||
{
|
||||
FilteredItemModel * itemModel = getItemModel(id);
|
||||
if (itemModel)
|
||||
delete itemModel;
|
||||
}
|
||||
|
||||
bool FilteredItemModelFactory::isItemModelRegistered(const int id) const
|
||||
{
|
||||
return getItemModel(id);
|
||||
}
|
||||
|
||||
bool FilteredItemModelFactory::isItemModelRegistered(const QString name) const
|
||||
{
|
||||
return getItemModel(name);
|
||||
}
|
||||
|
||||
FilteredItemModel * FilteredItemModelFactory::getItemModel(const int id) const
|
||||
{
|
||||
foreach (FilteredItemModel * itemModel, registeredItemModels) {
|
||||
if (itemModel->getId() == id)
|
||||
return itemModel;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FilteredItemModel * FilteredItemModelFactory::getItemModel(const QString name) const
|
||||
{
|
||||
foreach (FilteredItemModel * itemModel, registeredItemModels) {
|
||||
if (itemModel->getName() == name)
|
||||
return itemModel;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FilteredItemModelFactory::update()
|
||||
{
|
||||
foreach (FilteredItemModel * itemModel, registeredItemModels) {
|
||||
itemModel->update();
|
||||
}
|
||||
}
|
||||
|
||||
void FilteredItemModelFactory::dumpItemModelContents(const int id) const
|
||||
{
|
||||
FilteredItemModel::dumpItemModelContents(getItemModel(id));
|
||||
}
|
||||
|
||||
void FilteredItemModelFactory::dumpItemModelContents(const QString name) const
|
||||
{
|
||||
FilteredItemModel::dumpItemModelContents(getItemModel(name));
|
||||
}
|
||||
|
||||
void FilteredItemModelFactory::dumpAllItemModelContents() const
|
||||
{
|
||||
foreach (FilteredItemModel * itemModel, registeredItemModels) {
|
||||
FilteredItemModel::dumpItemModelContents(itemModel);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// CurveRefFilteredFactory
|
||||
//
|
||||
|
||||
CurveRefFilteredFactory::CurveRefFilteredFactory(CompoundItemModelFactory * sharedItemModels, const int curveFlags, const int gvarRefFlags)
|
||||
{
|
||||
if (!sharedItemModels) {
|
||||
qDebug() << "Error: invalid compound item model factory pointer";
|
||||
return;
|
||||
}
|
||||
|
||||
registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_Curve), curveFlags),
|
||||
fidToString(CRFIM_CURVE), CRFIM_CURVE);
|
||||
registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_GVarRef), gvarRefFlags),
|
||||
fidToString(CRFIM_GVARREF), CRFIM_GVARREF);
|
||||
registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_CurveRefType)),
|
||||
fidToString(CRFIM_TYPE), CRFIM_TYPE);
|
||||
registerItemModel(new FilteredItemModel(sharedItemModels->getItemModel(AbstractItemModel::IMID_CurveRefFunc)),
|
||||
fidToString(CRFIM_FUNC), CRFIM_FUNC);
|
||||
}
|
||||
|
||||
CurveRefFilteredFactory::~CurveRefFilteredFactory()
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
QString CurveRefFilteredFactory::fidToString(const int value)
|
||||
{
|
||||
switch(value) {
|
||||
case CRFIM_CURVE:
|
||||
return "Curves";
|
||||
case CRFIM_GVARREF:
|
||||
return "Global Variables";
|
||||
case CRFIM_TYPE:
|
||||
return "Types";
|
||||
case CRFIM_FUNC:
|
||||
return "Functions";
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef FILTEREDITEMMODELS_H
|
||||
#define FILTEREDITEMMODELS_H
|
||||
|
||||
#include "compounditemmodels.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QString>
|
||||
|
||||
class FilteredItemModel: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum DataFilters {
|
||||
AllFilter = AbstractItemModel::IMDG_Negative | AbstractItemModel::IMDG_None | AbstractItemModel::IMDG_Positive,
|
||||
AllExcludeNoneFilter = AllFilter &~ AbstractItemModel::IMDG_None,
|
||||
NegativeFilter = AbstractItemModel::IMDG_Negative | AbstractItemModel::IMDG_None,
|
||||
NegativeExcludeNoneFilter = AbstractItemModel::IMDG_Negative,
|
||||
PositiveFilter = AbstractItemModel::IMDG_Positive | AbstractItemModel::IMDG_None,
|
||||
PositiveExcludeNoneFilter = AbstractItemModel::IMDG_Positive
|
||||
};
|
||||
Q_ENUM(DataFilters)
|
||||
|
||||
explicit FilteredItemModel(AbstractItemModel * sourceModel, int flags);
|
||||
explicit FilteredItemModel(AbstractItemModel * sourceModel) :
|
||||
FilteredItemModel(sourceModel, 0) {}
|
||||
virtual ~FilteredItemModel() {};
|
||||
|
||||
void setId(int id) { m_id = id; }
|
||||
int getId() const { return m_id; };
|
||||
void setName(QString name) { m_name = name; }
|
||||
QString getName() const { return m_name; }
|
||||
|
||||
static void dumpItemModelContents(FilteredItemModel * itemModel);
|
||||
|
||||
public slots:
|
||||
void setFilterFlags(int flags);
|
||||
void update() const;
|
||||
void onAboutToBeUpdated();
|
||||
void onUpdateComplete();
|
||||
|
||||
signals:
|
||||
void aboutToBeUpdated();
|
||||
void updateComplete();
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
|
||||
|
||||
int filterFlags;
|
||||
|
||||
private:
|
||||
int m_id = 0;
|
||||
QString m_name = "";
|
||||
};
|
||||
|
||||
class FilteredItemModelFactory
|
||||
{
|
||||
public:
|
||||
explicit FilteredItemModelFactory();
|
||||
virtual ~FilteredItemModelFactory();
|
||||
|
||||
int registerItemModel(FilteredItemModel * itemModel, const QString name, const int id = -1);
|
||||
void unregisterItemModels();
|
||||
void unregisterItemModel(const int id);
|
||||
bool isItemModelRegistered(const int id) const;
|
||||
bool isItemModelRegistered(const QString name) const;
|
||||
FilteredItemModel * getItemModel(const int id) const;
|
||||
FilteredItemModel * getItemModel(const QString name) const;
|
||||
void update();
|
||||
|
||||
void dumpItemModelContents(const int id) const;
|
||||
void dumpItemModelContents(const QString name) const;
|
||||
void dumpAllItemModelContents() const;
|
||||
|
||||
protected:
|
||||
QVector<FilteredItemModel *> registeredItemModels;
|
||||
};
|
||||
|
||||
class CurveRefFilteredFactory : public FilteredItemModelFactory
|
||||
{
|
||||
public:
|
||||
enum FilteredItemModelId {
|
||||
CRFIM_CURVE,
|
||||
CRFIM_GVARREF,
|
||||
CRFIM_TYPE,
|
||||
CRFIM_FUNC
|
||||
};
|
||||
|
||||
explicit CurveRefFilteredFactory(CompoundItemModelFactory * sharedItemModels, const int curveFlags = 0, const int gvarRefFlags = 0);
|
||||
virtual ~CurveRefFilteredFactory();
|
||||
|
||||
static QString fidToString(const int value);
|
||||
};
|
||||
|
||||
#endif // FILTEREDITEMMODELS_H
|
||||
@@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "rawitemdatamodels.h"
|
||||
#include "generalsettings.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "modeldata.h"
|
||||
|
||||
RawSourceItemModel::RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
|
||||
AbstractRawItemDataModel(generalSettings, modelData, parent)
|
||||
{
|
||||
const Boards board = Boards(getCurrentBoard());
|
||||
Firmware * fw = getCurrentFirmware();
|
||||
|
||||
addItems(SOURCE_TYPE_NONE, RawSource::NoneGroup, 1);
|
||||
for (int i=0; i < fw->getCapability(LuaScripts); i++)
|
||||
addItems(SOURCE_TYPE_LUA_OUTPUT, RawSource::ScriptsGroup, fw->getCapability(LuaOutputsPerScript), i * 16);
|
||||
addItems(SOURCE_TYPE_VIRTUAL_INPUT, RawSource::InputsGroup, fw->getCapability(VirtualInputs));
|
||||
addItems(SOURCE_TYPE_STICK, RawSource::SourcesGroup, board.getCapability(Board::MaxAnalogs));
|
||||
addItems(SOURCE_TYPE_ROTARY_ENCODER, RawSource::SourcesGroup, fw->getCapability(RotaryEncoders));
|
||||
addItems(SOURCE_TYPE_TRIM, RawSource::TrimsGroup, board.getCapability(Board::NumTrims));
|
||||
addItems(SOURCE_TYPE_MAX, RawSource::SourcesGroup, 1);
|
||||
addItems(SOURCE_TYPE_SWITCH, RawSource::SwitchesGroup, board.getCapability(Board::Switches));
|
||||
addItems(SOURCE_TYPE_CUSTOM_SWITCH, RawSource::SwitchesGroup, fw->getCapability(LogicalSwitches));
|
||||
addItems(SOURCE_TYPE_CYC, RawSource::SourcesGroup, CPN_MAX_CYC);
|
||||
addItems(SOURCE_TYPE_PPM, RawSource::SourcesGroup, fw->getCapability(TrainerInputs));
|
||||
addItems(SOURCE_TYPE_CH, RawSource::SourcesGroup, fw->getCapability(Outputs));
|
||||
addItems(SOURCE_TYPE_SPECIAL, RawSource::TelemGroup, 5);
|
||||
addItems(SOURCE_TYPE_TELEMETRY, RawSource::TelemGroup, CPN_MAX_SENSORS * 3);
|
||||
addItems(SOURCE_TYPE_GVAR, RawSource::GVarsGroup, fw->getCapability(Gvars));
|
||||
}
|
||||
|
||||
void RawSourceItemModel::setDynamicItemData(QStandardItem * item, const RawSource & src) const
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
item->setText(src.toString(modelData, generalSettings, board));
|
||||
item->setData(src.isAvailable(modelData, generalSettings, board), IsAvailableRole);
|
||||
}
|
||||
|
||||
void RawSourceItemModel::addItems(const RawSourceType & type, const int group, const int count, const int start)
|
||||
{
|
||||
for (int i = start; i < start + count; i++) {
|
||||
const RawSource src = RawSource(type, i);
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(src.toValue(), ItemIdRole);
|
||||
modelItem->setData(type, ItemTypeRole);
|
||||
modelItem->setData(group, ItemFlagsRole);
|
||||
setDynamicItemData(modelItem, src);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RawSourceItemModel::update() const
|
||||
{
|
||||
for (int i=0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), RawSource(item(i)->data(ItemIdRole).toInt()));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// RawSwitchItemModel
|
||||
//
|
||||
|
||||
RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent) :
|
||||
AbstractRawItemDataModel(generalSettings, modelData, parent)
|
||||
{
|
||||
Boards board = Boards(getCurrentBoard());
|
||||
Firmware * fw = getCurrentFirmware();
|
||||
|
||||
// Descending switch direction: NOT (!) switches
|
||||
addItems(SWITCH_TYPE_ACT, -1);
|
||||
addItems(SWITCH_TYPE_SENSOR, -CPN_MAX_SENSORS);
|
||||
addItems(SWITCH_TYPE_TELEMETRY, -1);
|
||||
addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes));
|
||||
addItems(SWITCH_TYPE_VIRTUAL, -fw->getCapability(LogicalSwitches));
|
||||
addItems(SWITCH_TYPE_ROTARY_ENCODER, -fw->getCapability(RotaryEncoders));
|
||||
addItems(SWITCH_TYPE_TRIM, -board.getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, -(board.getCapability(Board::MultiposPots) * board.getCapability(Board::MultiposPotsPositions)));
|
||||
addItems(SWITCH_TYPE_SWITCH, -board.getCapability(Board::SwitchPositions));
|
||||
|
||||
// Ascending switch direction (including zero)
|
||||
addItems(SWITCH_TYPE_TIMER_MODE, 5);
|
||||
addItems(SWITCH_TYPE_NONE, 1);
|
||||
addItems(SWITCH_TYPE_SWITCH, board.getCapability(Board::SwitchPositions));
|
||||
addItems(SWITCH_TYPE_MULTIPOS_POT, board.getCapability(Board::MultiposPots) * board.getCapability(Board::MultiposPotsPositions));
|
||||
addItems(SWITCH_TYPE_TRIM, board.getCapability(Board::NumTrimSwitches));
|
||||
addItems(SWITCH_TYPE_ROTARY_ENCODER, fw->getCapability(RotaryEncoders));
|
||||
addItems(SWITCH_TYPE_VIRTUAL, fw->getCapability(LogicalSwitches));
|
||||
addItems(SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes));
|
||||
addItems(SWITCH_TYPE_TELEMETRY, 1);
|
||||
addItems(SWITCH_TYPE_SENSOR, CPN_MAX_SENSORS);
|
||||
addItems(SWITCH_TYPE_ON, 1);
|
||||
addItems(SWITCH_TYPE_ONE, 1);
|
||||
addItems(SWITCH_TYPE_ACT, 1);
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const
|
||||
{
|
||||
const Board::Type board = getCurrentBoard();
|
||||
item->setText(rsw.toString(board, generalSettings, modelData));
|
||||
item->setData(rsw.isAvailable(modelData, generalSettings, board), IsAvailableRole);
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::addItems(const RawSwitchType & type, int count)
|
||||
{
|
||||
// Most RawSwitch() indices are one-based (vs. typical zero); these are exceptions to the rule:
|
||||
const static QVector<int> rawSwitchIndexBaseZeroTypes = QVector<int>() << SWITCH_TYPE_NONE << SWITCH_TYPE_ON << SWITCH_TYPE_OFF << SWITCH_TYPE_TIMER_MODE;
|
||||
// handle exceptions in RawSwitch() index values
|
||||
const short rawIdxAdj = rawSwitchIndexBaseZeroTypes.contains(type) ? -1 : 0;
|
||||
|
||||
// determine cotext flags
|
||||
int context = RawSwitch::AllSwitchContexts;
|
||||
switch (type) {
|
||||
case SWITCH_TYPE_FLIGHT_MODE:
|
||||
context &= ~RawSwitch::MixesContext;
|
||||
// fallthrough
|
||||
case SWITCH_TYPE_VIRTUAL:
|
||||
case SWITCH_TYPE_SENSOR:
|
||||
context &= ~RawSwitch::GlobalFunctionsContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_TIMER_MODE:
|
||||
context = RawSwitch::TimersContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_NONE:
|
||||
context &= ~RawSwitch::TimersContext;
|
||||
break;
|
||||
|
||||
case SWITCH_TYPE_ON:
|
||||
case SWITCH_TYPE_ONE:
|
||||
context = RawSwitch::SpecialFunctionsContext | RawSwitch::GlobalFunctionsContext;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
int i = (count < 0 ? count : 1);
|
||||
count = (i < 0 ? 0 : count + i);
|
||||
for ( ; i < count; ++i) {
|
||||
RawSwitch rs(type, i + rawIdxAdj);
|
||||
QStandardItem * modelItem = new QStandardItem();
|
||||
modelItem->setData(rs.toValue(), ItemIdRole);
|
||||
modelItem->setData(type, ItemTypeRole);
|
||||
modelItem->setData(context, ItemFlagsRole);
|
||||
setDynamicItemData(modelItem, rs);
|
||||
appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
void RawSwitchItemModel::update() const
|
||||
{
|
||||
for (int i=0; i < rowCount(); ++i)
|
||||
setDynamicItemData(item(i), RawSwitch(item(i)->data(ItemIdRole).toInt()));
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef RAWITEMDATAMODELS_H
|
||||
#define RAWITEMDATAMODELS_H
|
||||
|
||||
#include "rawsource.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QStandardItemModel>
|
||||
|
||||
class GeneralSettings;
|
||||
class ModelData;
|
||||
|
||||
class AbstractRawItemDataModel: public QStandardItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum DataRoles { ItemIdRole = Qt::UserRole, ItemTypeRole, ItemFlagsRole, IsAvailableRole };
|
||||
Q_ENUM(DataRoles)
|
||||
|
||||
explicit AbstractRawItemDataModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
|
||||
QStandardItemModel(parent),
|
||||
generalSettings(generalSettings),
|
||||
modelData(modelData)
|
||||
{}
|
||||
|
||||
public slots:
|
||||
virtual void update() const = 0;
|
||||
|
||||
protected:
|
||||
const GeneralSettings * generalSettings;
|
||||
const ModelData * modelData;
|
||||
};
|
||||
|
||||
|
||||
class RawSourceItemModel: public AbstractRawItemDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void update() const override;
|
||||
|
||||
protected:
|
||||
void setDynamicItemData(QStandardItem * item, const RawSource & src) const;
|
||||
void addItems(const RawSourceType & type, const int group, const int count, const int start = 0);
|
||||
};
|
||||
|
||||
|
||||
class RawSwitchItemModel: public AbstractRawItemDataModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawSwitchItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void update() const override;
|
||||
|
||||
protected:
|
||||
void setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const;
|
||||
void addItems(const RawSwitchType & type, int count);
|
||||
};
|
||||
|
||||
|
||||
#endif // RAWITEMDATAMODELS_H
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "rawitemfilteredmodel.h"
|
||||
#include "rawitemdatamodels.h"
|
||||
|
||||
RawItemFilteredModel::RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent) :
|
||||
QSortFilterProxyModel(parent),
|
||||
filterFlags(0)
|
||||
{
|
||||
setFilterRole(AbstractRawItemDataModel::IsAvailableRole);
|
||||
setFilterKeyColumn(0);
|
||||
setFilterFlags(flags);
|
||||
setDynamicSortFilter(true);
|
||||
setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
void RawItemFilteredModel::setFilterFlags(int flags)
|
||||
{
|
||||
if (filterFlags != flags) {
|
||||
filterFlags = flags;
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
bool RawItemFilteredModel::filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const
|
||||
{
|
||||
const QModelIndex & srcIdx = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
if (!srcIdx.isValid() || !sourceModel()->data(srcIdx, filterRole()).toBool())
|
||||
return false;
|
||||
|
||||
if (!filterFlags)
|
||||
return true;
|
||||
|
||||
bool ok;
|
||||
const int flags = sourceModel()->data(srcIdx, AbstractRawItemDataModel::ItemFlagsRole).toInt(&ok);
|
||||
return (ok && (!flags || (filterFlags & flags)));
|
||||
}
|
||||
|
||||
void RawItemFilteredModel::update() const
|
||||
{
|
||||
AbstractRawItemDataModel * model = qobject_cast<AbstractRawItemDataModel *>(sourceModel());
|
||||
if (model)
|
||||
model->update();
|
||||
}
|
||||
|
||||
|
||||
RawSourceFilterItemModel::RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent) :
|
||||
RawItemFilteredModel(new RawSourceItemModel(generalSettings, modelData, parent), flags, parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RawSwitchFilterItemModel::RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent) :
|
||||
RawItemFilteredModel(new RawSwitchItemModel(generalSettings, modelData, parent), context, parent)
|
||||
{
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef RAWITEMFILTEREDMODEL_H
|
||||
#define RAWITEMFILTEREDMODEL_H
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class GeneralSettings;
|
||||
class ModelData;
|
||||
class RawSourceItemModel;
|
||||
class RawSwitchItemModel;
|
||||
|
||||
class RawItemFilteredModel: public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, int flags, QObject * parent = nullptr);
|
||||
explicit RawItemFilteredModel(QAbstractItemModel * sourceModel, QObject * parent = nullptr) : RawItemFilteredModel(sourceModel, 0, parent) {}
|
||||
|
||||
public slots:
|
||||
void setFilterFlags(int flags);
|
||||
void update() const;
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex & sourceParent) const override;
|
||||
|
||||
int filterFlags;
|
||||
};
|
||||
|
||||
|
||||
// The specialized "convenience" types below can go away once centralalized RawSource/RawSwitch item models are established.
|
||||
// These proxy classes will automatically create a source model of the corresponding type.
|
||||
|
||||
class RawSwitchFilterItemModel: public RawItemFilteredModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using RawItemFilteredModel::RawItemFilteredModel;
|
||||
|
||||
explicit RawSwitchFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int context, QObject * parent = nullptr);
|
||||
};
|
||||
|
||||
|
||||
class RawSourceFilterItemModel: public RawItemFilteredModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using RawItemFilteredModel::RawItemFilteredModel;
|
||||
|
||||
explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, int flags, QObject * parent = nullptr);
|
||||
|
||||
explicit RawSourceFilterItemModel(const GeneralSettings * const generalSettings, const ModelData * const modelData, QObject * parent = nullptr) :
|
||||
RawSourceFilterItemModel(generalSettings, modelData, 0, parent) {}
|
||||
};
|
||||
|
||||
#endif // RAWITEMFILTEREDMODEL_H
|
||||
@@ -39,6 +39,8 @@
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QSpinBox>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
|
||||
FileSyncDialog::FileSyncDialog(QWidget * parent, const SyncProcess::SyncOptions & syncOptions) :
|
||||
QDialog(parent),
|
||||
|
||||
@@ -2,27 +2,34 @@
|
||||
set(firmwares_SRCS
|
||||
adjustmentreference.cpp
|
||||
boards.cpp
|
||||
curvedata.cpp
|
||||
curvereference.cpp
|
||||
customfunctiondata.cpp
|
||||
eeprominterface.cpp
|
||||
generalsettings.cpp
|
||||
gvardata.cpp
|
||||
io_data.cpp
|
||||
input_data.cpp
|
||||
flightmodedata.cpp
|
||||
heli_data.cpp
|
||||
logicalswitchdata.cpp
|
||||
mixdata.cpp
|
||||
modeldata.cpp
|
||||
moduledata.cpp
|
||||
multiprotocols.cpp
|
||||
output_data.cpp
|
||||
radiodata.cpp
|
||||
radiodataconversionstate.cpp
|
||||
rawsource.cpp
|
||||
rawswitch.cpp
|
||||
sensordata.cpp
|
||||
telem_data.cpp
|
||||
timerdata.cpp
|
||||
afhds3.cpp
|
||||
ersky9x/ersky9xeeprom.cpp
|
||||
ersky9x/ersky9xinterface.cpp
|
||||
opentx/opentxeeprom.cpp
|
||||
opentx/opentxinterface.cpp
|
||||
datahelpers.cpp
|
||||
)
|
||||
|
||||
string(REPLACE ".cpp" ".h" firmwares_HDRS "${firmwares_SRCS}")
|
||||
@@ -32,8 +39,14 @@ list(APPEND firmwares_HDRS
|
||||
moduledata.h
|
||||
)
|
||||
|
||||
set(firmwares_QT
|
||||
curvereference.h
|
||||
)
|
||||
|
||||
qt5_wrap_cpp(firmwares_SRCS ${firmwares_QT})
|
||||
|
||||
add_library(firmwares ${firmwares_SRCS} ${firmwares_HDRS})
|
||||
target_link_libraries(firmwares ${CPN_COMMON_LIB} Qt5::Core Qt5::Xml Qt5::Widgets)
|
||||
target_link_libraries(firmwares ${CPN_COMMON_LIB} datamodels Qt5::Core Qt5::Xml Qt5::Widgets)
|
||||
target_include_directories(firmwares
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "adjustmentreference.h"
|
||||
#include "radiodata.h" // for ModelData
|
||||
#include "modeldata.h"
|
||||
|
||||
AdjustmentReference::AdjustmentReference(int value)
|
||||
{
|
||||
@@ -76,3 +76,8 @@ QString AdjustmentReference::toString(const ModelData * model, const bool sign)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const bool AdjustmentReference::isAvailable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ class AdjustmentReference {
|
||||
bool isSet() const { return type != ADJUST_REF_VALUE || value != 0; }
|
||||
bool isValid(const int value) const;
|
||||
QString toString(const ModelData * model = nullptr, const bool sign = false) const;
|
||||
const bool isAvailable() const;
|
||||
|
||||
inline const int toValue() const
|
||||
{
|
||||
|
||||
@@ -79,17 +79,21 @@ uint32_t Boards::getFourCC(Type board)
|
||||
return 0x3278746F;
|
||||
case BOARD_JUMPER_T12:
|
||||
return 0x3D78746F;
|
||||
case BOARD_JUMPER_TLITE:
|
||||
return 0x4278746F;
|
||||
case BOARD_JUMPER_T16:
|
||||
return 0x3F78746F;
|
||||
case BOARD_JUMPER_T18:
|
||||
return 0x4078746F;
|
||||
case BOARD_RADIOMASTER_TX16S:
|
||||
return 0x3878746F;
|
||||
case BOARD_UNKNOWN:
|
||||
break;
|
||||
case BOARD_RADIOMASTER_TX12:
|
||||
return 0x4178746F;
|
||||
case BOARD_RADIOMASTER_T8:
|
||||
return 0x4378746F;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Boards::getEEpromSize(Board::Type board)
|
||||
@@ -111,6 +115,9 @@ int Boards::getEEpromSize(Board::Type board)
|
||||
case BOARD_TARANIS_X9DP_2019:
|
||||
case BOARD_TARANIS_X9E:
|
||||
case BOARD_JUMPER_T12:
|
||||
case BOARD_JUMPER_TLITE:
|
||||
case BOARD_RADIOMASTER_TX12:
|
||||
case BOARD_RADIOMASTER_T8:
|
||||
return EESIZE_TARANIS;
|
||||
case BOARD_UNKNOWN:
|
||||
return EESIZE_MAX;
|
||||
@@ -121,9 +128,9 @@ int Boards::getEEpromSize(Board::Type board)
|
||||
case BOARD_JUMPER_T18:
|
||||
case BOARD_RADIOMASTER_TX16S:
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Boards::getFlashSize(Type board)
|
||||
@@ -145,6 +152,9 @@ int Boards::getFlashSize(Type board)
|
||||
case BOARD_TARANIS_X9DP_2019:
|
||||
case BOARD_TARANIS_X9E:
|
||||
case BOARD_JUMPER_T12:
|
||||
case BOARD_JUMPER_TLITE:
|
||||
case BOARD_RADIOMASTER_TX12:
|
||||
case BOARD_RADIOMASTER_T8:
|
||||
return FSIZE_TARANIS;
|
||||
case BOARD_HORUS_X12S:
|
||||
case BOARD_X10:
|
||||
@@ -177,7 +187,7 @@ SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_TARANIS_XLITE(board)) {
|
||||
else if (IS_TARANIS_XLITE(board) || IS_JUMPER_TLITE(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
@@ -187,7 +197,20 @@ SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_TARANIS_X7(board)) {
|
||||
else if (board == BOARD_TARANIS_X7_ACCESS) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_3POS, "SC"},
|
||||
{SWITCH_3POS, "SD"},
|
||||
{SWITCH_2POS, "SF"},
|
||||
{SWITCH_TOGGLE, "SH"},
|
||||
{SWITCH_2POS, "SI"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (board == BOARD_TARANIS_X7) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
@@ -201,6 +224,30 @@ SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_RADIOMASTER_TX12(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_TOGGLE, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_3POS, "SC"},
|
||||
{SWITCH_TOGGLE, "SD"},
|
||||
{SWITCH_3POS, "SE"},
|
||||
{SWITCH_3POS, "SF"},
|
||||
{SWITCH_2POS, "SI"},
|
||||
{SWITCH_2POS, "SJ"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_RADIOMASTER_T8(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_TOGGLE, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_3POS, "SC"},
|
||||
{SWITCH_TOGGLE, "SD"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_JUMPER_T12(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
@@ -213,7 +260,23 @@ SwitchInfo Boards::getSwitchInfo(Board::Type board, int index)
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_HORUS_OR_TARANIS(board)) {
|
||||
else if (IS_FAMILY_HORUS_OR_T16(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
{SWITCH_3POS, "SC"},
|
||||
{SWITCH_3POS, "SD"},
|
||||
{SWITCH_3POS, "SE"},
|
||||
{SWITCH_2POS, "SF"},
|
||||
{SWITCH_3POS, "SG"},
|
||||
{SWITCH_TOGGLE, "SH"},
|
||||
{SWITCH_2POS, "SI"},
|
||||
{SWITCH_2POS, "SJ"}
|
||||
};
|
||||
if (index < DIM(switches))
|
||||
return switches[index];
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "SA"},
|
||||
{SWITCH_3POS, "SB"},
|
||||
@@ -263,7 +326,9 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
case Pots:
|
||||
if (IS_TARANIS_X9LITE(board))
|
||||
return 1;
|
||||
else if (IS_TARANIS_SMALL(board) || IS_JUMPER_T12(board))
|
||||
else if (IS_JUMPER_TLITE(board))
|
||||
return 0;
|
||||
else if (IS_TARANIS_SMALL(board))
|
||||
return 2;
|
||||
else if (IS_TARANIS_X9E(board))
|
||||
return 4;
|
||||
@@ -289,7 +354,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
return 0;
|
||||
|
||||
case MouseAnalogs:
|
||||
if (IS_FAMILY_HORUS_OR_T16(board))
|
||||
if (IS_HORUS_X12S(board))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
@@ -316,10 +381,14 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
return 5;
|
||||
else if (board == Board::BOARD_TARANIS_X9LITES)
|
||||
return 7;
|
||||
else if (IS_TARANIS_X7(board))
|
||||
else if (board == BOARD_TARANIS_X7_ACCESS)
|
||||
return 7;
|
||||
else if (board == BOARD_TARANIS_X7)
|
||||
return 8;
|
||||
else if (board == BOARD_JUMPER_TLITE)
|
||||
return 4;
|
||||
else if (IS_FAMILY_T12(board))
|
||||
return 8;
|
||||
else if (IS_JUMPER_T12(board))
|
||||
return 6;
|
||||
else if (IS_TARANIS_XLITE(board))
|
||||
return 6;
|
||||
else if (board == Board::BOARD_TARANIS_X9DP_2019)
|
||||
@@ -334,7 +403,11 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
case FactoryInstalledSwitches:
|
||||
if (IS_TARANIS_X9E(board))
|
||||
return 8;
|
||||
if (IS_HORUS_X12S(board))
|
||||
else if (IS_JUMPER_TLITE(board))
|
||||
return 4;
|
||||
else if (IS_FAMILY_T12(board))
|
||||
return 6;
|
||||
else if (IS_HORUS_X12S(board))
|
||||
return 8;
|
||||
else
|
||||
return getCapability(board, Switches);
|
||||
@@ -479,8 +552,6 @@ QString Boards::getBoardName(Board::Type board)
|
||||
return "Taranis X7/X7S";
|
||||
case BOARD_TARANIS_X7_ACCESS:
|
||||
return "Taranis X7/X7S Access";
|
||||
case BOARD_JUMPER_T12:
|
||||
return "Jumper T12";
|
||||
case BOARD_TARANIS_XLITE:
|
||||
return "Taranis X-Lite";
|
||||
case BOARD_TARANIS_XLITES:
|
||||
@@ -509,12 +580,20 @@ QString Boards::getBoardName(Board::Type board)
|
||||
return "Horus X10/X10S";
|
||||
case BOARD_X10_EXPRESS:
|
||||
return "Horus X10/X10S Express";
|
||||
case BOARD_JUMPER_T12:
|
||||
return "Jumper T12";
|
||||
case BOARD_JUMPER_TLITE:
|
||||
return "Jumper T-Lite";
|
||||
case BOARD_JUMPER_T16:
|
||||
return "Jumper T16";
|
||||
case BOARD_JUMPER_T18:
|
||||
return "Jumper T18";
|
||||
case BOARD_RADIOMASTER_TX16S:
|
||||
return "Radiomaster TX16S";
|
||||
case BOARD_RADIOMASTER_TX12:
|
||||
return "Radiomaster TX12";
|
||||
case BOARD_RADIOMASTER_T8:
|
||||
return "Radiomaster T8";
|
||||
default:
|
||||
return tr("Unknown");
|
||||
}
|
||||
|
||||
@@ -52,10 +52,13 @@ namespace Board {
|
||||
BOARD_JUMPER_T16,
|
||||
BOARD_RADIOMASTER_TX16S,
|
||||
BOARD_JUMPER_T18,
|
||||
BOARD_RADIOMASTER_TX12,
|
||||
BOARD_RADIOMASTER_T8,
|
||||
BOARD_JUMPER_TLITE,
|
||||
BOARD_TYPE_COUNT,
|
||||
BOARD_TYPE_MAX = BOARD_TYPE_COUNT - 1
|
||||
};
|
||||
|
||||
constexpr int BOARD_TYPE_MAX = BOARD_JUMPER_T18;
|
||||
|
||||
enum PotType
|
||||
{
|
||||
POT_NONE,
|
||||
@@ -203,6 +206,11 @@ inline bool IS_JUMPER_T12(Board::Type board)
|
||||
return board == Board::BOARD_JUMPER_T12;
|
||||
}
|
||||
|
||||
inline bool IS_JUMPER_TLITE(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_JUMPER_TLITE;
|
||||
}
|
||||
|
||||
inline bool IS_JUMPER_T16(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_JUMPER_T16;
|
||||
@@ -218,11 +226,26 @@ inline bool IS_RADIOMASTER_TX16S(Board::Type board)
|
||||
return board == Board::BOARD_RADIOMASTER_TX16S;
|
||||
}
|
||||
|
||||
inline bool IS_RADIOMASTER_TX12(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_RADIOMASTER_TX12;
|
||||
}
|
||||
|
||||
inline bool IS_RADIOMASTER_T8(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_RADIOMASTER_T8;
|
||||
}
|
||||
|
||||
inline bool IS_FAMILY_T16(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_JUMPER_T16 || board == Board::BOARD_RADIOMASTER_TX16S || board == Board::BOARD_JUMPER_T18;
|
||||
}
|
||||
|
||||
inline bool IS_FAMILY_T12(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_JUMPER_T12 || board == Board::BOARD_RADIOMASTER_TX12 || board == Board::BOARD_RADIOMASTER_T8 || board == Board::BOARD_JUMPER_TLITE;
|
||||
}
|
||||
|
||||
inline bool IS_TARANIS_XLITE(Board::Type board)
|
||||
{
|
||||
return board == Board::BOARD_TARANIS_XLITE || board == Board::BOARD_TARANIS_XLITES;
|
||||
@@ -273,14 +296,14 @@ inline bool IS_TARANIS_X9E(Board::Type board)
|
||||
return board == Board::BOARD_TARANIS_X9E;
|
||||
}
|
||||
|
||||
inline bool IS_TARANIS(Board::Type board)
|
||||
{
|
||||
return IS_TARANIS_X9(board) || IS_TARANIS_X7(board) || IS_TARANIS_X9LITE(board) || IS_TARANIS_XLITE(board) || IS_JUMPER_T12(board);
|
||||
}
|
||||
|
||||
inline bool IS_TARANIS_SMALL(Board::Type board)
|
||||
{
|
||||
return IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || IS_JUMPER_T12(board);
|
||||
return IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || IS_FAMILY_T12(board);
|
||||
}
|
||||
|
||||
inline bool IS_TARANIS(Board::Type board)
|
||||
{
|
||||
return IS_TARANIS_X9(board) || IS_TARANIS_SMALL(board);
|
||||
}
|
||||
|
||||
inline bool IS_HORUS_X10(Board::Type board)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "curvedata.h"
|
||||
#include "radiodata.h"
|
||||
|
||||
CurveData::CurveData()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void CurveData::clear(int count)
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(CurveData));
|
||||
this->count = count;
|
||||
}
|
||||
|
||||
bool CurveData::isEmpty() const
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (points[i].y != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QString CurveData::nameToString(const int idx) const
|
||||
{
|
||||
return RadioData::getElementName(tr("CV"), idx + 1, name);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class CurvePoint {
|
||||
public:
|
||||
int8_t x;
|
||||
int8_t y;
|
||||
};
|
||||
|
||||
#define CURVEDATA_NAME_LEN 6
|
||||
|
||||
class CurveData {
|
||||
Q_DECLARE_TR_FUNCTIONS(CurveData)
|
||||
|
||||
public:
|
||||
enum CurveType {
|
||||
CURVE_TYPE_STANDARD,
|
||||
CURVE_TYPE_CUSTOM,
|
||||
CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM
|
||||
};
|
||||
|
||||
CurveData();
|
||||
|
||||
CurveType type;
|
||||
bool smooth;
|
||||
int count;
|
||||
CurvePoint points[CPN_MAX_POINTS];
|
||||
char name[CURVEDATA_NAME_LEN + 1];
|
||||
|
||||
void clear(int count = 5);
|
||||
bool isEmpty() const;
|
||||
QString nameToString(const int idx) const;
|
||||
};
|
||||
@@ -19,45 +19,269 @@
|
||||
*/
|
||||
|
||||
#include "curvereference.h"
|
||||
#include "adjustmentreference.h"
|
||||
#include "helpers.h"
|
||||
#include "modeldata.h"
|
||||
#include "filtereditemmodels.h"
|
||||
|
||||
#include "helpers.h" // for Helpers::getAdjustmentString()
|
||||
#include "radiodata.h" // for ModelData
|
||||
|
||||
QString CurveReference::toString(const ModelData * model, bool verbose) const
|
||||
const QString CurveReference::toString(const ModelData * model, bool verbose) const
|
||||
{
|
||||
if (value == 0) {
|
||||
return "----";
|
||||
}
|
||||
if (value == 0)
|
||||
return CPN_STR_NONE_ITEM;
|
||||
|
||||
QString ret;
|
||||
unsigned idx = abs(value) - 1;
|
||||
|
||||
switch(type) {
|
||||
case CURVE_REF_DIFF:
|
||||
ret = tr("Diff(%1)").arg(Helpers::getAdjustmentString(value, model));
|
||||
break;
|
||||
|
||||
case CURVE_REF_EXPO:
|
||||
ret = tr("Expo(%1)").arg(Helpers::getAdjustmentString(value, model));
|
||||
ret = AdjustmentReference(value).toString(model);
|
||||
break;
|
||||
|
||||
case CURVE_REF_FUNC:
|
||||
ret = QString("x>0" "x<0" "|x|" "f>0" "f<0" "|f|").mid(3*(value-1), 3);
|
||||
if (verbose)
|
||||
ret = tr("Function(%1)").arg(ret);
|
||||
ret = functionToString(value);
|
||||
break;
|
||||
|
||||
default:
|
||||
case CURVE_REF_CUSTOM:
|
||||
if (model)
|
||||
ret = model->curves[idx].nameToString(idx);
|
||||
else
|
||||
ret = CurveData().nameToString(idx);
|
||||
if (verbose)
|
||||
ret = tr("Curve(%1)").arg(ret);
|
||||
if (value < 0)
|
||||
ret.prepend(CPN_STR_SW_INDICATOR_REV);
|
||||
break;
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
ret = tr(qPrintable(QString(typeToString(type) + "(%1)").arg(ret)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const bool CurveReference::isValueNumber() const
|
||||
{
|
||||
return (type == CURVE_REF_DIFF || type == CURVE_REF_EXPO) && AdjustmentReference(value).type == AdjustmentReference::ADJUST_REF_VALUE;
|
||||
}
|
||||
|
||||
const bool CurveReference::isAvailable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
int CurveReference::getDefaultValue(const CurveRefType type, const bool isGVar)
|
||||
{
|
||||
if (isGVar && (type == CURVE_REF_DIFF || type == CURVE_REF_EXPO))
|
||||
return AdjustmentReference(AdjustmentReference::ADJUST_REF_GVAR, 1).toValue();
|
||||
else if (type == CURVE_REF_FUNC)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static
|
||||
QString CurveReference::typeToString(const CurveRefType type)
|
||||
{
|
||||
const QStringList strl = { tr("Diff"), tr("Expo") , tr("Func"), tr("Curve") };
|
||||
int idx = (int)type;
|
||||
|
||||
if (idx < 0 || idx >= strl.count())
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
|
||||
return strl.at(idx);
|
||||
}
|
||||
|
||||
// static
|
||||
QString CurveReference::functionToString(const int value)
|
||||
{
|
||||
const QStringList strl = { "x>0", "x<0", "|x|", "f>0", "f<0", "|f|" };
|
||||
int idx = value - 1;
|
||||
|
||||
if (idx < 0 || idx >= strl.count())
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
|
||||
return strl.at(idx);
|
||||
}
|
||||
|
||||
// static
|
||||
bool CurveReference::isTypeAvailable(const CurveRefType type)
|
||||
{
|
||||
bool ret = false;
|
||||
Firmware * fw = getCurrentFirmware();
|
||||
|
||||
switch(type) {
|
||||
case CURVE_REF_DIFF:
|
||||
if (fw->getCapability(HasInputDiff))
|
||||
ret = true;
|
||||
break;
|
||||
case CURVE_REF_EXPO:
|
||||
if (fw->getCapability(HasMixerExpo))
|
||||
ret = true;
|
||||
break;
|
||||
case CURVE_REF_FUNC:
|
||||
case CURVE_REF_CUSTOM:
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// static
|
||||
bool CurveReference::isFunctionAvailable(const int value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
int CurveReference::functionCount()
|
||||
{
|
||||
return 6;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CurveReferenceUIManager
|
||||
*/
|
||||
|
||||
CurveReferenceUIManager::CurveReferenceUIManager(QComboBox * curveTypeCB, QCheckBox * curveGVarCB, QSpinBox * curveValueSB,
|
||||
QComboBox * curveValueCB, CurveReference & curveRef, const ModelData & model,
|
||||
CurveRefFilteredFactory * curveRefFilteredFactory, QObject * parent) :
|
||||
QObject(parent),
|
||||
curveTypeCB(curveTypeCB),
|
||||
curveGVarCB(curveGVarCB),
|
||||
curveValueSB(curveValueSB),
|
||||
curveValueCB(curveValueCB),
|
||||
curveRef(curveRef),
|
||||
model(model),
|
||||
lock(false),
|
||||
filteredModelFactory(curveRefFilteredFactory)
|
||||
{
|
||||
hasCapabilityGvars = getCurrentFirmware()->getCapability(Gvars);
|
||||
|
||||
if (curveTypeCB) {
|
||||
curveTypeCB->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_TYPE));
|
||||
curveTypeCB->setCurrentIndex(curveTypeCB->findData((int)curveRef.type));
|
||||
connect(curveTypeCB, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged(int)));
|
||||
}
|
||||
|
||||
if (curveGVarCB)
|
||||
connect(curveGVarCB, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int)));
|
||||
|
||||
if (curveValueSB) {
|
||||
curveValueSB->setMinimum(-100);
|
||||
curveValueSB->setMaximum(100);
|
||||
connect(curveValueSB, SIGNAL(editingFinished()), this, SLOT(valueSBChanged()));
|
||||
}
|
||||
|
||||
if (curveValueCB) {
|
||||
curveValueCB->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
curveValueCB->setMaxVisibleItems(10);
|
||||
connect(curveValueCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valueCBChanged()));
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
CurveReferenceUIManager::~CurveReferenceUIManager()
|
||||
{
|
||||
delete filteredModelFactory;
|
||||
}
|
||||
|
||||
#define CURVE_REF_UI_GVAR_SHOW (1<<0)
|
||||
#define CURVE_REF_UI_VALUE_SHOW (1<<1)
|
||||
#define CURVE_REF_UI_REF_SHOW (1<<2)
|
||||
|
||||
void CurveReferenceUIManager::update()
|
||||
{
|
||||
lock = true;
|
||||
int widgetsMask = 0;
|
||||
|
||||
if (curveRef.type == CurveReference::CURVE_REF_DIFF || curveRef.type == CurveReference::CURVE_REF_EXPO) {
|
||||
if (hasCapabilityGvars)
|
||||
widgetsMask |= CURVE_REF_UI_GVAR_SHOW;
|
||||
if (curveRef.isValueNumber()) {
|
||||
curveGVarCB->setChecked(false);
|
||||
curveValueSB->setValue(curveRef.value);
|
||||
widgetsMask |= CURVE_REF_UI_VALUE_SHOW;
|
||||
}
|
||||
else {
|
||||
curveGVarCB->setChecked(true);
|
||||
widgetsMask |= CURVE_REF_UI_REF_SHOW;
|
||||
}
|
||||
}
|
||||
else {
|
||||
widgetsMask |= CURVE_REF_UI_REF_SHOW;
|
||||
}
|
||||
|
||||
if(curveTypeCB) {
|
||||
curveTypeCB->setCurrentIndex(curveTypeCB->findData(curveRef.type));
|
||||
curveTypeCB->show();
|
||||
}
|
||||
if(curveGVarCB)
|
||||
curveGVarCB->setVisible(widgetsMask & CURVE_REF_UI_GVAR_SHOW);
|
||||
if(curveValueSB)
|
||||
curveValueSB->setVisible(widgetsMask & CURVE_REF_UI_VALUE_SHOW);
|
||||
if(curveValueCB) {
|
||||
if (curveRef.isValueReference())
|
||||
populateValueCB(curveValueCB);
|
||||
curveValueCB->setVisible(widgetsMask & CURVE_REF_UI_REF_SHOW);
|
||||
}
|
||||
|
||||
lock = false;
|
||||
}
|
||||
|
||||
void CurveReferenceUIManager::gvarCBChanged(int state)
|
||||
{
|
||||
if (!lock) {
|
||||
curveRef.value = CurveReference::getDefaultValue(curveRef.type, state);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void CurveReferenceUIManager::typeChanged(int value)
|
||||
{
|
||||
if (!lock) {
|
||||
CurveReference::CurveRefType type = (CurveReference::CurveRefType)curveTypeCB->itemData(curveTypeCB->currentIndex()).toInt();
|
||||
curveRef = CurveReference(type, CurveReference::getDefaultValue(type));
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void CurveReferenceUIManager::valueSBChanged()
|
||||
{
|
||||
if (!lock) {
|
||||
curveRef.value = curveValueSB->value();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void CurveReferenceUIManager::valueCBChanged()
|
||||
{
|
||||
if (!lock) {
|
||||
curveRef.value = curveValueCB->itemData(curveValueCB->currentIndex()).toInt();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void CurveReferenceUIManager::populateValueCB(QComboBox * cb)
|
||||
{
|
||||
if (cb) {
|
||||
switch (curveRef.type) {
|
||||
case CurveReference::CURVE_REF_DIFF:
|
||||
case CurveReference::CURVE_REF_EXPO:
|
||||
cb->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_GVARREF));
|
||||
break;
|
||||
case CurveReference::CURVE_REF_FUNC:
|
||||
cb->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_FUNC));
|
||||
break;
|
||||
case CurveReference::CURVE_REF_CUSTOM:
|
||||
cb->setModel(filteredModelFactory->getItemModel(CurveRefFilteredFactory::CRFIM_CURVE));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
cb->setCurrentIndex(cb->findData(curveRef.value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,35 +22,101 @@
|
||||
#define CURVEREFERENCE_H
|
||||
|
||||
#include <QtCore>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QSpinBox>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
|
||||
class ModelData;
|
||||
class CurveRefFilteredFactory;
|
||||
|
||||
class CurveReference {
|
||||
|
||||
Q_DECLARE_TR_FUNCTIONS(CurveReference)
|
||||
|
||||
public:
|
||||
|
||||
enum CurveRefType {
|
||||
CURVE_REF_DIFF,
|
||||
CURVE_REF_EXPO,
|
||||
CURVE_REF_FUNC,
|
||||
CURVE_REF_CUSTOM
|
||||
CURVE_REF_CUSTOM,
|
||||
MAX_CURVE_REF_TYPE = CURVE_REF_CUSTOM
|
||||
};
|
||||
|
||||
enum CurveRefGroups {
|
||||
NoneGroup = 0x001,
|
||||
NegativeGroup = 0x002,
|
||||
PositiveGroup = 0x004,
|
||||
|
||||
AllCurveRefGroups = NoneGroup | NegativeGroup | PositiveGroup,
|
||||
PositiveCurveRefGroups = AllCurveRefGroups &~ NegativeGroup
|
||||
};
|
||||
|
||||
CurveReference() { clear(); }
|
||||
|
||||
CurveReference(CurveRefType type, int value):
|
||||
type(type),
|
||||
value(value)
|
||||
{
|
||||
}
|
||||
CurveReference(CurveRefType type, int value) : type(type), value(value) { ; }
|
||||
|
||||
void clear() { memset(this, 0, sizeof(CurveReference)); }
|
||||
const bool isEmpty() const { return type == CURVE_REF_DIFF && value == 0; }
|
||||
const bool isSet() const { return !isEmpty(); }
|
||||
const bool isValueNumber() const;
|
||||
const bool isValueReference() const { return !isValueNumber(); }
|
||||
const QString toString(const ModelData * model = nullptr, bool verbose = true) const;
|
||||
const bool isAvailable() const;
|
||||
|
||||
CurveRefType type;
|
||||
int value;
|
||||
|
||||
QString toString(const ModelData * model = NULL, bool verbose = true) const;
|
||||
bool isSet() const { return type != CURVE_REF_DIFF || value != 0; }
|
||||
bool operator == ( const CurveReference & other) const {
|
||||
return (this->type == other.type) && (this->value == other.value);
|
||||
}
|
||||
|
||||
bool operator != ( const CurveReference & other) const {
|
||||
return (this->type != other.type) || (this->value != other.value);
|
||||
}
|
||||
|
||||
static int getDefaultValue(const CurveRefType type, const bool isGVar = false);
|
||||
static QString typeToString(const CurveRefType type);
|
||||
static QString functionToString(const int value);
|
||||
static bool isTypeAvailable(const CurveRefType type);
|
||||
static bool isFunctionAvailable(const int value);
|
||||
static int functionCount();
|
||||
};
|
||||
|
||||
class CurveReferenceUIManager : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CurveReferenceUIManager(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QSpinBox *curveValueSB, QComboBox *curveValueCB,
|
||||
CurveReference & curve, const ModelData & model, CurveRefFilteredFactory * curveRefFilteredFactory,
|
||||
QObject * parent = nullptr);
|
||||
|
||||
explicit CurveReferenceUIManager(QComboBox *curveValueCB, CurveReference & curve, const ModelData & model,
|
||||
CurveRefFilteredFactory * curveRefFilteredFactory, QObject * parent = nullptr) :
|
||||
CurveReferenceUIManager(nullptr, nullptr, nullptr, curveValueCB, curve, model, curveRefFilteredFactory, parent) {}
|
||||
|
||||
virtual ~CurveReferenceUIManager();
|
||||
|
||||
protected slots:
|
||||
void gvarCBChanged(int);
|
||||
void typeChanged(int);
|
||||
void valueSBChanged();
|
||||
void valueCBChanged();
|
||||
void update();
|
||||
|
||||
private:
|
||||
QComboBox *curveTypeCB;
|
||||
QCheckBox *curveGVarCB;
|
||||
QSpinBox *curveValueSB;
|
||||
QComboBox *curveValueCB;
|
||||
CurveReference & curveRef;
|
||||
const ModelData & model;
|
||||
bool lock;
|
||||
bool hasCapabilityGvars;
|
||||
CurveRefFilteredFactory *filteredModelFactory;
|
||||
void populateValueCB(QComboBox * cb);
|
||||
};
|
||||
|
||||
#endif // CURVEREFERENCE_H
|
||||
|
||||
@@ -22,6 +22,17 @@
|
||||
#include "eeprominterface.h"
|
||||
#include "radiodata.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
#include "compounditemmodels.h"
|
||||
|
||||
void CustomFunctionData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("CFN"), 8);
|
||||
cstate.setSubComp(nameToString(cstate.subCompIdx, (cstate.toModel() ? false : true)));
|
||||
swtch.convert(cstate);
|
||||
if (func == FuncVolume || func == FuncBacklight || func == FuncPlayValue || (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast && adjustMode == 1)) {
|
||||
param = RawSource(param).convert(cstate.withComponentField("PARAM")).toValue();
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFunctionData::clear()
|
||||
{
|
||||
@@ -36,17 +47,24 @@ bool CustomFunctionData::isEmpty() const
|
||||
return (swtch.type == SWITCH_TYPE_NONE);
|
||||
}
|
||||
|
||||
QString CustomFunctionData::nameToString(int index, bool globalContext) const
|
||||
// static
|
||||
QString CustomFunctionData::nameToString(const int index, const bool globalContext)
|
||||
{
|
||||
return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index+1, 0, true);
|
||||
return RadioData::getElementName((globalContext ? tr("GF") : tr("SF")), index + 1, 0, true);
|
||||
}
|
||||
|
||||
QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||
{
|
||||
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32)
|
||||
return funcToString(func, model);
|
||||
}
|
||||
|
||||
// static
|
||||
QString CustomFunctionData::funcToString(const AssignFunc func, const ModelData * model)
|
||||
{
|
||||
if (func >= FuncOverrideCH1 && func <= FuncOverrideCHLast)
|
||||
return tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
|
||||
else if (func == FuncTrainer)
|
||||
return tr("Trainer");
|
||||
return tr("Trainer Sticks");
|
||||
else if (func == FuncTrainerRUD)
|
||||
return tr("Trainer RUD");
|
||||
else if (func == FuncTrainerELE)
|
||||
@@ -65,8 +83,8 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||
return tr("Haptic");
|
||||
else if (func == FuncReset)
|
||||
return tr("Reset");
|
||||
else if (func >= FuncSetTimer1 && func <= FuncSetTimer3)
|
||||
return tr("Set Timer %1").arg(func-FuncSetTimer1+1);
|
||||
else if (func >= FuncSetTimer1 && func <= FuncSetTimerLast)
|
||||
return tr("Set %1").arg(RawSource(SOURCE_TYPE_SPECIAL, SOURCE_TYPE_SPECIAL_TIMER1_IDX + func - FuncSetTimer1).toString(model));
|
||||
else if (func == FuncVario)
|
||||
return tr("Vario");
|
||||
else if (func == FuncPlayPrompt)
|
||||
@@ -76,7 +94,7 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||
else if (func == FuncPlayValue)
|
||||
return tr("Play Value");
|
||||
else if (func == FuncPlayScript)
|
||||
return tr("Play Script");
|
||||
return tr("Lua Script");
|
||||
else if (func == FuncLogs)
|
||||
return tr("SD Logs");
|
||||
else if (func == FuncVolume)
|
||||
@@ -90,106 +108,44 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||
else if (func == FuncBackgroundMusicPause)
|
||||
return tr("Background Music Pause");
|
||||
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast)
|
||||
return tr("Adjust %1").arg(RawSource(SOURCE_TYPE_GVAR, func-FuncAdjustGV1).toString(model));
|
||||
else if (func == FuncSetFailsafeInternalModule)
|
||||
return tr("SetFailsafe Int. Module");
|
||||
else if (func == FuncSetFailsafeExternalModule)
|
||||
return tr("SetFailsafe Ext. Module");
|
||||
return tr("Adjust %1").arg(RawSource(SOURCE_TYPE_GVAR, func - FuncAdjustGV1).toString(model));
|
||||
else if (func == FuncSetFailsafe)
|
||||
return tr("Set Failsafe");
|
||||
else if (func == FuncRangeCheckInternalModule)
|
||||
return tr("RangeCheck Int. Module");
|
||||
return tr("Range Check Int. Module");
|
||||
else if (func == FuncRangeCheckExternalModule)
|
||||
return tr("RangeCheck Ext. Module");
|
||||
return tr("Range Check Ext. Module");
|
||||
else if (func == FuncBindInternalModule)
|
||||
return tr("Bind Int. Module");
|
||||
else if (func == FuncBindExternalModule)
|
||||
return tr("Bind Ext. Module");
|
||||
else {
|
||||
return QString("???"); // Highlight unknown functions with output of question marks.(BTW should not happen that we do not know what a function is)
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox * b, unsigned int value = 0)
|
||||
{
|
||||
int val = 0;
|
||||
Firmware * firmware = Firmware::getCurrentVariant();
|
||||
|
||||
b->addItem(tr("Timer1"), val++);
|
||||
b->addItem(tr("Timer2"), val++);
|
||||
b->addItem( tr("Timer3"), val++);
|
||||
b->addItem(tr("Flight"), val++);
|
||||
b->addItem(tr("Telemetry"), val++);
|
||||
int reCount = firmware->getCapability(RotaryEncoders);
|
||||
if (reCount == 1) {
|
||||
b->addItem(tr("Rotary Encoder"), val++);
|
||||
}
|
||||
else if (reCount == 2) {
|
||||
b->addItem(tr("REa"), val++);
|
||||
b->addItem(tr("REb"), val++);
|
||||
}
|
||||
if ((int)value < b->count()) {
|
||||
b->setCurrentIndex(value);
|
||||
}
|
||||
if (model) {
|
||||
for (unsigned i=0; i<CPN_MAX_SENSORS; ++i) {
|
||||
if (model->sensorData[i].isAvailable()) {
|
||||
RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3*i);
|
||||
b->addItem(item.toString(model), val+i);
|
||||
if (value == val+i) {
|
||||
b->setCurrentIndex(b->count()-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFunctionData::populatePlaySoundParams(QStringList & qs)
|
||||
{
|
||||
qs <<"Beep 1" << "Beep 2" << "Beep 3" << "Warn1" << "Warn2" << "Cheep" << "Ratata" << "Tick" << "Siren" << "Ring" ;
|
||||
qs << "SciFi" << "Robot" << "Chirp" << "Tada" << "Crickt" << "AlmClk" ;
|
||||
}
|
||||
|
||||
void CustomFunctionData::populateHapticParams(QStringList & qs)
|
||||
{
|
||||
qs << "0" << "1" << "2" << "3";
|
||||
}
|
||||
|
||||
QString CustomFunctionData::paramToString(const ModelData * model) const
|
||||
{
|
||||
QStringList qs;
|
||||
if (func <= FuncInstantTrim) {
|
||||
return QString("%1").arg(param);
|
||||
}
|
||||
else if (func==FuncLogs) {
|
||||
return QString("%1").arg(param/10.0) + tr("s");
|
||||
else if (func == FuncLogs) {
|
||||
return QString("%1").arg(param / 10.0) + tr("s");
|
||||
}
|
||||
else if (func==FuncPlaySound) {
|
||||
CustomFunctionData::populatePlaySoundParams(qs);
|
||||
if (param>=0 && param<(int)qs.count())
|
||||
return qs.at(param);
|
||||
else
|
||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
||||
else if (func == FuncPlaySound) {
|
||||
return playSoundToString(param);
|
||||
}
|
||||
else if (func==FuncPlayHaptic) {
|
||||
CustomFunctionData::populateHapticParams(qs);
|
||||
if (param>=0 && param<(int)qs.count())
|
||||
return qs.at(param);
|
||||
else
|
||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
||||
else if (func == FuncPlayHaptic) {
|
||||
return harpicToString(param);
|
||||
}
|
||||
else if (func==FuncReset) {
|
||||
QComboBox cb;
|
||||
CustomFunctionData::populateResetParams(model, &cb);
|
||||
int pos = cb.findData(param);
|
||||
if (pos >= 0)
|
||||
return cb.itemText(pos);
|
||||
else
|
||||
return tr("<font color=red><b>Inconsistent parameter</b></font>");
|
||||
else if (func == FuncReset) {
|
||||
return resetToString(param, model);
|
||||
}
|
||||
else if ((func==FuncVolume)|| (func==FuncPlayValue)) {
|
||||
RawSource item(param);
|
||||
return item.toString(model);
|
||||
else if (func == FuncVolume || func == FuncPlayValue || func == FuncBacklight) {
|
||||
return RawSource(param).toString(model);
|
||||
}
|
||||
else if ((func==FuncPlayPrompt) || (func==FuncPlayBoth)) {
|
||||
else if (func == FuncPlayPrompt || func == FuncPlayBoth) {
|
||||
if ( getCurrentFirmware()->getCapability(VoicesAsNumbers)) {
|
||||
return QString("%1").arg(param);
|
||||
}
|
||||
@@ -197,19 +153,17 @@ QString CustomFunctionData::paramToString(const ModelData * model) const
|
||||
return paramarm;
|
||||
}
|
||||
}
|
||||
else if ((func>=FuncAdjustGV1) && (func<FuncCount)) {
|
||||
else if (func >= FuncAdjustGV1 && func < FuncCount) {
|
||||
switch (adjustMode) {
|
||||
case FUNC_ADJUST_GVAR_CONSTANT:
|
||||
return tr("Value ")+QString("%1").arg(param);
|
||||
return gvarAdjustModeToString(adjustMode) + QString(" %1").arg(param);
|
||||
case FUNC_ADJUST_GVAR_SOURCE:
|
||||
case FUNC_ADJUST_GVAR_GVAR:
|
||||
return RawSource(param).toString();
|
||||
case FUNC_ADJUST_GVAR_INCDEC:
|
||||
float val;
|
||||
QString unit;
|
||||
val = param * model->gvarData[func - FuncAdjustGV1].multiplierGet();
|
||||
unit = model->gvarData[func - FuncAdjustGV1].unitToString();
|
||||
return QString("Increment: %1%2").arg(val).arg(unit);
|
||||
const float val = param * model->gvarData[func - FuncAdjustGV1].multiplierGet();
|
||||
const QString unit = model->gvarData[func - FuncAdjustGV1].unitToString();
|
||||
return gvarAdjustModeToString(adjustMode) + QString(": %1%2").arg(val).arg(unit);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
@@ -217,25 +171,31 @@ QString CustomFunctionData::paramToString(const ModelData * model) const
|
||||
|
||||
QString CustomFunctionData::repeatToString() const
|
||||
{
|
||||
if (repeatParam == -1) {
|
||||
return tr("played once, not during startup");
|
||||
return repeatToString(repeatParam);
|
||||
}
|
||||
|
||||
// static
|
||||
QString CustomFunctionData::repeatToString(const int value)
|
||||
{
|
||||
if (value == -1) {
|
||||
return tr("Played once, not during startup");
|
||||
}
|
||||
else if (repeatParam == 0) {
|
||||
return "";
|
||||
else if (value == 0) {
|
||||
return tr("No repeat");
|
||||
}
|
||||
else {
|
||||
unsigned int step = 1;
|
||||
return tr("repeat(%1s)").arg(step*repeatParam);
|
||||
return tr("Repeat %1s").arg(value);
|
||||
}
|
||||
}
|
||||
|
||||
QString CustomFunctionData::enabledToString() const
|
||||
{
|
||||
if ((func>=FuncOverrideCH1 && func<=FuncOverrideCH32) ||
|
||||
(func>=FuncAdjustGV1 && func<=FuncAdjustGVLast) ||
|
||||
(func==FuncReset) ||
|
||||
(func>=FuncSetTimer1 && func<=FuncSetTimer2) ||
|
||||
(func==FuncVolume) ||
|
||||
if ((func >= FuncOverrideCH1 && func <= FuncOverrideCHLast) ||
|
||||
(func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) ||
|
||||
(func == FuncReset) ||
|
||||
(func >= FuncSetTimer1 && func <= FuncSetTimerLast) ||
|
||||
(func == FuncVolume) ||
|
||||
(func == FuncBacklight) ||
|
||||
(func <= FuncInstantTrim)) {
|
||||
if (!enabled) {
|
||||
return tr("DISABLED");
|
||||
@@ -244,12 +204,197 @@ QString CustomFunctionData::enabledToString() const
|
||||
return "";
|
||||
}
|
||||
|
||||
void CustomFunctionData::convert(RadioDataConversionState & cstate)
|
||||
// static
|
||||
bool CustomFunctionData::isFuncAvailable(const int index)
|
||||
{
|
||||
cstate.setComponent(tr("CFN"), 8);
|
||||
cstate.setSubComp(nameToString(cstate.subCompIdx, (cstate.toModel() ? false : true)));
|
||||
swtch.convert(cstate);
|
||||
if (func == FuncVolume || func == FuncPlayValue || (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast && adjustMode == 1)) {
|
||||
param = RawSource(param).convert(cstate.withComponentField("PARAM")).toValue();
|
||||
Firmware * fw = getCurrentFirmware();
|
||||
|
||||
bool ret = (((index >= FuncOverrideCH1 && index <= FuncOverrideCHLast) && !fw->getCapability(SafetyChannelCustomFunction)) ||
|
||||
((index == FuncVolume || index == FuncBackgroundMusic || index == FuncBackgroundMusicPause) && !fw->getCapability(HasVolume)) ||
|
||||
((index == FuncPlayScript && !IS_HORUS_OR_TARANIS(fw->getBoard()))) ||
|
||||
((index == FuncPlayHaptic) && !fw->getCapability(Haptic)) ||
|
||||
((index == FuncPlayBoth) && !fw->getCapability(HasBeeper)) ||
|
||||
((index == FuncLogs) && !fw->getCapability(HasSDLogs)) ||
|
||||
((index >= FuncSetTimer1 && index <= FuncSetTimerLast) && index > FuncSetTimer1 + fw->getCapability(Timers)) ||
|
||||
((index == FuncScreenshot) && !IS_HORUS_OR_TARANIS(fw->getBoard())) ||
|
||||
((index >= FuncRangeCheckInternalModule && index <= FuncBindExternalModule) && !fw->getCapability(DangerousFunctions)) ||
|
||||
((index >= FuncAdjustGV1 && index <= FuncAdjustGVLast) && !fw->getCapability(Gvars))
|
||||
);
|
||||
return !ret;
|
||||
}
|
||||
|
||||
// static
|
||||
int CustomFunctionData::funcContext(const int index)
|
||||
{
|
||||
int ret = AllFunctionContexts;
|
||||
|
||||
if ((index >= FuncOverrideCH1 && index <= FuncOverrideCHLast) ||
|
||||
(index >= FuncRangeCheckInternalModule && index <= FuncBindExternalModule) ||
|
||||
(index >= FuncAdjustGV1 && index <= FuncAdjustGVLast))
|
||||
ret &= ~GlobalFunctionsContext;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// static
|
||||
QString CustomFunctionData::resetToString(const int value, const ModelData * model)
|
||||
{
|
||||
Firmware * firmware = getCurrentFirmware();
|
||||
int step = CPN_MAX_TIMERS;
|
||||
|
||||
if (value < step) {
|
||||
if (value < firmware->getCapability(Timers))
|
||||
return RawSource(SOURCE_TYPE_SPECIAL, value + SOURCE_TYPE_SPECIAL_TIMER1_IDX).toString(model);
|
||||
else
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
|
||||
if (value < ++step)
|
||||
return tr("Flight");
|
||||
|
||||
if (value < ++step)
|
||||
return tr("Telemetry");
|
||||
|
||||
if (value < step + firmware->getCapability(Sensors))
|
||||
return RawSource(SOURCE_TYPE_TELEMETRY, 3 * (value - step)).toString(model);
|
||||
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
|
||||
// static
|
||||
int CustomFunctionData::resetParamCount()
|
||||
{
|
||||
Firmware * firmware = getCurrentFirmware();
|
||||
|
||||
return CPN_MAX_TIMERS + 2 + firmware->getCapability(Sensors);
|
||||
}
|
||||
|
||||
// static
|
||||
bool CustomFunctionData::isResetParamAvailable(const int index, const ModelData * model)
|
||||
{
|
||||
Firmware * firmware = getCurrentFirmware();
|
||||
|
||||
if (index < CPN_MAX_TIMERS) {
|
||||
if (index < firmware->getCapability(Timers))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else if (index < CPN_MAX_TIMERS + 2)
|
||||
return true;
|
||||
else if (model && index < resetParamCount())
|
||||
return model->sensorData[index - (CPN_MAX_TIMERS + 2)].isAvailable();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString CustomFunctionData::harpicToString() const
|
||||
{
|
||||
return harpicToString(param);
|
||||
}
|
||||
|
||||
// static
|
||||
QString CustomFunctionData::harpicToString(const int value)
|
||||
{
|
||||
return QString("%1").arg(value);
|
||||
}
|
||||
|
||||
// static
|
||||
QStringList CustomFunctionData::playSoundStringList()
|
||||
{
|
||||
return QStringList({ tr("Beep 1"), tr("Beep 2"), tr("Beep 3"), tr("Warn 1"), tr("Warn 2"), tr("Cheep"), tr("Ratata"), tr("Tick"),
|
||||
tr("Siren"), tr("Ring"), tr("Sci Fi"), tr("Robot"), tr("Chirp"), tr("Tada"), tr("Cricket"), tr("Alarm Clock") });
|
||||
}
|
||||
|
||||
QString CustomFunctionData::playSoundToString() const
|
||||
{
|
||||
return playSoundToString(param);
|
||||
}
|
||||
|
||||
// static
|
||||
QString CustomFunctionData::playSoundToString(const int value)
|
||||
{
|
||||
const QStringList strl = playSoundStringList();
|
||||
if (value < strl.count())
|
||||
return strl.at(value);
|
||||
else
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
|
||||
QString CustomFunctionData::gvarAdjustModeToString() const
|
||||
{
|
||||
return gvarAdjustModeToString(adjustMode);
|
||||
}
|
||||
|
||||
// static
|
||||
QString CustomFunctionData::gvarAdjustModeToString(const int value)
|
||||
{
|
||||
switch (value) {
|
||||
case FUNC_ADJUST_GVAR_CONSTANT:
|
||||
return tr("Value");
|
||||
case FUNC_ADJUST_GVAR_SOURCE:
|
||||
return tr("Source");
|
||||
case FUNC_ADJUST_GVAR_GVAR:
|
||||
return tr("Global Variable");
|
||||
case FUNC_ADJUST_GVAR_INCDEC:
|
||||
return tr("Inc/Decrement");
|
||||
default:
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * CustomFunctionData::repeatItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName("customfunctiondata.repeat");
|
||||
|
||||
for (int i = -1; i <= 60; i++) {
|
||||
mdl->appendToItemList(repeatToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * CustomFunctionData::playSoundItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName("customfunctiondata.playsound");
|
||||
|
||||
for (int i = 0; i < playSoundStringList().count(); i++) {
|
||||
mdl->appendToItemList(playSoundToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * CustomFunctionData::harpicItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName("customfunctiondata.harpic");
|
||||
|
||||
for (int i = 0; i <= 3; i++) {
|
||||
mdl->appendToItemList(harpicToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * CustomFunctionData::gvarAdjustModeItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName("customfunctiondata.gvaradjustmode");
|
||||
|
||||
for (int i = 0; i < FUNC_ADJUST_GVAR_COUNT; i++) {
|
||||
mdl->appendToItemList(gvarAdjustModeToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef CUSTOMFUNCTIONDATA_H
|
||||
#define CUSTOMFUNCTIONDATA_H
|
||||
#pragma once
|
||||
|
||||
#include "boards.h"
|
||||
#include "constants.h"
|
||||
@@ -32,10 +31,12 @@ class Firmware;
|
||||
class ModelData;
|
||||
class GeneralSettings;
|
||||
class RadioDataConversionState;
|
||||
class AbstractStaticItemModel;
|
||||
|
||||
enum AssignFunc {
|
||||
FuncOverrideCH1 = 0,
|
||||
FuncOverrideCH32 = FuncOverrideCH1+CPN_MAX_CHNOUT-1,
|
||||
FuncOverrideCHLast = FuncOverrideCH1 + CPN_MAX_CHNOUT - 1,
|
||||
FuncOverrideCH32 = FuncOverrideCHLast, // TODO remove
|
||||
FuncTrainer,
|
||||
FuncTrainerRUD,
|
||||
FuncTrainerELE,
|
||||
@@ -47,8 +48,9 @@ enum AssignFunc {
|
||||
FuncPlayHaptic,
|
||||
FuncReset,
|
||||
FuncSetTimer1,
|
||||
FuncSetTimer2,
|
||||
FuncSetTimer3,
|
||||
FuncSetTimer2, // TODO remove
|
||||
FuncSetTimer3, // TODO remove
|
||||
FuncSetTimerLast = FuncSetTimer1 + CPN_MAX_TIMERS - 1,
|
||||
FuncVario,
|
||||
FuncPlayPrompt,
|
||||
FuncPlayBoth,
|
||||
@@ -61,9 +63,8 @@ enum AssignFunc {
|
||||
FuncBackgroundMusic,
|
||||
FuncBackgroundMusicPause,
|
||||
FuncAdjustGV1,
|
||||
FuncAdjustGVLast = FuncAdjustGV1+CPN_MAX_GVARS-1,
|
||||
FuncSetFailsafeInternalModule,
|
||||
FuncSetFailsafeExternalModule,
|
||||
FuncAdjustGVLast = FuncAdjustGV1 + CPN_MAX_GVARS - 1,
|
||||
FuncSetFailsafe,
|
||||
FuncRangeCheckInternalModule,
|
||||
FuncRangeCheckExternalModule,
|
||||
FuncBindInternalModule,
|
||||
@@ -77,14 +78,23 @@ enum GVarAdjustModes
|
||||
FUNC_ADJUST_GVAR_CONSTANT,
|
||||
FUNC_ADJUST_GVAR_SOURCE,
|
||||
FUNC_ADJUST_GVAR_GVAR,
|
||||
FUNC_ADJUST_GVAR_INCDEC
|
||||
FUNC_ADJUST_GVAR_INCDEC,
|
||||
FUNC_ADJUST_GVAR_COUNT
|
||||
};
|
||||
|
||||
class CustomFunctionData {
|
||||
Q_DECLARE_TR_FUNCTIONS(CustomFunctionData)
|
||||
|
||||
public:
|
||||
CustomFunctionData(AssignFunc func=FuncOverrideCH1) { clear(); this->func = func; }
|
||||
enum CustomFunctionContext
|
||||
{
|
||||
GlobalFunctionsContext = 0x01,
|
||||
SpecialFunctionsContext = 0x02,
|
||||
|
||||
AllFunctionContexts = GlobalFunctionsContext | SpecialFunctionsContext
|
||||
};
|
||||
|
||||
CustomFunctionData(AssignFunc func = FuncOverrideCH1) { clear(); this->func = func; }
|
||||
RawSwitch swtch;
|
||||
AssignFunc func;
|
||||
int param;
|
||||
@@ -93,21 +103,33 @@ class CustomFunctionData {
|
||||
unsigned int adjustMode;
|
||||
int repeatParam;
|
||||
|
||||
void clear();
|
||||
bool isEmpty() const;
|
||||
QString nameToString(int index, bool globalContext = false) const;
|
||||
QString funcToString(const ModelData * model = NULL) const;
|
||||
QString paramToString(const ModelData * model) const;
|
||||
QString repeatToString() const;
|
||||
QString enabledToString() const;
|
||||
|
||||
static void populateResetParams(const ModelData * model, QComboBox * b, unsigned int value);
|
||||
static void populatePlaySoundParams(QStringList & qs);
|
||||
static void populateHapticParams(QStringList & qs);
|
||||
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
|
||||
void clear();
|
||||
bool isEmpty() const;
|
||||
QString funcToString(const ModelData * model = nullptr) const;
|
||||
QString paramToString(const ModelData * model = nullptr) const;
|
||||
QString repeatToString() const;
|
||||
QString enabledToString() const;
|
||||
QString playSoundToString() const;
|
||||
QString harpicToString() const;
|
||||
QString gvarAdjustModeToString() const;
|
||||
|
||||
static QString nameToString(const int index, const bool globalContext = false);
|
||||
static QString funcToString(const AssignFunc func, const ModelData * model = nullptr);
|
||||
static bool isFuncAvailable(const int index);
|
||||
static int funcContext(const int index);
|
||||
static QString resetToString(const int value, const ModelData * model = nullptr);
|
||||
static int resetParamCount();
|
||||
static bool isResetParamAvailable(const int index, const ModelData * model = nullptr);
|
||||
static QString repeatToString(const int value);
|
||||
static QStringList playSoundStringList();
|
||||
static QString playSoundToString(const int value);
|
||||
static QString harpicToString(const int value);
|
||||
static QStringList gvarAdjustModeStringList();
|
||||
static QString gvarAdjustModeToString(const int value);
|
||||
static AbstractStaticItemModel * repeatItemModel();
|
||||
static AbstractStaticItemModel * playSoundItemModel();
|
||||
static AbstractStaticItemModel * harpicItemModel();
|
||||
static AbstractStaticItemModel * gvarAdjustModeItemModel();
|
||||
};
|
||||
|
||||
|
||||
#endif // CUSTOMFUNCTIONDATA_H
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "datahelpers.h"
|
||||
|
||||
QString DataHelpers::boolToString(const bool value, const BoolFormat format)
|
||||
{
|
||||
static const char *strings[] = {
|
||||
QT_TRANSLATE_NOOP("DataHelpers", "Disabled"),
|
||||
QT_TRANSLATE_NOOP("DataHelpers", "Enabled"),
|
||||
QT_TRANSLATE_NOOP("DataHelpers", "OFF"),
|
||||
QT_TRANSLATE_NOOP("DataHelpers", "ON"),
|
||||
QT_TRANSLATE_NOOP("DataHelpers", "False"),
|
||||
QT_TRANSLATE_NOOP("DataHelpers", "True"),
|
||||
QT_TRANSLATE_NOOP("DataHelpers", "N"),
|
||||
QT_TRANSLATE_NOOP("DataHelpers", "Y"),
|
||||
QT_TRANSLATE_NOOP("DataHelpers", "No"),
|
||||
QT_TRANSLATE_NOOP("DataHelpers", "Yes")
|
||||
};
|
||||
|
||||
return QCoreApplication::translate("DataHelpers", strings[format * 2 + value]);
|
||||
}
|
||||
|
||||
QString DataHelpers::getElementName(const QString & prefix, const unsigned int index, const char * name, const bool padding)
|
||||
{
|
||||
QString result = prefix;
|
||||
result.append(padding ? QString("%1").arg(index, 2, 10, QChar('0')) : QString("%1").arg(index));
|
||||
if (name && QString(name).trimmed().length() > 0)
|
||||
result.append(":" + QString(name).trimmed());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString DataHelpers::timeToString(const int value, const unsigned int mask)
|
||||
{
|
||||
bool negative = value < 0 ? true : false;
|
||||
int val = abs(value);
|
||||
|
||||
QString result = QString("%1").arg(negative ? "-" : ((mask & TIMESTR_MASK_PADSIGN) ? " " : ""));
|
||||
|
||||
if (mask & TIMESTR_MASK_HRSMINS) {
|
||||
int hours = val / 3600;
|
||||
if (hours > 0 || (mask & TIMESTR_MASK_ZEROHRS)) {
|
||||
val -= hours * 3600;
|
||||
result.append(QString("%1:").arg(hours, 2, 10, QLatin1Char('0')));
|
||||
}
|
||||
}
|
||||
|
||||
int minutes = val / 60;
|
||||
int seconds = val % 60;
|
||||
result.append(QString("%1:%2").arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0')));
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class FieldRange
|
||||
{
|
||||
public:
|
||||
FieldRange():
|
||||
decimals(0),
|
||||
min(0.0),
|
||||
max(0.0),
|
||||
step(1.0),
|
||||
offset(0.0),
|
||||
prefix(""),
|
||||
unit("")
|
||||
{
|
||||
}
|
||||
|
||||
float getValue(int value) { return float(value) * step; }
|
||||
|
||||
int decimals;
|
||||
double min;
|
||||
double max;
|
||||
double step;
|
||||
double offset;
|
||||
QString prefix;
|
||||
QString unit;
|
||||
};
|
||||
|
||||
|
||||
constexpr unsigned int TIMESTR_MASK_HRSMINS { 1 << 1 };
|
||||
constexpr unsigned int TIMESTR_MASK_ZEROHRS { 1 << 2 };
|
||||
constexpr unsigned int TIMESTR_MASK_PADSIGN { 1 << 3 };
|
||||
|
||||
namespace DataHelpers
|
||||
{
|
||||
enum BoolFormat {
|
||||
BOOL_FMT_ENABLEDISABLE,
|
||||
BOOL_FMT_ONOFF,
|
||||
BOOL_FMT_TRUEFALSE,
|
||||
BOOL_FMT_YN,
|
||||
BOOL_FMT_YESNO
|
||||
};
|
||||
|
||||
QString boolToString(const bool value, const BoolFormat format);
|
||||
QString getElementName(const QString & prefix, const unsigned int index, const char * name = 0, const bool padding = false);
|
||||
QString timeToString(const int value, const unsigned int mask);
|
||||
|
||||
}
|
||||
@@ -151,6 +151,7 @@ enum Capability {
|
||||
DangerousFunctions,
|
||||
HasModelCategories,
|
||||
HasSwitchableJack,
|
||||
HasSportConnector,
|
||||
PwrButtonPress,
|
||||
Sensors
|
||||
};
|
||||
|
||||
@@ -18,121 +18,17 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "io_data.h"
|
||||
|
||||
#include "radiodata.h" // for RadioData::getElementName
|
||||
#include "flightmodedata.h"
|
||||
#include "radiodata.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
/*
|
||||
* ExpoData
|
||||
*/
|
||||
|
||||
void ExpoData::convert(RadioDataConversionState & cstate)
|
||||
void FlightModeData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("INP"), 3);
|
||||
cstate.setSubComp(RawSource(SOURCE_TYPE_VIRTUAL_INPUT, chn).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx));
|
||||
srcRaw.convert(cstate);
|
||||
cstate.setComponent("FMD", 2);
|
||||
cstate.setSubComp(nameToString(cstate.subCompIdx));
|
||||
swtch.convert(cstate);
|
||||
}
|
||||
|
||||
bool ExpoData::isEmpty() const
|
||||
{
|
||||
return (chn == 0 && mode == INPUT_MODE_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
* MixData
|
||||
*/
|
||||
|
||||
void MixData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("MIX"), 4);
|
||||
cstate.setSubComp(RawSource(SOURCE_TYPE_CH, destCh-1).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx));
|
||||
srcRaw.convert(cstate);
|
||||
swtch.convert(cstate);
|
||||
}
|
||||
|
||||
bool MixData::isEmpty() const
|
||||
{
|
||||
return (destCh == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* LimitData
|
||||
*/
|
||||
|
||||
QString LimitData::minToString() const
|
||||
{
|
||||
return QString::number((qreal)min/10);
|
||||
}
|
||||
|
||||
QString LimitData::maxToString() const
|
||||
{
|
||||
return QString::number((qreal)max/10);
|
||||
}
|
||||
|
||||
QString LimitData::revertToString() const
|
||||
{
|
||||
return revert ? tr("INV") : tr("NOR");
|
||||
}
|
||||
|
||||
QString LimitData::nameToString(int index) const
|
||||
{
|
||||
return RadioData::getElementName(tr("CH"), index + 1, name);
|
||||
}
|
||||
|
||||
QString LimitData::offsetToString() const
|
||||
{
|
||||
return QString::number((qreal)offset/10, 'f', 1);
|
||||
}
|
||||
|
||||
void LimitData::clear()
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(LimitData));
|
||||
min = -1000;
|
||||
max = +1000;
|
||||
}
|
||||
|
||||
bool LimitData::isEmpty() const
|
||||
{
|
||||
return (min == -1000 && max == 1000 && !revert && !offset && !ppmCenter && !symetrical && name[0] == '\0' && !curve.isSet());
|
||||
}
|
||||
|
||||
/*
|
||||
* CurveData
|
||||
*/
|
||||
|
||||
CurveData::CurveData()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void CurveData::clear(int count)
|
||||
{
|
||||
memset(this, 0, sizeof(CurveData));
|
||||
this->count = count;
|
||||
}
|
||||
|
||||
bool CurveData::isEmpty() const
|
||||
{
|
||||
for (int i=0; i<count; i++) {
|
||||
if (points[i].y != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QString CurveData::nameToString(const int idx) const
|
||||
{
|
||||
return RadioData::getElementName(tr("CV"), idx + 1, name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* FlightModeData
|
||||
*/
|
||||
|
||||
void FlightModeData::clear(const int phaseIdx)
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(FlightModeData));
|
||||
@@ -149,13 +45,6 @@ QString FlightModeData::nameToString(int phaseIdx) const
|
||||
return RadioData::getElementName(tr("FM"), phaseIdx, name); // names are zero-based, FM0, FM1, etc
|
||||
}
|
||||
|
||||
void FlightModeData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent("FMD", 2);
|
||||
cstate.setSubComp(nameToString(cstate.subCompIdx));
|
||||
swtch.convert(cstate);
|
||||
}
|
||||
|
||||
bool FlightModeData::isEmpty(int phaseIdx) const
|
||||
{
|
||||
if (name[0] != '\0' || swtch.isSet() || fadeIn != 0 || fadeOut != 0)
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "constants.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class RadioDataConversionState;
|
||||
|
||||
#define FLIGHTMODE_NAME_LEN 10
|
||||
#define RENC_MAX_VALUE 1024
|
||||
#define RENC_MIN_VALUE -RENC_MAX_VALUE
|
||||
|
||||
class FlightModeData {
|
||||
Q_DECLARE_TR_FUNCTIONS(FlightModeData)
|
||||
|
||||
public:
|
||||
FlightModeData() { clear(0); }
|
||||
|
||||
int trimMode[CPN_MAX_TRIMS];
|
||||
int trimRef[CPN_MAX_TRIMS];
|
||||
int trim[CPN_MAX_TRIMS];
|
||||
RawSwitch swtch;
|
||||
char name[FLIGHTMODE_NAME_LEN + 1];
|
||||
unsigned int fadeIn;
|
||||
unsigned int fadeOut;
|
||||
int rotaryEncoders[CPN_MAX_ENCODERS];
|
||||
int gvars[CPN_MAX_GVARS];
|
||||
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
void clear(const int phaseIdx);
|
||||
bool isEmpty(int phaseIdx) const;
|
||||
QString nameToString(int phaseIdx) const;
|
||||
bool isGVarEmpty(int phaseIdx, int gvIdx) const;
|
||||
bool isREncEmpty(int phaseIdx, int reIdx) const;
|
||||
int linkedFlightModeZero(int phaseIdx, int maxOwnValue) const;
|
||||
int linkedGVarFlightModeZero(int phaseIdx) const;
|
||||
int linkedREncFlightModeZero(int phaseIdx) const;
|
||||
};
|
||||
@@ -94,6 +94,12 @@ GeneralSettings::GeneralSettings()
|
||||
vBatMin = -23; // 6.7V
|
||||
vBatMax = -37; // 8.3V
|
||||
}
|
||||
else if (IS_JUMPER_TLITE(board)) {
|
||||
// 1S Li-Ion
|
||||
vBatWarn = 32;
|
||||
vBatMin = -60; //3V
|
||||
vBatMax = -78; //4.2V
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
// NI-MH 7.2V, X9D, X9D+ and X7
|
||||
vBatWarn = 65;
|
||||
@@ -239,6 +245,10 @@ void GeneralSettings::setDefaultControlTypes(Board::Type board)
|
||||
switchConfig[i] = Boards::getSwitchInfo(board, i).config;
|
||||
}
|
||||
|
||||
// TLite does not have pots or sliders
|
||||
if (IS_JUMPER_TLITE(board))
|
||||
return;
|
||||
|
||||
// TODO: move to Boards, like with switches
|
||||
if (IS_FAMILY_HORUS_OR_T16(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
@@ -253,11 +263,11 @@ void GeneralSettings::setDefaultControlTypes(Board::Type board)
|
||||
potConfig[0] = Board::POT_WITHOUT_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
else if (IS_FAMILY_T12(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
else if (IS_JUMPER_T12(board)) {
|
||||
else if (IS_TARANIS(board)) {
|
||||
potConfig[0] = Board::POT_WITH_DETENT;
|
||||
potConfig[1] = Board::POT_WITH_DETENT;
|
||||
}
|
||||
@@ -329,14 +339,14 @@ void GeneralSettings::convert(RadioDataConversionState & cstate)
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_JUMPER_T12(cstate.toType)) {
|
||||
if (IS_FAMILY_T12(cstate.toType)) {
|
||||
if (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType)) {
|
||||
strncpy(switchName[4], switchName[5], sizeof(switchName[0]));
|
||||
strncpy(switchName[5], switchName[7], sizeof(switchName[0]));
|
||||
}
|
||||
}
|
||||
|
||||
else if (IS_JUMPER_T12(cstate.fromType)) {
|
||||
else if (IS_FAMILY_T12(cstate.fromType)) {
|
||||
if (IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) {
|
||||
strncpy(switchName[5], switchName[4], sizeof(switchName[0]));
|
||||
strncpy(switchName[7], switchName[5], sizeof(switchName[0]));
|
||||
|
||||
@@ -103,6 +103,7 @@ class GeneralSettings {
|
||||
bool disableRssiPoweroffAlarm;
|
||||
unsigned int usbMode;
|
||||
unsigned int jackMode;
|
||||
bool sportPower;
|
||||
BeeperMode hapticMode;
|
||||
unsigned int stickMode; // TODO enum
|
||||
int timezone;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "heli_data.h"
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rawsource.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class SwashRingData {
|
||||
Q_DECLARE_TR_FUNCTIONS(SwashRingData)
|
||||
|
||||
public:
|
||||
SwashRingData() { clear(); }
|
||||
|
||||
int elevatorWeight;
|
||||
int aileronWeight;
|
||||
int collectiveWeight;
|
||||
unsigned int type;
|
||||
RawSource collectiveSource;
|
||||
RawSource aileronSource;
|
||||
RawSource elevatorSource;
|
||||
unsigned int value;
|
||||
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(SwashRingData)); }
|
||||
};
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "input_data.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
void ExpoData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("INP"), 3);
|
||||
cstate.setSubComp(RawSource(SOURCE_TYPE_VIRTUAL_INPUT, chn).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx));
|
||||
srcRaw.convert(cstate);
|
||||
swtch.convert(cstate);
|
||||
}
|
||||
|
||||
bool ExpoData::isEmpty() const
|
||||
{
|
||||
return (chn == 0 && mode == INPUT_MODE_NONE);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "curvereference.h"
|
||||
#include "rawsource.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class RadioDataConversionState;
|
||||
|
||||
enum InputMode {
|
||||
INPUT_MODE_NONE,
|
||||
INPUT_MODE_POS,
|
||||
INPUT_MODE_NEG,
|
||||
INPUT_MODE_BOTH
|
||||
};
|
||||
|
||||
#define EXPODATA_NAME_LEN 10
|
||||
|
||||
class ExpoData {
|
||||
Q_DECLARE_TR_FUNCTIONS(ExpoData)
|
||||
|
||||
public:
|
||||
ExpoData() { clear(); }
|
||||
|
||||
RawSource srcRaw;
|
||||
unsigned int scale;
|
||||
unsigned int mode; // InputMode
|
||||
unsigned int chn;
|
||||
RawSwitch swtch;
|
||||
unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4
|
||||
int weight;
|
||||
int offset;
|
||||
CurveReference curve;
|
||||
int carryTrim;
|
||||
char name[EXPODATA_NAME_LEN + 1];
|
||||
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(ExpoData)); }
|
||||
bool isEmpty() const;
|
||||
};
|
||||
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef IO_DATA_H
|
||||
#define IO_DATA_H
|
||||
|
||||
#include "constants.h"
|
||||
#include "curvereference.h"
|
||||
#include "rawsource.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class RadioDataConversionState;
|
||||
|
||||
enum InputMode {
|
||||
INPUT_MODE_NONE,
|
||||
INPUT_MODE_POS,
|
||||
INPUT_MODE_NEG,
|
||||
INPUT_MODE_BOTH
|
||||
};
|
||||
|
||||
#define EXPODATA_NAME_LEN 10
|
||||
|
||||
class ExpoData {
|
||||
Q_DECLARE_TR_FUNCTIONS(ExpoData)
|
||||
|
||||
public:
|
||||
ExpoData() { clear(); }
|
||||
RawSource srcRaw;
|
||||
unsigned int scale;
|
||||
unsigned int mode; // InputMode
|
||||
unsigned int chn;
|
||||
RawSwitch swtch;
|
||||
unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4
|
||||
int weight;
|
||||
int offset;
|
||||
CurveReference curve;
|
||||
int carryTrim;
|
||||
char name[EXPODATA_NAME_LEN+1];
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(ExpoData)); }
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
bool isEmpty() const;
|
||||
};
|
||||
|
||||
enum MltpxValue {
|
||||
MLTPX_ADD=0,
|
||||
MLTPX_MUL=1,
|
||||
MLTPX_REP=2
|
||||
};
|
||||
|
||||
#define MIXDATA_NAME_LEN 10
|
||||
|
||||
class MixData {
|
||||
Q_DECLARE_TR_FUNCTIONS(MixData)
|
||||
|
||||
public:
|
||||
MixData() { clear(); }
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
|
||||
unsigned int destCh; // 1..CPN_MAX_CHNOUT
|
||||
RawSource srcRaw;
|
||||
int weight;
|
||||
RawSwitch swtch;
|
||||
CurveReference curve; //0=symmetrisch
|
||||
unsigned int delayUp;
|
||||
unsigned int delayDown;
|
||||
unsigned int speedUp; // Servogeschwindigkeit aus Tabelle (10ms Cycle)
|
||||
unsigned int speedDown; // 0 nichts
|
||||
int carryTrim;
|
||||
bool noExpo;
|
||||
MltpxValue mltpx; // multiplex method 0=+ 1=* 2=replace
|
||||
unsigned int mixWarn; // mixer warning
|
||||
unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4
|
||||
int sOffset;
|
||||
char name[MIXDATA_NAME_LEN+1];
|
||||
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(MixData)); }
|
||||
bool isEmpty() const;
|
||||
};
|
||||
|
||||
#define LIMITDATA_NAME_LEN 6
|
||||
|
||||
class LimitData {
|
||||
Q_DECLARE_TR_FUNCTIONS(LimitData)
|
||||
|
||||
public:
|
||||
LimitData() { clear(); }
|
||||
int min;
|
||||
int max;
|
||||
bool revert;
|
||||
int offset;
|
||||
int ppmCenter;
|
||||
bool symetrical;
|
||||
int failsafe;
|
||||
char name[LIMITDATA_NAME_LEN + 1];
|
||||
CurveReference curve;
|
||||
QString minToString() const;
|
||||
QString maxToString() const;
|
||||
QString offsetToString() const;
|
||||
QString revertToString() const;
|
||||
QString nameToString(int index) const;
|
||||
void clear();
|
||||
bool isEmpty() const;
|
||||
};
|
||||
|
||||
class CurvePoint {
|
||||
public:
|
||||
int8_t x;
|
||||
int8_t y;
|
||||
};
|
||||
|
||||
#define CURVEDATA_NAME_LEN 6
|
||||
|
||||
class CurveData {
|
||||
Q_DECLARE_TR_FUNCTIONS(CurveData)
|
||||
|
||||
public:
|
||||
enum CurveType {
|
||||
CURVE_TYPE_STANDARD,
|
||||
CURVE_TYPE_CUSTOM,
|
||||
CURVE_TYPE_LAST = CURVE_TYPE_CUSTOM
|
||||
};
|
||||
|
||||
CurveData();
|
||||
void clear(int count = 5);
|
||||
bool isEmpty() const;
|
||||
QString nameToString(const int idx) const;
|
||||
|
||||
CurveType type;
|
||||
bool smooth;
|
||||
int count;
|
||||
CurvePoint points[CPN_MAX_POINTS];
|
||||
char name[CURVEDATA_NAME_LEN+1];
|
||||
};
|
||||
|
||||
#define FLIGHTMODE_NAME_LEN 10
|
||||
#define RENC_MAX_VALUE 1024
|
||||
#define RENC_MIN_VALUE -RENC_MAX_VALUE
|
||||
|
||||
class FlightModeData {
|
||||
Q_DECLARE_TR_FUNCTIONS(FlightModeData)
|
||||
|
||||
public:
|
||||
FlightModeData() { clear(0); }
|
||||
int trimMode[CPN_MAX_TRIMS];
|
||||
int trimRef[CPN_MAX_TRIMS];
|
||||
int trim[CPN_MAX_TRIMS];
|
||||
RawSwitch swtch;
|
||||
char name[FLIGHTMODE_NAME_LEN+1];
|
||||
unsigned int fadeIn;
|
||||
unsigned int fadeOut;
|
||||
int rotaryEncoders[CPN_MAX_ENCODERS];
|
||||
int gvars[CPN_MAX_GVARS];
|
||||
void clear(const int phaseIdx);
|
||||
QString nameToString(int phaseIdx) const;
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
bool isEmpty(int phaseIdx) const;
|
||||
bool isGVarEmpty(int phaseIdx, int gvIdx) const;
|
||||
bool isREncEmpty(int phaseIdx, int reIdx) const;
|
||||
int linkedFlightModeZero(int phaseIdx, int maxOwnValue) const;
|
||||
int linkedGVarFlightModeZero(int phaseIdx) const;
|
||||
int linkedREncFlightModeZero(int phaseIdx) const;
|
||||
};
|
||||
|
||||
class SwashRingData {
|
||||
Q_DECLARE_TR_FUNCTIONS(SwashRingData)
|
||||
|
||||
public:
|
||||
SwashRingData() { clear(); }
|
||||
int elevatorWeight;
|
||||
int aileronWeight;
|
||||
int collectiveWeight;
|
||||
unsigned int type;
|
||||
RawSource collectiveSource;
|
||||
RawSource aileronSource;
|
||||
RawSource elevatorSource;
|
||||
unsigned int value;
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(SwashRingData)); }
|
||||
};
|
||||
|
||||
#endif // IO_DATA_H
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "mixdata.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
void MixData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("MIX"), 4);
|
||||
cstate.setSubComp(RawSource(SOURCE_TYPE_CH, destCh-1).toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType) % tr(" (@%1)").arg(cstate.subCompIdx));
|
||||
srcRaw.convert(cstate);
|
||||
swtch.convert(cstate);
|
||||
}
|
||||
|
||||
bool MixData::isEmpty() const
|
||||
{
|
||||
return (destCh == 0);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "curvereference.h"
|
||||
#include "rawsource.h"
|
||||
#include "rawswitch.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class RadioDataConversionState;
|
||||
|
||||
enum MltpxValue {
|
||||
MLTPX_ADD,
|
||||
MLTPX_MUL,
|
||||
MLTPX_REP
|
||||
};
|
||||
|
||||
#define MIXDATA_NAME_LEN 10
|
||||
|
||||
class MixData {
|
||||
Q_DECLARE_TR_FUNCTIONS(MixData)
|
||||
|
||||
public:
|
||||
MixData() { clear(); }
|
||||
|
||||
unsigned int destCh; // 1..CPN_MAX_CHNOUT
|
||||
RawSource srcRaw;
|
||||
int weight;
|
||||
RawSwitch swtch;
|
||||
CurveReference curve;
|
||||
unsigned int delayUp;
|
||||
unsigned int delayDown;
|
||||
unsigned int speedUp;
|
||||
unsigned int speedDown;
|
||||
int carryTrim;
|
||||
bool noExpo;
|
||||
MltpxValue mltpx;
|
||||
unsigned int mixWarn;
|
||||
unsigned int flightModes; // -5=!FP4, 0=normal, 5=FP4
|
||||
int sOffset;
|
||||
char name[MIXDATA_NAME_LEN + 1];
|
||||
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(MixData)); }
|
||||
bool isEmpty() const;
|
||||
};
|
||||
@@ -27,26 +27,6 @@
|
||||
#include "helpers.h"
|
||||
#include "adjustmentreference.h"
|
||||
|
||||
/*
|
||||
* TimerData
|
||||
*/
|
||||
|
||||
void TimerData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("TMR"), 1);
|
||||
cstate.setSubComp(tr("Timer %1").arg(cstate.subCompIdx + 1));
|
||||
mode.convert(cstate);
|
||||
}
|
||||
|
||||
bool TimerData::isEmpty()
|
||||
{
|
||||
return (mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0) && name[0] == '\0' && minuteBeep == 0 && countdownBeep == COUNTDOWN_SILENT && val == 0 && persistent == 0 /*&& pvalue == 0*/);
|
||||
}
|
||||
|
||||
/*
|
||||
* ModelData
|
||||
*/
|
||||
|
||||
ModelData::ModelData()
|
||||
{
|
||||
clear();
|
||||
@@ -527,6 +507,8 @@ int ModelData::updateReference()
|
||||
|
||||
Firmware *fw = getCurrentFirmware();
|
||||
|
||||
updRefInfo.occurences = 1;
|
||||
|
||||
switch (updRefInfo.type)
|
||||
{
|
||||
case REF_UPD_TYPE_CHANNEL:
|
||||
@@ -561,6 +543,7 @@ int ModelData::updateReference()
|
||||
updRefInfo.srcType = SOURCE_TYPE_TELEMETRY;
|
||||
updRefInfo.swtchType = SWITCH_TYPE_SENSOR;
|
||||
updRefInfo.maxindex = fw->getCapability(Sensors);
|
||||
updRefInfo.occurences = 3;
|
||||
break;
|
||||
case REF_UPD_TYPE_TIMER:
|
||||
updRefInfo.srcType = SOURCE_TYPE_SPECIAL;
|
||||
@@ -651,6 +634,8 @@ int ModelData::updateReference()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updRefInfo.type == REF_UPD_TYPE_CHANNEL)
|
||||
sortMixes();
|
||||
//s1.report("Mixes");
|
||||
|
||||
for (int i = 0; i < CPN_MAX_CHNOUT; i++) {
|
||||
@@ -668,41 +653,56 @@ int ModelData::updateReference()
|
||||
LogicalSwitchData *lsd = &logicalSw[i];
|
||||
if (!lsd->isEmpty()) {
|
||||
bool clearlsd = false;
|
||||
int oldval1;
|
||||
int oldval2;
|
||||
CSFunctionFamily family = lsd->getFunctionFamily();
|
||||
switch(family) {
|
||||
case LS_FAMILY_VOFS:
|
||||
updateSourceIntRef(lsd->val1);
|
||||
if (lsd->val1 == 0)
|
||||
clearlsd = true;
|
||||
if (lsd->val1 != 0) {
|
||||
updateSourceIntRef(lsd->val1);
|
||||
if (lsd->val1 == 0)
|
||||
clearlsd = true;
|
||||
}
|
||||
break;
|
||||
case LS_FAMILY_STICKY:
|
||||
case LS_FAMILY_VBOOL:
|
||||
updateSwitchIntRef(lsd->val1);
|
||||
updateSwitchIntRef(lsd->val2);
|
||||
if (lsd->val1 == 0 && lsd->val2 == 0)
|
||||
oldval1 = lsd->val1;
|
||||
oldval2 = lsd->val2;
|
||||
if (lsd->val1 != 0)
|
||||
updateSwitchIntRef(lsd->val1);
|
||||
if (lsd->val2 != 0)
|
||||
updateSwitchIntRef(lsd->val2);
|
||||
if (lsd->val1 == 0 && lsd->val2 == 0 && ((lsd->val1 != oldval1 && oldval2 == 0) || (lsd->val2 != oldval2 && oldval1 == 0)))
|
||||
clearlsd = true;
|
||||
break;
|
||||
case LS_FAMILY_EDGE:
|
||||
updateSwitchIntRef(lsd->val1);
|
||||
if (lsd->val1 == 0)
|
||||
clearlsd = true;
|
||||
if (lsd->val1 != 0) {
|
||||
updateSwitchIntRef(lsd->val1);
|
||||
if (lsd->val1 == 0)
|
||||
clearlsd = true;
|
||||
}
|
||||
break;
|
||||
case LS_FAMILY_VCOMP:
|
||||
updateSourceIntRef(lsd->val1);
|
||||
updateSourceIntRef(lsd->val2);
|
||||
if (lsd->val1 == 0 && lsd->val2 == 0)
|
||||
oldval1 = lsd->val1;
|
||||
oldval2 = lsd->val2;
|
||||
if (lsd->val1 != 0)
|
||||
updateSourceIntRef(lsd->val1);
|
||||
if (lsd->val2 != 0)
|
||||
updateSourceIntRef(lsd->val2);
|
||||
if (lsd->val1 == 0 && lsd->val2 == 0 && ((lsd->val1 != oldval1 && oldval2 == 0) || (lsd->val2 != oldval2 && oldval1 == 0)))
|
||||
clearlsd = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (clearlsd) {
|
||||
|
||||
if (lsd->andsw != 0)
|
||||
updateSwitchIntRef(lsd->andsw);
|
||||
|
||||
if (clearlsd && lsd->andsw == 0) {
|
||||
lsd->clear();
|
||||
appendUpdateReferenceParams(REF_UPD_TYPE_LOGICAL_SWITCH, REF_UPD_ACT_CLEAR, i);
|
||||
}
|
||||
else {
|
||||
updateSwitchIntRef(lsd->andsw);
|
||||
}
|
||||
}
|
||||
}
|
||||
//s1.report("Logical Switches");
|
||||
@@ -713,11 +713,15 @@ int ModelData::updateReference()
|
||||
updateAssignFunc(cfd);
|
||||
if (!cfd->isEmpty()) {
|
||||
updateSwitchRef(cfd->swtch);
|
||||
if (cfd->func == FuncVolume || cfd->func == FuncPlayValue || (cfd->func >= FuncAdjustGV1 && cfd->func <= FuncAdjustGVLast && (cfd->adjustMode == FUNC_ADJUST_GVAR_GVAR || cfd->adjustMode == FUNC_ADJUST_GVAR_SOURCE))) {
|
||||
if (cfd->func == FuncVolume || cfd->func == FuncBacklight || cfd->func == FuncPlayValue ||
|
||||
(cfd->func >= FuncAdjustGV1 && cfd->func <= FuncAdjustGVLast && (cfd->adjustMode == FUNC_ADJUST_GVAR_GVAR || cfd->adjustMode == FUNC_ADJUST_GVAR_SOURCE))) {
|
||||
updateSourceIntRef(cfd->param);
|
||||
if (cfd->param == 0)
|
||||
cfd->clear();
|
||||
}
|
||||
else if (cfd->func == FuncReset) {
|
||||
updateResetParam(cfd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -762,15 +766,35 @@ int ModelData::updateReference()
|
||||
//s1.report("Telemetry");
|
||||
}
|
||||
|
||||
// TODO maybe less risk to leave it up to the user??
|
||||
/*
|
||||
for (int i = 0; i < CPN_MAX_SENSORS; i++) {
|
||||
SensorData *sd = &sensorData[i];
|
||||
if (sd->isAvailable() && sd->type == SensorData::TELEM_TYPE_CALCULATED) {
|
||||
if (!sd->isEmpty() && sd->type == SensorData::TELEM_TYPE_CALCULATED) {
|
||||
if (sd->formula == SensorData::TELEM_FORMULA_CELL) {
|
||||
updateTelemetryRef(sd->source);
|
||||
if (sd->source == 0) {
|
||||
sd->clear();
|
||||
appendUpdateReferenceParams(REF_UPD_TYPE_SENSOR, REF_UPD_ACT_CLEAR, i);
|
||||
}
|
||||
}
|
||||
else if (sd->formula == SensorData::TELEM_FORMULA_DIST) {
|
||||
updateTelemetryRef(sd->gps);
|
||||
updateTelemetryRef(sd->alt);
|
||||
}
|
||||
else if (sd->formula == SensorData::TELEM_FORMULA_CONSUMPTION || sd->formula == SensorData::TELEM_FORMULA_TOTALIZE) {
|
||||
updateTelemetryRef(sd->amps);
|
||||
if (sd->amps == 0) {
|
||||
sd->clear();
|
||||
appendUpdateReferenceParams(REF_UPD_TYPE_SENSOR, REF_UPD_ACT_CLEAR, i);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (unsigned int i = 0; i < 4; i++) {
|
||||
updateTelemetryRef(sd->sources[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
s1.report("Telemetry Sensors");
|
||||
*/
|
||||
//s1.report("Telemetry Sensors");
|
||||
|
||||
// TODO needs lua incorporated into Companion as script needs to be parsed to determine if input field is source or value
|
||||
/*
|
||||
@@ -806,10 +830,13 @@ void ModelData::updateTypeIndexRef(R & curRef, const T type, const int idxAdj, c
|
||||
newRef.type = curRef.type;
|
||||
newRef.index = abs(curRef.index);
|
||||
|
||||
div_t idx = div(newRef.index, updRefInfo.occurences);
|
||||
div_t newidx;
|
||||
|
||||
switch (updRefInfo.action)
|
||||
{
|
||||
case REF_UPD_ACT_CLEAR:
|
||||
if (newRef.index != (updRefInfo.index1 + idxAdj))
|
||||
if (idx.quot != (updRefInfo.index1 + idxAdj))
|
||||
return;
|
||||
if (defClear)
|
||||
newRef.clear();
|
||||
@@ -819,25 +846,26 @@ void ModelData::updateTypeIndexRef(R & curRef, const T type, const int idxAdj, c
|
||||
}
|
||||
break;
|
||||
case REF_UPD_ACT_SHIFT:
|
||||
if (newRef.index < (updRefInfo.index1 + idxAdj))
|
||||
if (idx.quot < (updRefInfo.index1 + idxAdj))
|
||||
return;
|
||||
|
||||
newRef.index += updRefInfo.shift;
|
||||
newRef.index = ((idx.quot + updRefInfo.shift) * updRefInfo.occurences) + idx.rem;
|
||||
newidx = div(newRef.index, updRefInfo.occurences);
|
||||
|
||||
if (newRef.index < (updRefInfo.index1 + idxAdj) || newRef.index > (updRefInfo.maxindex + idxAdj)) {
|
||||
if (newidx.quot < (updRefInfo.index1 + idxAdj) || newidx.quot > (updRefInfo.maxindex + idxAdj)) {
|
||||
if (defClear)
|
||||
newRef.clear();
|
||||
else {
|
||||
newRef.type = (T)defType;
|
||||
newRef.index = defIndex;
|
||||
newRef.index = defIndex + idxAdj;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case REF_UPD_ACT_SWAP:
|
||||
if (newRef.index == updRefInfo.index1 + idxAdj)
|
||||
newRef.index = updRefInfo.index2 + idxAdj;
|
||||
else if (newRef.index == updRefInfo.index2 + idxAdj)
|
||||
newRef.index = updRefInfo.index1 + idxAdj;
|
||||
if (idx.quot == updRefInfo.index1 + idxAdj)
|
||||
newRef.index = ((updRefInfo.index2 + idxAdj) * updRefInfo.occurences) + idx.rem;
|
||||
else if (idx.quot == updRefInfo.index2 + idxAdj)
|
||||
newRef.index = ((updRefInfo.index1 + idxAdj) * updRefInfo.occurences) + idx.rem;
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Error - unhandled action:" << updRefInfo.action;
|
||||
@@ -886,7 +914,7 @@ void ModelData::updateTypeValueRef(R & curRef, const T type, const int idxAdj, c
|
||||
newRef.clear();
|
||||
else {
|
||||
newRef.type = (T)defType;
|
||||
newRef.value = defValue;
|
||||
newRef.value = defValue + idxAdj;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -940,7 +968,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd)
|
||||
{
|
||||
const int invalidateRef = -1;
|
||||
int newRef = (int)cfd->func;
|
||||
int idxAdj;
|
||||
int idxAdj = 0;
|
||||
|
||||
switch (updRefInfo.type)
|
||||
{
|
||||
@@ -957,7 +985,7 @@ void ModelData::updateAssignFunc(CustomFunctionData * cfd)
|
||||
case REF_UPD_TYPE_TIMER:
|
||||
if (cfd->func < FuncSetTimer1 || cfd->func > FuncSetTimer3) // TODO refactor to FuncSetTimerLast
|
||||
return;
|
||||
idxAdj = FuncSetTimer1 - 2; // reverse earlier offset requiured for rawsource
|
||||
idxAdj = FuncSetTimer1 - 2; // reverse earlier offset required for rawsource
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -1070,7 +1098,7 @@ void ModelData::updateFlightModeFlags(unsigned int & curRef)
|
||||
switch (updRefInfo.action)
|
||||
{
|
||||
case REF_UPD_ACT_CLEAR:
|
||||
flag[updRefInfo.index1] = false;
|
||||
flag[updRefInfo.index1] = true;
|
||||
break;
|
||||
case REF_UPD_ACT_SHIFT:
|
||||
if(updRefInfo.shift < 0) {
|
||||
@@ -1078,7 +1106,7 @@ void ModelData::updateFlightModeFlags(unsigned int & curRef)
|
||||
if (i - updRefInfo.shift <= updRefInfo.maxindex)
|
||||
flag[i] = flag[i - updRefInfo.shift];
|
||||
else
|
||||
flag[i] = false;
|
||||
flag[i] = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1086,7 +1114,7 @@ void ModelData::updateFlightModeFlags(unsigned int & curRef)
|
||||
if (i - updRefInfo.shift >= updRefInfo.index1)
|
||||
flag[i] = flag[i - updRefInfo.shift];
|
||||
else
|
||||
flag[i] = false;
|
||||
flag[i] = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1115,13 +1143,14 @@ void ModelData::updateFlightModeFlags(unsigned int & curRef)
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::updateTelemetryRef(unsigned int & curRef)
|
||||
void ModelData::updateTelemetryRef(int & curRef)
|
||||
{
|
||||
if (updRefInfo.type != REF_UPD_TYPE_SENSOR)
|
||||
return;
|
||||
|
||||
const int idxAdj = 1;
|
||||
int newRef = curRef;
|
||||
|
||||
switch (updRefInfo.action)
|
||||
{
|
||||
case REF_UPD_ACT_CLEAR:
|
||||
@@ -1149,13 +1178,23 @@ void ModelData::updateTelemetryRef(unsigned int & curRef)
|
||||
return;
|
||||
}
|
||||
|
||||
if (curRef != static_cast<unsigned int>(newRef)) {
|
||||
if (curRef != newRef) {
|
||||
//qDebug() << "Updated reference:" << curRef << " -> " << newRef;
|
||||
curRef = newRef;
|
||||
updRefInfo.updcnt++;
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::updateTelemetryRef(unsigned int & curRef)
|
||||
{
|
||||
int newRef = (int)curRef;
|
||||
updateTelemetryRef(newRef);
|
||||
|
||||
if (curRef != static_cast<unsigned int>(newRef)) {
|
||||
curRef = (unsigned int)newRef;
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::updateModuleFailsafes(ModuleData * md)
|
||||
{
|
||||
if (updRefInfo.type != REF_UPD_TYPE_CHANNEL)
|
||||
@@ -1289,3 +1328,225 @@ void ModelData::removeMix(const int idx)
|
||||
memmove(&mixData[idx], &mixData[idx + 1], (CPN_MAX_MIXERS - (idx + 1)) * sizeof(MixData));
|
||||
mixData[CPN_MAX_MIXERS - 1].clear();
|
||||
}
|
||||
|
||||
void ModelData::sortMixes()
|
||||
{
|
||||
unsigned int lastchn = 0;
|
||||
bool sortreq = false;
|
||||
|
||||
for (int i = 0; i < CPN_MAX_MIXERS; i++) {
|
||||
MixData *md = &mixData[i];
|
||||
if (!md->isEmpty()) {
|
||||
if (md->destCh < lastchn) {
|
||||
sortreq = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
lastchn = md->destCh;
|
||||
}
|
||||
}
|
||||
|
||||
if (!sortreq)
|
||||
return;
|
||||
|
||||
// QMap automatically sorts based on key
|
||||
QMap<int, int> map;
|
||||
for (int i = 0; i < CPN_MAX_MIXERS; i++) {
|
||||
MixData *md = &mixData[i];
|
||||
if (!md->isEmpty()) {
|
||||
// destCh may not be unique so build a compound sort key
|
||||
map.insert(md->destCh * (CPN_MAX_MIXERS + 1) + i, i);
|
||||
}
|
||||
}
|
||||
|
||||
MixData sortedMixData[CPN_MAX_MIXERS];
|
||||
int destidx = 0;
|
||||
|
||||
QMap<int, int>::const_iterator i;
|
||||
for (i = map.constBegin(); i != map.constEnd(); ++i) {
|
||||
memcpy(&sortedMixData[destidx], &mixData[i.value()], sizeof(MixData));
|
||||
destidx++;
|
||||
}
|
||||
|
||||
memcpy(&mixData[0], &sortedMixData[0], CPN_MAX_MIXERS * sizeof(MixData));
|
||||
}
|
||||
|
||||
void ModelData::updateResetParam(CustomFunctionData * cfd)
|
||||
{
|
||||
if (cfd->func != FuncReset)
|
||||
return;
|
||||
|
||||
const int invalidateRef = -1;
|
||||
int newRef = cfd->param;
|
||||
int idxAdj = 0;
|
||||
Firmware *firmware = getCurrentFirmware();
|
||||
|
||||
switch (updRefInfo.type)
|
||||
{
|
||||
case REF_UPD_TYPE_TIMER:
|
||||
if (cfd->param < 0 || cfd->param > 2)
|
||||
return;
|
||||
idxAdj = -2; // reverse earlier offset required for rawsource
|
||||
break;
|
||||
case REF_UPD_TYPE_SENSOR:
|
||||
idxAdj = 5/*3 Timers + Flight + Telemetery*/ + firmware->getCapability(RotaryEncoders);
|
||||
if (cfd->param < idxAdj || cfd->param > (idxAdj + firmware->getCapability(Sensors)))
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
switch (updRefInfo.action)
|
||||
{
|
||||
case REF_UPD_ACT_CLEAR:
|
||||
if (newRef != (updRefInfo.index1 + idxAdj))
|
||||
return;
|
||||
newRef = invalidateRef;
|
||||
break;
|
||||
case REF_UPD_ACT_SHIFT:
|
||||
if (newRef < (updRefInfo.index1 + idxAdj))
|
||||
return;
|
||||
|
||||
newRef += updRefInfo.shift;
|
||||
|
||||
if (newRef < (updRefInfo.index1 + idxAdj) || newRef > (updRefInfo.maxindex + idxAdj))
|
||||
newRef = invalidateRef;
|
||||
break;
|
||||
case REF_UPD_ACT_SWAP:
|
||||
if (newRef == updRefInfo.index1 + idxAdj)
|
||||
newRef = updRefInfo.index2 + idxAdj;
|
||||
else if (newRef == updRefInfo.index2 + idxAdj)
|
||||
newRef = updRefInfo.index1 + idxAdj;
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Error - unhandled action:" << updRefInfo.action;
|
||||
return;
|
||||
}
|
||||
|
||||
if (newRef == invalidateRef) {
|
||||
cfd->clear();
|
||||
//qDebug() << "Function cleared";
|
||||
updRefInfo.updcnt++;
|
||||
}
|
||||
else if (cfd->param != newRef) {
|
||||
//qDebug() << "Updated reference:" << cfd->param << " -> " << newRef;
|
||||
cfd->param = newRef;
|
||||
updRefInfo.updcnt++;
|
||||
}
|
||||
}
|
||||
|
||||
QString ModelData::thrTraceSrcToString() const
|
||||
{
|
||||
return thrTraceSrcToString((int)thrTraceSrc);
|
||||
}
|
||||
|
||||
QString ModelData::thrTraceSrcToString(const int index) const
|
||||
{
|
||||
Firmware * firmware = getCurrentFirmware();
|
||||
const Boards board = Boards(getCurrentBoard());
|
||||
const int pscnt = board.getCapability(Board::Pots) + board.getCapability(Board::Sliders);
|
||||
|
||||
if (index == 0)
|
||||
return tr("THR");
|
||||
else if (index <= pscnt)
|
||||
return board.getAnalogInputName(index + board.getCapability(Board::Sticks) - 1);
|
||||
else if (index <= pscnt + firmware->getCapability(Outputs))
|
||||
return RawSource(SOURCE_TYPE_CH, index - pscnt - 1).toString(this);
|
||||
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
|
||||
int ModelData::thrTraceSrcCount() const
|
||||
{
|
||||
const Boards board = Boards(getCurrentBoard());
|
||||
Firmware * firmware = getCurrentFirmware();
|
||||
|
||||
return 1 + board.getCapability(Board::Pots) + board.getCapability(Board::Sliders) + firmware->getCapability(Outputs);
|
||||
}
|
||||
|
||||
bool ModelData::isThrTraceSrcAvailable(const GeneralSettings * generalSettings, const int index) const
|
||||
{
|
||||
const Boards board = Boards(getCurrentBoard());
|
||||
|
||||
if (index > 0 && index <= board.getCapability(Board::Pots) + board.getCapability(Board::Sliders))
|
||||
return RawSource(SOURCE_TYPE_STICK, index + board.getCapability(Board::Sticks) - 1).isAvailable(this, generalSettings, board.getBoardType());
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModelData::limitsClear(const int index)
|
||||
{
|
||||
if (index < 0 || index >= CPN_MAX_CHNOUT)
|
||||
return;
|
||||
|
||||
if (!limitData[index].isEmpty()) {
|
||||
limitData[index].clear();
|
||||
updateAllReferences(REF_UPD_TYPE_CHANNEL, REF_UPD_ACT_CLEAR, index);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::limitsClearAll()
|
||||
{
|
||||
for (int i = 0; i < CPN_MAX_CHNOUT; i++) {
|
||||
limitsClear(i);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::limitsDelete(const int index)
|
||||
{
|
||||
if (index < 0 || index >= CPN_MAX_CHNOUT)
|
||||
return;
|
||||
|
||||
memmove(&limitData[index], &limitData[index + 1], (CPN_MAX_CHNOUT - (index + 1)) * sizeof(LimitData));
|
||||
limitData[CPN_MAX_CHNOUT - 1].clear();
|
||||
updateAllReferences(REF_UPD_TYPE_CHANNEL, REF_UPD_ACT_SHIFT, index, 0, -1);
|
||||
}
|
||||
|
||||
void ModelData::limitsGet(const int index, QByteArray & data)
|
||||
{
|
||||
if (index < 0 || index >= CPN_MAX_CHNOUT)
|
||||
return;
|
||||
|
||||
data.append((char*)&limitData[index], sizeof(LimitData));
|
||||
}
|
||||
|
||||
void ModelData::limitsInsert(const int index)
|
||||
{
|
||||
if (index < 0 || index >= CPN_MAX_CHNOUT)
|
||||
return;
|
||||
|
||||
memmove(&limitData[index + 1], &limitData[index], (CPN_MAX_CHNOUT - (index + 1)) * sizeof(LimitData));
|
||||
limitData[index].clear();
|
||||
updateAllReferences(REF_UPD_TYPE_CHANNEL, REF_UPD_ACT_SHIFT, index, 0, 1);
|
||||
}
|
||||
|
||||
void ModelData::limitsMove(const int index, const int offset)
|
||||
{
|
||||
if (index + offset < 0 || index + offset >= CPN_MAX_CHNOUT)
|
||||
return;
|
||||
|
||||
int idx1 = index;
|
||||
int idx2;
|
||||
const int direction = offset < 0 ? -1 : 1;
|
||||
const int cnt = abs(offset);
|
||||
|
||||
for (int i = 1; i <= cnt; i++) {
|
||||
idx2 = idx1 + direction;
|
||||
LimitData tmp = limitData[idx2];
|
||||
LimitData *d1 = &limitData[idx1];
|
||||
LimitData *d2 = &limitData[idx2];
|
||||
memcpy(d2, d1, sizeof(LimitData));
|
||||
memcpy(d1, &tmp, sizeof(LimitData));
|
||||
updateAllReferences(REF_UPD_TYPE_CHANNEL, REF_UPD_ACT_SWAP, idx1, idx2);
|
||||
idx1 += direction;
|
||||
}
|
||||
}
|
||||
|
||||
void ModelData::limitsSet(const int index, const QByteArray & data)
|
||||
{
|
||||
if (index < 0 || index >= CPN_MAX_CHNOUT || data.size() < (int)sizeof(LimitData))
|
||||
return;
|
||||
|
||||
memcpy(&limitData[index], data.constData(), sizeof(LimitData));
|
||||
}
|
||||
|
||||
@@ -18,17 +18,22 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef MODELDATA_H
|
||||
#define MODELDATA_H
|
||||
#pragma once
|
||||
|
||||
#include "constants.h"
|
||||
#include "curvedata.h"
|
||||
#include "customfunctiondata.h"
|
||||
#include "gvardata.h"
|
||||
#include "io_data.h"
|
||||
#include "flightmodedata.h"
|
||||
#include "heli_data.h"
|
||||
#include "input_data.h"
|
||||
#include "logicalswitchdata.h"
|
||||
#include "mixdata.h"
|
||||
#include "moduledata.h"
|
||||
#include "output_data.h"
|
||||
#include "sensordata.h"
|
||||
#include "telem_data.h"
|
||||
#include "timerdata.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
@@ -51,32 +56,6 @@ class RSSIAlarmData {
|
||||
}
|
||||
};
|
||||
|
||||
#define TIMER_NAME_LEN 8
|
||||
|
||||
class TimerData {
|
||||
Q_DECLARE_TR_FUNCTIONS(TimerData)
|
||||
|
||||
public:
|
||||
enum CountDownMode {
|
||||
COUNTDOWN_SILENT,
|
||||
COUNTDOWN_BEEPS,
|
||||
COUNTDOWN_VOICE,
|
||||
COUNTDOWN_HAPTIC
|
||||
};
|
||||
TimerData() { clear(); }
|
||||
RawSwitch mode;
|
||||
char name[TIMER_NAME_LEN+1];
|
||||
bool minuteBeep;
|
||||
unsigned int countdownBeep;
|
||||
unsigned int val;
|
||||
unsigned int persistent;
|
||||
int pvalue;
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(TimerData)); mode = RawSwitch(SWITCH_TYPE_TIMER_MODE, 0); }
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
bool isEmpty();
|
||||
bool isModeOff() { return mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0); }
|
||||
};
|
||||
|
||||
#define CPN_MAX_SCRIPTS 9
|
||||
#define CPN_MAX_SCRIPT_INPUTS 10
|
||||
class ScriptData {
|
||||
@@ -181,6 +160,7 @@ class ModelData {
|
||||
unsigned int thrTraceSrc;
|
||||
uint64_t switchWarningStates;
|
||||
unsigned int switchWarningEnable;
|
||||
unsigned int thrTrimSwitch;
|
||||
unsigned int potsWarningMode;
|
||||
bool potsWarnEnabled[CPN_MAX_POTS];
|
||||
int potsWarnPosition[CPN_MAX_POTS];
|
||||
@@ -281,6 +261,18 @@ class ModelData {
|
||||
bool hasExpoChildren(const int index);
|
||||
bool hasExpoSiblings(const int index);
|
||||
void removeMix(const int idx);
|
||||
QString thrTraceSrcToString() const;
|
||||
QString thrTraceSrcToString(const int index) const;
|
||||
int thrTraceSrcCount() const;
|
||||
bool isThrTraceSrcAvailable(const GeneralSettings * generalSettings, const int index) const;
|
||||
|
||||
void limitsClear(const int index);
|
||||
void limitsClearAll();
|
||||
void limitsDelete(const int index);
|
||||
void limitsGet(const int index, QByteArray & data);
|
||||
void limitsInsert(const int index);
|
||||
void limitsMove(const int index, const int offset);
|
||||
void limitsSet(const int index, const QByteArray & data);
|
||||
|
||||
protected:
|
||||
void removeGlobalVar(int & var);
|
||||
@@ -297,6 +289,7 @@ class ModelData {
|
||||
int shift;
|
||||
int updcnt;
|
||||
int maxindex;
|
||||
int occurences;
|
||||
RawSourceType srcType;
|
||||
RawSwitchType swtchType;
|
||||
};
|
||||
@@ -314,6 +307,7 @@ class ModelData {
|
||||
void updateDestCh(MixData * md);
|
||||
void updateLimitCurveRef(CurveReference & crv);
|
||||
void updateFlightModeFlags(unsigned int & flags);
|
||||
void updateTelemetryRef(int & idx);
|
||||
void updateTelemetryRef(unsigned int & idx);
|
||||
void updateModuleFailsafes(ModuleData * md);
|
||||
inline void updateSourceRef(RawSource & src) { updateTypeIndexRef<RawSource, RawSourceType>(src, updRefInfo.srcType); }
|
||||
@@ -333,6 +327,6 @@ class ModelData {
|
||||
if (value != swtch.toValue())
|
||||
value = swtch.toValue();
|
||||
}
|
||||
void sortMixes();
|
||||
void updateResetParam(CustomFunctionData * cfd);
|
||||
};
|
||||
|
||||
#endif // MODELDATA_H
|
||||
|
||||
@@ -45,19 +45,6 @@ bool ModuleData::isPxx2Module() const
|
||||
}
|
||||
}
|
||||
|
||||
bool ModuleData::isPxx1Module() const
|
||||
{
|
||||
switch(protocol){
|
||||
case PULSES_PXX_XJT_X16:
|
||||
case PULSES_PXX_R9M:
|
||||
case PULSES_PXX_R9M_LITE:
|
||||
case PULSES_PXX_R9M_LITE_PRO:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ModuleData::supportRxNum() const
|
||||
{
|
||||
switch (protocol) {
|
||||
@@ -66,6 +53,7 @@ bool ModuleData::supportRxNum() const
|
||||
case PULSES_PXX_R9M_LITE:
|
||||
case PULSES_PXX_R9M_LITE_PRO:
|
||||
case PULSES_MULTIMODULE:
|
||||
case PULSES_CROSSFIRE:
|
||||
case PULSES_ACCESS_ISRM:
|
||||
case PULSES_ACCST_ISRM_D16:
|
||||
case PULSES_ACCESS_R9M:
|
||||
@@ -160,7 +148,8 @@ QString ModuleData::protocolToString(unsigned protocol)
|
||||
"FrSky ACCESS R9M Lite",
|
||||
"FrSky ACCESS R9M Lite Pro",
|
||||
"FrSky XJT lite (D16)", "FrSky XJT lite (D8)", "FrSky XJT lite (LR12)",
|
||||
"AFHDS3"
|
||||
"AFHDS3",
|
||||
"ImmersionRC Ghost"
|
||||
};
|
||||
|
||||
return CHECK_IN_ARRAY(strings, protocol);
|
||||
@@ -221,6 +210,7 @@ int ModuleData::getMaxChannelCount()
|
||||
case PULSES_XJT_LITE_X16:
|
||||
case PULSES_PXX_XJT_X16:
|
||||
case PULSES_CROSSFIRE:
|
||||
case PULSES_GHOST:
|
||||
case PULSES_SBUS:
|
||||
case PULSES_PPM:
|
||||
return 16;
|
||||
|
||||
@@ -59,6 +59,7 @@ enum PulsesProtocol {
|
||||
PULSES_XJT_LITE_D8,
|
||||
PULSES_XJT_LITE_LR12,
|
||||
PULSES_AFHDS3,
|
||||
PULSES_GHOST,
|
||||
PULSES_PROTOCOL_LAST
|
||||
};
|
||||
|
||||
@@ -83,7 +84,7 @@ enum MultiModuleRFProtocols {
|
||||
MODULE_SUBTYPE_MULTI_MJXQ,
|
||||
MODULE_SUBTYPE_MULTI_SHENQI,
|
||||
MODULE_SUBTYPE_MULTI_FY326,
|
||||
MODULE_SUBTYPE_MULTI_SFHSS,
|
||||
MODULE_SUBTYPE_MULTI_FUTABA,
|
||||
MODULE_SUBTYPE_MULTI_J6PRO,
|
||||
MODULE_SUBTYPE_MULTI_FQ777,
|
||||
MODULE_SUBTYPE_MULTI_ASSAN,
|
||||
@@ -114,7 +115,7 @@ enum MultiModuleRFProtocols {
|
||||
MODULE_SUBTYPE_MULTI_REDPINE,
|
||||
MODULE_SUBTYPE_MULTI_POTENSIC,
|
||||
MODULE_SUBTYPE_MULTI_ZSX,
|
||||
MODULE_SUBTYPE_MULTI_FLYZONE,
|
||||
MODULE_SUBTYPE_MULTI_HEIGHT,
|
||||
MODULE_SUBTYPE_MULTI_SCANNER,
|
||||
MODULE_SUBTYPE_MULTI_FRSKYX_RX,
|
||||
MODULE_SUBTYPE_MULTI_AFHDS2A_RX,
|
||||
@@ -134,7 +135,15 @@ enum MultiModuleRFProtocols {
|
||||
MODULE_SUBTYPE_MULTI_DSM_RX,
|
||||
MODULE_SUBTYPE_MULTI_JJRC345,
|
||||
MODULE_SUBTYPE_MULTI_Q90C,
|
||||
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_Q90C
|
||||
MODULE_SUBTYPE_MULTI_KYOSHO,
|
||||
MODULE_SUBTYPE_MULTI_RLINK,
|
||||
MODULE_SUBTYPE_MULTI_ELRS,
|
||||
MODULE_SUBTYPE_MULTI_REALACC,
|
||||
MODULE_SUBTYPE_MULTI_OMP,
|
||||
MODULE_SUBTYPE_MULTI_MLINK,
|
||||
MODULE_SUBTYPE_MULTI_WFLY2,
|
||||
MODULE_SUBTYPE_MULTI_E016HV2,
|
||||
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_E016HV2
|
||||
};
|
||||
|
||||
enum TrainerProtocol {
|
||||
@@ -206,12 +215,12 @@ class ModuleData {
|
||||
struct Access {
|
||||
unsigned int receivers;
|
||||
char receiverName[PXX2_MAX_RECEIVERS_PER_MODULE][PXX2_LEN_RX_NAME+1];
|
||||
unsigned int racingMode;
|
||||
} access;
|
||||
|
||||
void clear() { memset(this, 0, sizeof(ModuleData)); }
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
bool isPxx2Module() const;
|
||||
bool isPxx1Module() const;
|
||||
bool supportRxNum() const;
|
||||
QString polarityToString() const { return ppm.pulsePol ? tr("Positive") : tr("Negative"); }
|
||||
QString rfProtocolToString() const;
|
||||
|
||||
@@ -55,8 +55,9 @@ static const QStringList STR_SUBTYPE_ESky {"Standard", "ET4"};
|
||||
static const QStringList STR_SUBTYPE_MT99 {"MT99", "H7", "YZ", "LS", "FY805"};
|
||||
static const QStringList STR_SUBTYPE_MJXQ {"WLH08", "X600", "X800", "H26D", "E010", "H26WH", "Phoenix"};
|
||||
static const QStringList STR_SUBTYPE_FY326 {"Standard", "FY319"};
|
||||
static const QStringList STR_SUBTYPE_FUTABA {"SFHSS"};
|
||||
static const QStringList STR_SUBTYPE_HONTAI {"Standard", "JJRC X1", "X5C1 Clone", "FQ777_951"};
|
||||
static const QStringList STR_SUBTYPE_AFHDS2A {"PWM and IBUS", "PPM and IBUS", "PWM and SBUS", "PPM and SBUS"};
|
||||
static const QStringList STR_SUBTYPE_AFHDS2A {"PWM and IBUS", "PPM and IBUS", "PWM and SBUS", "PPM and SBUS", "PWM and IBUS16", "PPM and IBUS16"};
|
||||
static const QStringList STR_SUBTYPE_Q2X2 {"Q222", "Q242", "Q282"};
|
||||
static const QStringList STR_SUBTYPE_WK2x01 {"WK2801", "WK2401", "W6_5_1", "W6_6_1", "W6_HEL", "W6_HEL_I"};
|
||||
static const QStringList STR_SUBTYPE_Q303 {"Standard", "CX35", "CX10D", "CX10WD"};
|
||||
@@ -65,7 +66,7 @@ static const QStringList STR_SUBTYPE_ESKY150 {"4 Channel", "7 Channel"};
|
||||
static const QStringList STR_SUBTYPE_H83D {"H8 Mini 3D", "H20H", "H20 Mini", "H30 Mini"};
|
||||
static const QStringList STR_SUBTYPE_CORONA {"Corona V1", "Corona V2", "Flydream V3"};
|
||||
static const QStringList STR_SUBTYPE_HITEC {"Optima", "Optima Hub Telem", "Minima"};
|
||||
static const QStringList STR_SUBTYPE_WFLY {"WFR0xS"};
|
||||
static const QStringList STR_SUBTYPE_WFLY {"WFR0x"};
|
||||
static const QStringList STR_SUBTYPE_BUGS_MINI {"Standard", "Bugs 3H"};
|
||||
static const QStringList STR_SUBTYPE_TRAXXAS {"6519 RX"};
|
||||
static const QStringList STR_SUBTYPE_E01X {"E012", "E015", "E016H"};
|
||||
@@ -75,18 +76,24 @@ static const QStringList STR_SUBTYPE_V761 {"3 Channel", "4 Channel"};
|
||||
static const QStringList STR_SUBTYPE_REDPINE {"Fast", "Slow"};
|
||||
static const QStringList STR_SUBTYPE_POTENSIC {"A20 Firefly"};
|
||||
static const QStringList STR_SUBTYPE_ZSX {"JJRC ZSX-280"};
|
||||
static const QStringList STR_SUBTYPE_FLYZONE {"FZ-410 TX"};
|
||||
static const QStringList STR_SUBTYPE_HEIGHT {"5 Channel", "8 Channel"};
|
||||
static const QStringList STR_SUBTYPE_FRSKYX_RX {"RX", "Clone TX"};
|
||||
static const QStringList STR_SUBTYPE_HOTT {"Sync", "No_Sync"};
|
||||
static const QStringList STR_SUBTYPE_FX816 {"P38"};
|
||||
static const QStringList STR_SUBTYPE_PELIKAN {"Pro", "Lite"};
|
||||
static const QStringList STR_SUBTYPE_XK {"X450", "X420"};
|
||||
static const QStringList STR_SUBTYPE_XN297DUMP {"250K", "1M", "2M", "AUTO", "NRF"};
|
||||
static const QStringList STR_SUBTYPE_FRSKYX2 {"D16", "D16 8ch", "D16 EU-LBT", "D16 EU-LBT 8ch", "D16 Cloned"};
|
||||
static const QStringList STR_SUBTYPE_FRSKYR9 {"915 MHz", "868 MHz", "915 MHz 8-Channel", "868 MHz 8-Channel"};
|
||||
static const QStringList STR_SUBTYPE_FRSKYX2 {"D16", "D16 8ch", "D16 EU-LBT", "D16 EU-LBT 8ch", "Cloned", "Cloned 8ch"};
|
||||
static const QStringList STR_SUBTYPE_FRSKYR9 {"915 MHz", "868 MHz", "915 MHz 8-Channel", "868 MHz 8-Channel", "FCC", "---", "FCC 8-Channel"};
|
||||
static const QStringList STR_SUBTYPE_PROPEL {"74-Z"};
|
||||
static const QStringList STR_SUBTYPE_FRSKYL {"LR12", "LR12 6-Channel"};
|
||||
static const QStringList STR_SUBTYPE_ESKY150V2 {"150 V2"};
|
||||
static const QStringList STR_SUBTYPE_JJRC345 {"Standard", "SkyTumbler"};
|
||||
static const QStringList STR_SUBTYPE_KYOSHO {"FHSS", "Hype"};
|
||||
static const QStringList STR_SUBTYPE_RLINK {"Surface", "Air", "DumboRC"};
|
||||
static const QStringList STR_SUBTYPE_ELRS {"Not Available WIP"};
|
||||
static const QStringList STR_SUBTYPE_REALACC {"R11"};
|
||||
static const QStringList STR_SUBTYPE_WFLY2 {"RF20x"};
|
||||
|
||||
static const QStringList NO_SUBTYPE {STR_MULTI_DEFAULT};
|
||||
|
||||
@@ -112,11 +119,11 @@ const Multiprotocols multiProtocols {
|
||||
{MODULE_SUBTYPE_MULTI_MT99XX, 4, false, STR_SUBTYPE_MT99, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_MJXQ, 6, false, STR_SUBTYPE_MJXQ, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_FY326, 1, false, STR_SUBTYPE_FY326, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_SFHSS, 0, true, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_FUTABA, 0, true, STR_SUBTYPE_FUTABA, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_J6PRO, 0, false, NO_SUBTYPE, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_HONTAI, 3, false, STR_SUBTYPE_HONTAI, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_OLRS, 0, false, NO_SUBTYPE, STR_MULTI_RFPOWER},
|
||||
{MODULE_SUBTYPE_MULTI_FS_AFHDS2A, 3, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ},
|
||||
{MODULE_SUBTYPE_MULTI_FS_AFHDS2A, 5, true, STR_SUBTYPE_AFHDS2A, STR_MULTI_SERVOFREQ},
|
||||
{MODULE_SUBTYPE_MULTI_Q2X2, 2, false, STR_SUBTYPE_Q2X2, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_WK_2X01, 5, false, STR_SUBTYPE_WK2x01, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_Q303, 3, false, STR_SUBTYPE_Q303, nullptr},
|
||||
@@ -136,20 +143,28 @@ const Multiprotocols multiProtocols {
|
||||
{MODULE_SUBTYPE_MULTI_REDPINE, 1, false, STR_SUBTYPE_REDPINE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, STR_SUBTYPE_POTENSIC, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_ZSX, 0, false, STR_SUBTYPE_ZSX, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, STR_SUBTYPE_FLYZONE, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_HEIGHT, 1, false, STR_SUBTYPE_HEIGHT, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYX_RX, 1, false, STR_SUBTYPE_FRSKYX_RX, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_HOTT, 1, true, STR_SUBTYPE_HOTT, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_FX816, 0, false, STR_SUBTYPE_FX816, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_PELIKAN, 1, false, STR_SUBTYPE_PELIKAN, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_XK, 1, false, STR_SUBTYPE_XK, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_XN297DUMP, 4, false, STR_SUBTYPE_XN297DUMP, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYX2, 4, true, STR_SUBTYPE_FRSKYX2, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKY_R9, 3, true, STR_SUBTYPE_FRSKYR9, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYX2, 5, true, STR_SUBTYPE_FRSKYX2, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKY_R9, 6, true, STR_SUBTYPE_FRSKYR9, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_PROPEL, 0, false, STR_SUBTYPE_PROPEL, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_FRSKYL, 1, false, STR_SUBTYPE_FRSKYL, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_SKYARTEC, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_ESKY150V2, 0, false, STR_SUBTYPE_ESKY150V2, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_JJRC345, 1, false, STR_SUBTYPE_JJRC345, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_Q90C, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_KYOSHO, 1, false, STR_SUBTYPE_KYOSHO, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_RLINK, 2, false, STR_SUBTYPE_RLINK, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_ELRS, 0, false, STR_SUBTYPE_ELRS, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_REALACC, 0, false, STR_SUBTYPE_REALACC, nullptr},
|
||||
{MODULE_SUBTYPE_MULTI_OMP, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MODULE_SUBTYPE_MULTI_WFLY2, 0, false, STR_SUBTYPE_WFLY2, STR_MULTI_OPTION},
|
||||
{MODULE_SUBTYPE_MULTI_E016HV2, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
|
||||
{MM_RF_CUSTOM_SELECTED, 7, true, STR_SUBTYPE_CUSTOM, STR_MULTI_OPTION},
|
||||
|
||||
// Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff)
|
||||
@@ -189,12 +204,13 @@ QString Multiprotocols::protocolToString(int protocol, bool custom)
|
||||
{
|
||||
static const QStringList strings({
|
||||
"FlySky", "Hubsan", "FrSky", "Hisky", "V2x2", "DSM", "Devo", "YD717", "KN", "SymaX", "SLT", "CX10", "CG023",
|
||||
"Bayang", "ESky", "MT99XX", "MJXQ", "Shenqi", "FY326", "SFHSS", "J6 PRO","FQ777","Assan","Hontai","Open LRS",
|
||||
"Bayang", "ESky", "MT99XX", "MJXQ", "Shenqi", "FY326", "Futaba", "J6 PRO","FQ777","Assan","Hontai","Open LRS",
|
||||
"FlySky AFHDS2A", "Q2x2", "WK2x01", "Q303", "GW008", "DM002", "Cabell", "ESky 150", "H8 3D", "Corona", "CFlie",
|
||||
"Hitec", "Wfly", "Bugs", "Bugs Mini", "Traxxas", "NCC-1701-A", "E01X", "WL Heli V911S", "GD00X", "Volantex V761",
|
||||
"KFPlan KF606", "Redpine", "Potensic", "ZSX", "FlyZone", "Scanner", "FrSky RX", "FlySky AFHDS2A RX", "HoTT", "Fx816",
|
||||
"KFPlan KF606", "Redpine", "Potensic", "ZSX", "Height", "Scanner", "FrSky RX", "FlySky AFHDS2A RX", "HoTT", "Fx816",
|
||||
"Bayang RX", "Pelikan", "Tiger", "XK", "XN297 Dump", "FrSky X 2.1", "FrSky R9", "Propel", "FrSky L", "Skyartec",
|
||||
"ESky 150v2", "DSM RX", "JJRC345", "Q90C"
|
||||
"ESky 150v2", "DSM RX", "JJRC345", "Q90C", "Kyosho", "RadioLink", "ExpressLRS", "Realacc", "OMP", "M-Link", "Wfly 2",
|
||||
"E016H v2"
|
||||
});
|
||||
|
||||
return strings.value(protocol, CPN_STR_UNKNOWN_ITEM);
|
||||
|
||||
@@ -45,7 +45,10 @@ inline int MAX_SWITCHES(Board::Type board, int version)
|
||||
if (IS_TARANIS_X9D(board))
|
||||
return 9;
|
||||
|
||||
if (IS_JUMPER_T12(board))
|
||||
if (IS_FAMILY_T12(board))
|
||||
return 8;
|
||||
|
||||
if (IS_TARANIS_X7(board))
|
||||
return 8;
|
||||
|
||||
return Boards::getCapability(board, Board::Switches);
|
||||
@@ -73,6 +76,8 @@ inline int MAX_POTS(Board::Type board, int version)
|
||||
{
|
||||
if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board))
|
||||
return 3;
|
||||
if (IS_FAMILY_T12(board))
|
||||
return 2;
|
||||
return Boards::getCapability(board, Board::Pots);
|
||||
}
|
||||
|
||||
@@ -82,6 +87,8 @@ inline int MAX_POTS_STORAGE(Board::Type board, int version)
|
||||
return 3;
|
||||
if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board))
|
||||
return 5;
|
||||
if (IS_FAMILY_T12(board))
|
||||
return 2;
|
||||
return Boards::getCapability(board, Board::Pots);
|
||||
}
|
||||
|
||||
@@ -89,6 +96,8 @@ inline int MAX_POTS_SOURCES(Board::Type board, int version)
|
||||
{
|
||||
if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board))
|
||||
return 5;
|
||||
if (IS_FAMILY_T12(board))
|
||||
return 2;
|
||||
return Boards::getCapability(board, Board::Pots);
|
||||
}
|
||||
|
||||
@@ -128,6 +137,14 @@ inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version)
|
||||
return 16;
|
||||
}
|
||||
|
||||
inline int MAX_MOUSE_ANALOG_SOURCES(Board::Type board, int version)
|
||||
{
|
||||
if (IS_FAMILY_HORUS_OR_T16(board))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_ROTARY_ENCODERS(board) 0
|
||||
#define MAX_FLIGHT_MODES(board, version) 9
|
||||
#define MAX_TIMERS(board, version) 3
|
||||
@@ -300,7 +317,7 @@ class SourcesConversionTable: public ConversionTable {
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<CPN_MAX_STICKS + MAX_POTS_SOURCES(board, version) + MAX_SLIDERS_SOURCES(board, version) + Boards::getCapability(board, Board::MouseAnalogs) + MAX_GYRO_ANALOGS(board, version); i++) {
|
||||
for (int i=0; i<CPN_MAX_STICKS + MAX_POTS_SOURCES(board, version) + MAX_SLIDERS_SOURCES(board, version) + MAX_MOUSE_ANALOG_SOURCES(board, version) + MAX_GYRO_ANALOGS(board, version); i++) {
|
||||
int offset = 0;
|
||||
if (version <= 218 && IS_HORUS_X10(board) && i >= CPN_MAX_STICKS + MAX_POTS_STORAGE(board, version))
|
||||
offset += 2;
|
||||
@@ -1398,8 +1415,7 @@ class CustomFunctionsConversionTable: public ConversionTable {
|
||||
addConversion(FuncAdjustGV1+i, val);
|
||||
val++;
|
||||
addConversion(FuncVolume, val++);
|
||||
addConversion(FuncSetFailsafeInternalModule, val);
|
||||
addConversion(FuncSetFailsafeExternalModule, val++);
|
||||
addConversion(FuncSetFailsafe, val++);
|
||||
addConversion(FuncRangeCheckInternalModule, val);
|
||||
addConversion(FuncRangeCheckExternalModule, val++);
|
||||
addConversion(FuncBindInternalModule, val);
|
||||
@@ -1512,9 +1528,6 @@ class ArmCustomFunctionField: public TransformedField {
|
||||
*((uint16_t *)_param) = fn.param;
|
||||
*((uint8_t *)(_param+3)) = fn.func - FuncSetTimer1;
|
||||
}
|
||||
else if (fn.func >= FuncSetFailsafeInternalModule && fn.func <= FuncSetFailsafeExternalModule) {
|
||||
*((uint16_t *)_param) = fn.func - FuncSetFailsafeInternalModule;
|
||||
}
|
||||
else if (fn.func >= FuncRangeCheckInternalModule && fn.func <= FuncRangeCheckExternalModule) {
|
||||
*((uint16_t *)_param) = fn.func - FuncRangeCheckInternalModule;
|
||||
}
|
||||
@@ -1536,7 +1549,7 @@ class ArmCustomFunctionField: public TransformedField {
|
||||
value = fn.param;
|
||||
*((uint16_t *)_param) = value;
|
||||
}
|
||||
else if (fn.func == FuncPlayValue || fn.func == FuncVolume) {
|
||||
else if (fn.func == FuncPlayValue || fn.func == FuncVolume || fn.func == FuncBacklight) {
|
||||
unsigned int value;
|
||||
sourcesConversionTable->exportValue(fn.param, (int &)value);
|
||||
*((uint16_t *)_param) = value;
|
||||
@@ -1579,7 +1592,7 @@ class ArmCustomFunctionField: public TransformedField {
|
||||
else if (fn.func == FuncPlayPrompt || fn.func == FuncBackgroundMusic || fn.func == FuncPlayScript) {
|
||||
memcpy(fn.paramarm, _param, sizeof(fn.paramarm));
|
||||
}
|
||||
else if (fn.func == FuncVolume) {
|
||||
else if (fn.func == FuncVolume || fn.func == FuncBacklight) {
|
||||
sourcesConversionTable->importValue(value, (int &)fn.param);
|
||||
}
|
||||
else if (fn.func >= FuncAdjustGV1 && fn.func <= FuncAdjustGVLast) {
|
||||
@@ -2145,15 +2158,16 @@ class ModuleUnionField: public UnionField<unsigned int> {
|
||||
module(module)
|
||||
{
|
||||
internalField.Append(new UnsignedField<3>(this, module.access.receivers));
|
||||
internalField.Append(new SpareBitsField<5>(this));
|
||||
internalField.Append(new SpareBitsField<4>(this));
|
||||
internalField.Append(new UnsignedField<1>(this, module.access.racingMode));
|
||||
|
||||
for (int i=0; i<PXX2_MAX_RECEIVERS_PER_MODULE; i++)
|
||||
for (int i = 0; i < PXX2_MAX_RECEIVERS_PER_MODULE; i++)
|
||||
internalField.Append(new CharField<8>(this, receiverName[i]));
|
||||
|
||||
memset(receiverName, 0, sizeof(receiverName));
|
||||
}
|
||||
|
||||
bool select(const unsigned int& attr) const override
|
||||
bool select(const unsigned int & attr) const override
|
||||
{
|
||||
return attr >= PULSES_ACCESS_ISRM && attr <= PULSES_ACCESS_R9M_LITE_PRO;
|
||||
}
|
||||
@@ -2298,7 +2312,8 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
|
||||
internalField.Append(new UnsignedField<2>(this, modelData.timers[i].countdownBeep));
|
||||
internalField.Append(new BoolField<1>(this, modelData.timers[i].minuteBeep));
|
||||
internalField.Append(new UnsignedField<2>(this, modelData.timers[i].persistent));
|
||||
internalField.Append(new SpareBitsField<3>(this));
|
||||
internalField.Append(new SignedField<2>(this, modelData.timers[i].countdownStart));
|
||||
internalField.Append(new UnsignedField<1>(this, modelData.timers[i].direction));
|
||||
if (HAS_LARGE_LCD(board))
|
||||
internalField.Append(new ZCharField<8>(this, modelData.timers[i].name, "Timer name"));
|
||||
else
|
||||
@@ -2413,7 +2428,8 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
|
||||
internalField.Append(new UnsignedField<2>(this, modelData.potsWarningMode));
|
||||
}
|
||||
else {
|
||||
internalField.Append(new SpareBitsField<6>(this));
|
||||
internalField.Append(new SpareBitsField<3>(this));
|
||||
internalField.Append(new UnsignedField<3>(this, modelData.thrTrimSwitch));
|
||||
internalField.Append(new UnsignedField<2>(this, modelData.potsWarningMode));
|
||||
}
|
||||
|
||||
@@ -2569,7 +2585,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
||||
generalData(generalData),
|
||||
board(board),
|
||||
version(version),
|
||||
inputsCount(CPN_MAX_STICKS + MAX_POTS_STORAGE(board, version) + MAX_SLIDERS_STORAGE(board, version) + Boards::getCapability(board, Board::MouseAnalogs))
|
||||
inputsCount(CPN_MAX_STICKS + MAX_POTS_STORAGE(board, version) + MAX_SLIDERS_STORAGE(board, version) + MAX_MOUSE_ANALOG_SOURCES(board, version))
|
||||
{
|
||||
qCDebug(eepromImport) << QString("OpenTxGeneralData::OpenTxGeneralData(board: %1, version:%2, variant:%3)").arg(board).arg(version).arg(variant);
|
||||
|
||||
@@ -2711,7 +2727,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
||||
internalField.Append(new BoolField<1>(this, generalData.disableRssiPoweroffAlarm));
|
||||
internalField.Append(new UnsignedField<2>(this, generalData.usbMode));
|
||||
internalField.Append(new UnsignedField<2>(this, generalData.jackMode));
|
||||
internalField.Append(new SpareBitsField<1>(this));
|
||||
internalField.Append(new BoolField<1>(this, generalData.sportPower));
|
||||
}
|
||||
else {
|
||||
internalField.Append(new SpareBitsField<7>(this));
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
#define TARANIS_X9LITE_VARIANT 0x0800
|
||||
#define TARANIS_X9LITES_VARIANT 0x0801
|
||||
#define JUMPER_T12_VARIANT 0x4001
|
||||
#define RADIOMASTER_TX12_VARIANT 0x4002
|
||||
#define JUMPER_TLITE_VARIANT 0x4003
|
||||
#define RADIOMASTER_T8_VARIANT 0x4004
|
||||
|
||||
class OpenTxGeneralData: public TransformedField {
|
||||
public:
|
||||
@@ -96,7 +99,7 @@ class ProtocolsConversionTable: public ConversionTable
|
||||
addConversion(PULSES_ACCESS_R9M, val++);
|
||||
addConversion(PULSES_PXX_R9M_LITE, val++);
|
||||
addConversion(PULSES_ACCESS_R9M_LITE, val++);
|
||||
addConversion(PULSES_PXX_R9M_LITE_PRO, val++);
|
||||
addConversion(PULSES_GHOST, val++);
|
||||
addConversion(PULSES_ACCESS_R9M_LITE_PRO, val++);
|
||||
|
||||
addConversion(PULSES_SBUS, val++);
|
||||
@@ -104,6 +107,7 @@ class ProtocolsConversionTable: public ConversionTable
|
||||
addConversion(PULSES_XJT_LITE_X16, val);
|
||||
addConversion(PULSES_XJT_LITE_D8, val);
|
||||
addConversion(PULSES_XJT_LITE_LR12, val++);
|
||||
|
||||
if (version >= 219) {
|
||||
addConversion(PULSES_AFHDS3, val++);
|
||||
}
|
||||
|
||||
@@ -60,12 +60,18 @@ const char * OpenTxEepromInterface::getName()
|
||||
switch (board) {
|
||||
case BOARD_JUMPER_T12:
|
||||
return "OpenTX for Jumper T12";
|
||||
case BOARD_JUMPER_TLITE:
|
||||
return "OpenTX for Jumper T-Lite";
|
||||
case BOARD_JUMPER_T16:
|
||||
return "OpenTX for Jumper T16";
|
||||
case BOARD_JUMPER_T18:
|
||||
return "OpenTX for Jumper T18";
|
||||
case BOARD_RADIOMASTER_TX16S:
|
||||
return "OpenTX for Radiomaster TX16S";
|
||||
case BOARD_RADIOMASTER_TX12:
|
||||
return "OpenTX for Radiomaster TX12";
|
||||
case BOARD_RADIOMASTER_T8:
|
||||
return "OpenTX for Radiomaster T8";
|
||||
case BOARD_TARANIS_X9D:
|
||||
return "OpenTX for FrSky Taranis X9D";
|
||||
case BOARD_TARANIS_X9DP:
|
||||
@@ -334,7 +340,15 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, u
|
||||
else if (IS_JUMPER_T12(board)) {
|
||||
variant |= JUMPER_T12_VARIANT;
|
||||
}
|
||||
|
||||
else if (IS_JUMPER_TLITE(board)) {
|
||||
variant |= JUMPER_TLITE_VARIANT;
|
||||
}
|
||||
else if (IS_RADIOMASTER_TX12(board)) {
|
||||
variant |= RADIOMASTER_TX12_VARIANT;
|
||||
}
|
||||
else if (IS_RADIOMASTER_T8(board)) {
|
||||
variant |= RADIOMASTER_T8_VARIANT;
|
||||
}
|
||||
OpenTxGeneralData generator((GeneralSettings &)radioData.generalSettings, board, version, variant);
|
||||
// generator.dump();
|
||||
QByteArray data;
|
||||
@@ -520,7 +534,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
case MaxVolume:
|
||||
return 23;
|
||||
case MaxContrast:
|
||||
if (IS_TARANIS_SMALL(board) || IS_JUMPER_T12(board))
|
||||
if (IS_TARANIS_SMALL(board))
|
||||
return 30;
|
||||
else
|
||||
return 45;
|
||||
@@ -540,7 +554,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
case Simulation:
|
||||
return 1;
|
||||
case NumCurves:
|
||||
return (HAS_LARGE_LCD(board) ? 32 : 16);
|
||||
return 32;
|
||||
case HasMixerNames:
|
||||
return (IS_TARANIS_X9(board) ? 8 : 6);
|
||||
case HasExpoNames:
|
||||
@@ -615,7 +629,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
case LcdWidth:
|
||||
if (IS_FAMILY_HORUS_OR_T16(board))
|
||||
return 480;
|
||||
else if (IS_TARANIS_SMALL(board) || IS_JUMPER_T12(board))
|
||||
else if (IS_TARANIS_SMALL(board))
|
||||
return 128;
|
||||
else if (IS_TARANIS(board))
|
||||
return 212;
|
||||
@@ -629,7 +643,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
case LcdDepth:
|
||||
if (IS_FAMILY_HORUS_OR_T16(board))
|
||||
return 16;
|
||||
else if (IS_TARANIS_SMALL(board) || IS_JUMPER_T12(board))
|
||||
else if (IS_TARANIS_SMALL(board))
|
||||
return 1;
|
||||
else if (IS_TARANIS(board))
|
||||
return 4;
|
||||
@@ -679,6 +693,12 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
return TARANIS_XLITE_VARIANT;
|
||||
else if (IS_JUMPER_T12(board))
|
||||
return JUMPER_T12_VARIANT;
|
||||
else if (IS_JUMPER_TLITE(board))
|
||||
return JUMPER_TLITE_VARIANT;
|
||||
else if (IS_RADIOMASTER_TX12(board))
|
||||
return RADIOMASTER_TX12_VARIANT;
|
||||
else if (IS_RADIOMASTER_T8(board))
|
||||
return RADIOMASTER_T8_VARIANT;
|
||||
else
|
||||
return 0;
|
||||
case MavlinkTelemetry:
|
||||
@@ -696,6 +716,8 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
return IS_FAMILY_HORUS_OR_T16(board);
|
||||
case HasSwitchableJack:
|
||||
return IS_TARANIS_XLITES(board);
|
||||
case HasSportConnector:
|
||||
return IS_ACCESS_RADIO(board, id) || IS_TARANIS_X7(board) || IS_HORUS_X10(board) || IS_TARANIS_XLITE(board);
|
||||
case PwrButtonPress:
|
||||
return IS_HORUS_OR_TARANIS(board) && (board!=Board::BOARD_TARANIS_X9D) && (board!=Board::BOARD_TARANIS_X9DP);
|
||||
case Sensors:
|
||||
@@ -731,14 +753,14 @@ bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
|
||||
return true;
|
||||
case PULSES_PXX_XJT_X16:
|
||||
case PULSES_PXX_XJT_LR12:
|
||||
return !IS_ACCESS_RADIO(board, id) && !IS_FAMILY_T16(board) && !IS_JUMPER_T12(board);
|
||||
return !IS_ACCESS_RADIO(board, id) && !IS_FAMILY_T16(board) && !IS_FAMILY_T12(board);
|
||||
case PULSES_PXX_XJT_D8:
|
||||
return !(IS_ACCESS_RADIO(board, id) || id.contains("eu")) && !IS_FAMILY_T16(board) && !IS_JUMPER_T12(board);
|
||||
return !(IS_ACCESS_RADIO(board, id) || id.contains("eu")) && !IS_FAMILY_T16(board) && !IS_FAMILY_T12(board);
|
||||
case PULSES_ACCESS_ISRM:
|
||||
case PULSES_ACCST_ISRM_D16:
|
||||
return IS_ACCESS_RADIO(board, id);
|
||||
case PULSES_MULTIMODULE:
|
||||
return id.contains("internalmulti") || IS_RADIOMASTER_TX16S(board) || IS_JUMPER_T18(board);
|
||||
return id.contains("internalmulti") || IS_RADIOMASTER_TX16S(board) || IS_JUMPER_T18(board) || IS_RADIOMASTER_TX12(board) || IS_JUMPER_TLITE(board);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -760,16 +782,17 @@ bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
|
||||
case PULSES_MULTIMODULE:
|
||||
case PULSES_CROSSFIRE:
|
||||
case PULSES_AFHDS3:
|
||||
case PULSES_GHOST:
|
||||
return true;
|
||||
case PULSES_ACCESS_R9M:
|
||||
return IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || board == BOARD_TARANIS_X9DP_2019 || board == BOARD_X10_EXPRESS || (IS_FAMILY_HORUS_OR_T16(board) && id.contains("internalaccess"));
|
||||
return IS_ACCESS_RADIO(board, id) || (IS_FAMILY_HORUS_OR_T16(board) && id.contains("externalaccessmod"));
|
||||
case PULSES_PXX_R9M_LITE:
|
||||
case PULSES_ACCESS_R9M_LITE:
|
||||
case PULSES_ACCESS_R9M_LITE_PRO:
|
||||
case PULSES_XJT_LITE_X16:
|
||||
case PULSES_XJT_LITE_D8:
|
||||
case PULSES_XJT_LITE_LR12:
|
||||
return (IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board));
|
||||
return (IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || IS_JUMPER_TLITE(board));
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -940,6 +963,21 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
|
||||
variantError = true;
|
||||
}
|
||||
}
|
||||
else if (IS_JUMPER_TLITE(board)) {
|
||||
if (variant != JUMPER_TLITE_VARIANT) {
|
||||
variantError = true;
|
||||
}
|
||||
}
|
||||
else if (IS_RADIOMASTER_TX12(board)) {
|
||||
if (variant != RADIOMASTER_TX12_VARIANT) {
|
||||
variantError = true;
|
||||
}
|
||||
}
|
||||
else if (IS_RADIOMASTER_T8(board)) {
|
||||
if (variant != RADIOMASTER_T8_VARIANT) {
|
||||
variantError = true;
|
||||
}
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
if (variant != 0) {
|
||||
variantError = true;
|
||||
@@ -1188,19 +1226,19 @@ void registerOpenTxFirmwares()
|
||||
firmware->addOption("horussticks", Firmware::tr("Horus gimbals installed (Hall sensors)"));
|
||||
addOpenTxTaranisOptions(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, EU + FLEX + AFHDS3);
|
||||
addOpenTxRfOptions(firmware, EU + FLEX);
|
||||
|
||||
/* FrSky X9-Lite board */
|
||||
firmware = new OpenTxFirmware("opentx-x9lite", Firmware::tr("FrSky Taranis X9-Lite"), BOARD_TARANIS_X9LITE);
|
||||
addOpenTxTaranisOptions(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
|
||||
/* FrSky X9-LiteS board */
|
||||
firmware = new OpenTxFirmware("opentx-x9lites", Firmware::tr("FrSky Taranis X9-Lite S"), BOARD_TARANIS_X9LITES);
|
||||
addOpenTxTaranisOptions(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
|
||||
/* FrSky X7 board */
|
||||
firmware = new OpenTxFirmware("opentx-x7", Firmware::tr("FrSky Taranis X7 / X7S"), BOARD_TARANIS_X7);
|
||||
@@ -1218,7 +1256,7 @@ void registerOpenTxFirmwares()
|
||||
firmware = new OpenTxFirmware("opentx-xlites", Firmware::tr("FrSky Taranis X-Lite S/PRO"), BOARD_TARANIS_XLITES);
|
||||
addOpenTxTaranisOptions(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
|
||||
/* FrSky X-Lite board */
|
||||
firmware = new OpenTxFirmware("opentx-xlite", Firmware::tr("FrSky Taranis X-Lite"), BOARD_TARANIS_XLITE);
|
||||
@@ -1231,6 +1269,7 @@ void registerOpenTxFirmwares()
|
||||
firmware = new OpenTxFirmware("opentx-x10", Firmware::tr("FrSky Horus X10 / X10S"), BOARD_X10);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
firmware->addOption("internalaccess", Firmware::tr("Support for ACCESS internal module replacement"));
|
||||
firmware->addOption("externalaccessmod", Firmware::tr("Support hardware mod: R9M ACCESS"));
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, EU + FLEX);
|
||||
|
||||
@@ -1244,6 +1283,7 @@ void registerOpenTxFirmwares()
|
||||
firmware = new OpenTxFirmware("opentx-x12s", Firmware::tr("FrSky Horus X12S"), BOARD_HORUS_X12S);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
firmware->addOption("internalaccess", Firmware::tr("Support for ACCESS internal module replacement"));
|
||||
firmware->addOption("externalaccessmod", Firmware::tr("Support hardware mod: R9M ACCESS"));
|
||||
firmware->addOption("pcbdev", Firmware::tr("Use ONLY with first DEV pcb version"));
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, EU + FLEX);
|
||||
@@ -1257,29 +1297,63 @@ void registerOpenTxFirmwares()
|
||||
firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module"));
|
||||
addOpenTxFontOptions(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
|
||||
/* Jumper T-Lite board */
|
||||
firmware = new OpenTxFirmware("opentx-tlite", QCoreApplication::translate("Firmware", "Jumper T-Lite"), BOARD_JUMPER_TLITE);
|
||||
addOpenTxCommonOptions(firmware);
|
||||
firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support"));
|
||||
firmware->addOption("nogvars", Firmware::tr("Disable Global variables"));
|
||||
firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen"));
|
||||
addOpenTxFontOptions(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
|
||||
/* Jumper T16 board */
|
||||
firmware = new OpenTxFirmware("opentx-t16", Firmware::tr("Jumper T16 / T16+ / T16 Pro"), BOARD_JUMPER_T16);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module"));
|
||||
firmware->addOption("bluetooth", Firmware::tr("Support for bluetooth module"));
|
||||
firmware->addOption("externalaccessmod", Firmware::tr("Support hardware mod: R9M ACCESS"));
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
registerOpenTxFirmware(firmware);
|
||||
|
||||
/* Radiomaster TX12 board */
|
||||
firmware = new OpenTxFirmware("opentx-tx12", QCoreApplication::translate("Firmware", "Radiomaster TX12"), BOARD_RADIOMASTER_TX12);
|
||||
addOpenTxCommonOptions(firmware);
|
||||
firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support"));
|
||||
firmware->addOption("nogvars", Firmware::tr("Disable Global variables"));
|
||||
firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen"));
|
||||
addOpenTxFontOptions(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
|
||||
/* Radiomaster T8 board */
|
||||
firmware = new OpenTxFirmware("opentx-t8", QCoreApplication::translate("Firmware", "Radiomaster T8"), BOARD_RADIOMASTER_T8);
|
||||
addOpenTxCommonOptions(firmware);
|
||||
firmware->addOption("noheli", Firmware::tr("Disable HELI menu and cyclic mix support"));
|
||||
firmware->addOption("nogvars", Firmware::tr("Disable Global variables"));
|
||||
firmware->addOption("lua", Firmware::tr("Enable Lua custom scripts screen"));
|
||||
addOpenTxFontOptions(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, NONE);
|
||||
firmware->addOption("bindkey", Firmware::tr("Allow bind using bind key"));
|
||||
|
||||
/* Radiomaster TX16S board */
|
||||
firmware = new OpenTxFirmware("opentx-tx16s", Firmware::tr("Radiomaster TX16s / TX16s Hall / TX16s Masterfire"), BOARD_RADIOMASTER_TX16S);
|
||||
firmware = new OpenTxFirmware("opentx-tx16s", Firmware::tr("Radiomaster TX16S / SE / Hall / Masterfire"), BOARD_RADIOMASTER_TX16S);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
static const Firmware::Option opt_bt("bluetooth", Firmware::tr("Support for bluetooth module"));
|
||||
static const Firmware::Option opt_internal_gps("internalgps", Firmware::tr("Support internal GPS"));
|
||||
firmware->addOptionsGroup({opt_bt, opt_internal_gps});
|
||||
firmware->addOption("externalaccessmod", Firmware::tr("Support hardware mod: R9M ACCESS"));
|
||||
registerOpenTxFirmware(firmware);
|
||||
|
||||
/* Jumper T18 board */
|
||||
firmware = new OpenTxFirmware("opentx-t18", Firmware::tr("Jumper T18"), BOARD_JUMPER_T18);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
firmware->addOption("bluetooth", Firmware::tr("Support for bluetooth module"));
|
||||
firmware->addOption("externalaccessmod", Firmware::tr("Support hardware mod: R9M ACCESS"));
|
||||
registerOpenTxFirmware(firmware);
|
||||
addOpenTxRfOptions(firmware, FLEX);
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "output_data.h"
|
||||
#include "radiodata.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
|
||||
void LimitData::clear()
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(LimitData));
|
||||
min = -1000;
|
||||
max = +1000;
|
||||
}
|
||||
|
||||
bool LimitData::isEmpty() const
|
||||
{
|
||||
LimitData tmp;
|
||||
return !memcmp(this, &tmp, sizeof(LimitData));
|
||||
}
|
||||
|
||||
QString LimitData::minToString() const
|
||||
{
|
||||
return QString::number((qreal)min / 10);
|
||||
}
|
||||
|
||||
QString LimitData::maxToString() const
|
||||
{
|
||||
return QString::number((qreal)max / 10);
|
||||
}
|
||||
|
||||
QString LimitData::revertToString() const
|
||||
{
|
||||
return revert ? tr("INV") : tr("NOR");
|
||||
}
|
||||
|
||||
QString LimitData::nameToString(int index) const
|
||||
{
|
||||
return RadioData::getElementName(tr("CH"), index + 1, name);
|
||||
}
|
||||
|
||||
QString LimitData::offsetToString() const
|
||||
{
|
||||
return QString::number((qreal)offset / 10, 'f', 1);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "curvereference.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
#define LIMITDATA_NAME_LEN 6
|
||||
|
||||
class LimitData {
|
||||
Q_DECLARE_TR_FUNCTIONS(LimitData)
|
||||
|
||||
public:
|
||||
LimitData() { clear(); }
|
||||
|
||||
int min;
|
||||
int max;
|
||||
bool revert;
|
||||
int offset;
|
||||
int ppmCenter;
|
||||
bool symetrical;
|
||||
int failsafe;
|
||||
char name[LIMITDATA_NAME_LEN + 1];
|
||||
CurveReference curve;
|
||||
|
||||
void clear();
|
||||
bool isEmpty() const;
|
||||
QString minToString() const;
|
||||
QString maxToString() const;
|
||||
QString offsetToString() const;
|
||||
QString revertToString() const;
|
||||
QString nameToString(int index) const;
|
||||
};
|
||||
@@ -22,23 +22,6 @@
|
||||
#include "radiodataconversionstate.h"
|
||||
#include "eeprominterface.h"
|
||||
|
||||
// static
|
||||
QString RadioData::getElementName(const QString & prefix, unsigned int index, const char * name, bool padding)
|
||||
{
|
||||
QString result = prefix;
|
||||
if (padding)
|
||||
result += QString("%1").arg(index, 2, 10, QChar('0'));
|
||||
else
|
||||
result += QString("%1").arg(index);
|
||||
if (name) {
|
||||
QString trimmed = QString(name).trimmed();
|
||||
if (trimmed.length() > 0) {
|
||||
result += ":" + QString(name).trimmed();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
RadioData::RadioData()
|
||||
{
|
||||
models.resize(getCurrentFirmware()->getCapability(Models));
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#ifndef _RADIODATA_H_
|
||||
#define _RADIODATA_H_
|
||||
#pragma once
|
||||
|
||||
#include "generalsettings.h"
|
||||
#include "modeldata.h"
|
||||
|
||||
#include "datahelpers.h" // required for getElementName
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class RadioDataConversionState;
|
||||
@@ -32,10 +33,10 @@ class RadioData {
|
||||
void fixModelFilenames();
|
||||
QString getNextModelFilename();
|
||||
|
||||
static QString getElementName(const QString & prefix, unsigned int index, const char * name = 0, bool padding = false);
|
||||
// leave here until all calls repointed
|
||||
static QString getElementName(const QString & prefix, unsigned int index, const char * name = 0, bool padding = false)
|
||||
{ return DataHelpers::getElementName(prefix, index, name, padding); }
|
||||
|
||||
protected:
|
||||
void fixModelFilename(unsigned int index);
|
||||
};
|
||||
|
||||
#endif // _RADIODATA_H_
|
||||
|
||||
@@ -60,7 +60,7 @@ RawSourceRange RawSource::getRange(const ModelData * model, const GeneralSetting
|
||||
result.min = -30000 * result.step;
|
||||
result.max = +30000 * result.step;
|
||||
result.decimals = sensor.prec;
|
||||
result.unit = sensor.unitString();
|
||||
result.unit = SensorData::unitToString(qr.quot);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -140,32 +140,17 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
tr("Batt"), tr("Time"), tr("Timer1"), tr("Timer2"), tr("Timer3"),
|
||||
};
|
||||
|
||||
static const QString telemetry[] = {
|
||||
tr("Batt"), tr("Time"), tr("Timer1"), tr("Timer2"), tr("Timer3"),
|
||||
tr("RAS"), tr("RSSI Tx"), tr("RSSI Rx"),
|
||||
tr("A1"), tr("A2"), tr("A3"), tr("A4"),
|
||||
tr("Alt"), tr("Rpm"), tr("Fuel"), tr("T1"), tr("T2"),
|
||||
tr("Speed"), tr("Dist"), tr("GPS Alt"),
|
||||
tr("Cell"), tr("Cells"), tr("Vfas"), tr("Curr"), tr("Cnsp"), tr("Powr"),
|
||||
tr("AccX"), tr("AccY"), tr("AccZ"),
|
||||
tr("Hdg "), tr("VSpd"), tr("AirSpeed"), tr("dTE"),
|
||||
tr("A1-"), tr("A2-"), tr("A3-"), tr("A4-"),
|
||||
tr("Alt-"), tr("Alt+"), tr("Rpm+"), tr("T1+"), tr("T2+"), tr("Speed+"), tr("Dist+"), tr("AirSpeed+"),
|
||||
tr("Cell-"), tr("Cells-"), tr("Vfas-"), tr("Curr+"), tr("Powr+"),
|
||||
tr("ACC"), tr("GPS Time"),
|
||||
};
|
||||
|
||||
static const QString rotary[] = { tr("REa"), tr("REb") };
|
||||
|
||||
if (index<0) {
|
||||
return tr("???");
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
|
||||
QString result;
|
||||
int genAryIdx = 0;
|
||||
switch (type) {
|
||||
case SOURCE_TYPE_NONE:
|
||||
return tr("----");
|
||||
return QString(CPN_STR_NONE_ITEM);
|
||||
|
||||
case SOURCE_TYPE_VIRTUAL_INPUT:
|
||||
{
|
||||
@@ -176,7 +161,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
}
|
||||
|
||||
case SOURCE_TYPE_LUA_OUTPUT:
|
||||
return tr("LUA%1%2").arg(index/16+1).arg(QChar('a'+index%16));
|
||||
return tr("LUA%1%2").arg(index / 16 + 1).arg(QChar('a' + index % 16));
|
||||
|
||||
case SOURCE_TYPE_STICK:
|
||||
if (generalSettings) {
|
||||
@@ -208,10 +193,10 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
return result;
|
||||
|
||||
case SOURCE_TYPE_CUSTOM_SWITCH:
|
||||
return RawSwitch(SWITCH_TYPE_VIRTUAL, index+1).toString();
|
||||
return RawSwitch(SWITCH_TYPE_VIRTUAL, index + 1).toString();
|
||||
|
||||
case SOURCE_TYPE_CYC:
|
||||
return tr("CYC%1").arg(index+1);
|
||||
return tr("CYC%1").arg(index + 1);
|
||||
|
||||
case SOURCE_TYPE_PPM:
|
||||
return RadioData::getElementName(tr("TR", "as in Trainer"), index + 1);
|
||||
@@ -223,7 +208,16 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
return LimitData().nameToString(index);
|
||||
|
||||
case SOURCE_TYPE_SPECIAL:
|
||||
return CHECK_IN_ARRAY(special, index);
|
||||
if (index >= SOURCE_TYPE_SPECIAL_TIMER1_IDX && index <= SOURCE_TYPE_SPECIAL_TIMER1_IDX + CPN_MAX_TIMERS - 1) {
|
||||
if (model)
|
||||
result = model->timers[index - SOURCE_TYPE_SPECIAL_TIMER1_IDX].nameToString(index - SOURCE_TYPE_SPECIAL_TIMER1_IDX);
|
||||
else
|
||||
result = TimerData().nameToString(index - SOURCE_TYPE_SPECIAL_TIMER1_IDX);
|
||||
}
|
||||
else
|
||||
result = CHECK_IN_ARRAY(special, index);
|
||||
|
||||
return result;
|
||||
|
||||
case SOURCE_TYPE_TELEMETRY:
|
||||
{
|
||||
@@ -244,7 +238,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
return GVarData().nameToString(index);
|
||||
|
||||
default:
|
||||
return tr("???");
|
||||
return QString(CPN_STR_UNKNOWN_ITEM);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,111 +341,40 @@ RawSource RawSource::convert(RadioDataConversionState & cstate)
|
||||
RadioDataConversionState::LogField oldData(index, toString(cstate.fromModel(), cstate.fromGS(), cstate.fromType));
|
||||
|
||||
if (type == SOURCE_TYPE_STICK) {
|
||||
if (cstate.toBoard.getCapability(Board::Sliders)) {
|
||||
if (index >= cstate.fromBoard.getCapability(Board::Sticks) + cstate.fromBoard.getCapability(Board::Pots)) {
|
||||
// 1st slider alignment
|
||||
index += cstate.toBoard.getCapability(Board::Pots) - cstate.fromBoard.getCapability(Board::Pots);
|
||||
}
|
||||
|
||||
if (isSlider(0, cstate.fromType)) {
|
||||
// LS and RS sliders are after 2 aux sliders on X12 and X9E
|
||||
if ((IS_HORUS_X12S(cstate.toType) || IS_TARANIS_X9E(cstate.toType)) && !IS_HORUS_X12S(cstate.fromType) && !IS_TARANIS_X9E(cstate.fromType)) {
|
||||
if (index >= 7) {
|
||||
index += 2; // LS/RS to LS/RS
|
||||
}
|
||||
}
|
||||
else if (!IS_TARANIS_X9E(cstate.toType) && !IS_HORUS_X12S(cstate.toType) && (IS_HORUS_X12S(cstate.fromType) || IS_TARANIS_X9E(cstate.fromType))) {
|
||||
if (index >= 7 && index <= 8) {
|
||||
index += 2; // aux sliders to spare analogs (which may not exist, this is validated later)
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
else if (index >= 9 && index <= 10) {
|
||||
index -= 2; // LS/RS to LS/RS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_TARANIS(cstate.toType) && IS_FAMILY_HORUS_OR_T16(cstate.fromType)) {
|
||||
if (index == 6)
|
||||
index = 5; // pot S2 to S2
|
||||
else if (index == 5)
|
||||
index = -1; // 6P on Horus doesn't exist on Taranis
|
||||
}
|
||||
else if (IS_FAMILY_HORUS_OR_T16(cstate.toType) && IS_TARANIS(cstate.fromType) && index == 5)
|
||||
{
|
||||
index = 6; // pot S2 to S2
|
||||
}
|
||||
|
||||
} // SOURCE_TYPE_STICK
|
||||
QStringList fromStickList(getStickList(cstate.fromBoard));
|
||||
QStringList toStickList(getStickList(cstate.toBoard));
|
||||
index = toStickList.indexOf(fromStickList.at(oldData.id));
|
||||
// index set to -1 if no match found
|
||||
// perform forced mapping
|
||||
}
|
||||
|
||||
if (type == SOURCE_TYPE_SWITCH) {
|
||||
// SWI to SWR don't exist on !X9E board
|
||||
if (!IS_TARANIS_X9E(cstate.toType) && IS_TARANIS_X9E(cstate.fromType)) {
|
||||
if (index >= 8) {
|
||||
index = index % 8;
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
QStringList fromSwitchList(getSwitchList(cstate.fromBoard));
|
||||
QStringList toSwitchList(getSwitchList(cstate.toBoard));
|
||||
index = toSwitchList.indexOf(fromSwitchList.at(oldData.id));
|
||||
// index set to -1 if no match found
|
||||
// perform forced mapping
|
||||
if (index < 0) {
|
||||
if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
// No SE and SG on X7 board
|
||||
index = toSwitchList.indexOf("SD");
|
||||
if (index >= 0)
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
else if (IS_FAMILY_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
// No SE and SG on T12 board
|
||||
index = toSwitchList.indexOf("SD");
|
||||
if (index >= 0)
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
// No SE and SG on X7 board
|
||||
if (index == 4 || index == 6) {
|
||||
index = 3; // SG and SE to SD
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
else if (index == 5) {
|
||||
index = 4; // SF to SF
|
||||
}
|
||||
else if (index == 7) {
|
||||
index = 5; // SH to SH
|
||||
}
|
||||
}
|
||||
else if (IS_JUMPER_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
// No SE and SG on T12 board
|
||||
if (index == 4 || index == 6) {
|
||||
index = 3; // SG and SE to SD
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
else if (index == 5) {
|
||||
index = 4; // SF to SF
|
||||
}
|
||||
else if (index == 7) {
|
||||
index = 5; // SH to SH
|
||||
}
|
||||
}
|
||||
// Compensate for SE and SG on X9/Horus board if converting from X7
|
||||
else if ((IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) && IS_TARANIS_X7(cstate.fromType)) {
|
||||
if (index == 4) {
|
||||
index = 5; // SF to SF
|
||||
}
|
||||
else if (index == 5) {
|
||||
index = 7; // SH to SH
|
||||
}
|
||||
}
|
||||
else if ((IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) {
|
||||
if (index == 4) {
|
||||
index = 5; // SF to SF
|
||||
}
|
||||
else if (index == 5) {
|
||||
index = 7; // SH to SH
|
||||
}
|
||||
}
|
||||
else if ((IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) {
|
||||
if (index == 4) {
|
||||
index = 5; // SF to SF
|
||||
}
|
||||
else if (index == 5) {
|
||||
index = 7; // SH to SH
|
||||
}
|
||||
}
|
||||
} // SOURCE_TYPE_SWITCH
|
||||
}
|
||||
|
||||
// final validation (we do not pass model to isAvailable() because we don't know what has or hasn't been converted)
|
||||
if (!isAvailable(NULL, cstate.toGS(), cstate.toType)) {
|
||||
if (index < 0 || !isAvailable(NULL, cstate.toGS(), cstate.toType)) {
|
||||
cstate.setInvalid(oldData);
|
||||
index = -1; // TODO: better way to flag invalid sources?
|
||||
type = MAX_SOURCE_TYPE;
|
||||
// no source is safer than an invalid one
|
||||
clear();
|
||||
}
|
||||
else if (evt == RadioDataConversionState::EVT_CVRT) {
|
||||
cstate.setConverted(oldData, RadioDataConversionState::LogField(index, toString(cstate.toModel(), cstate.toGS(), cstate.toType)));
|
||||
@@ -463,3 +386,23 @@ RawSource RawSource::convert(RadioDataConversionState & cstate)
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QStringList RawSource::getStickList(Boards board) const
|
||||
{
|
||||
QStringList ret;
|
||||
|
||||
for (int i = 0; i < board.getCapability(Board::MaxAnalogs); i++) {
|
||||
ret.append(board.getAnalogInputName(i));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList RawSource::getSwitchList(Boards board) const
|
||||
{
|
||||
QStringList ret;
|
||||
|
||||
for (int i = 0; i < board.getCapability(Board::Switches); i++) {
|
||||
ret.append(board.getSwitchInfo(i).name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -178,6 +178,9 @@ enum RawSourceType {
|
||||
MAX_SOURCE_TYPE
|
||||
};
|
||||
|
||||
constexpr int SOURCE_TYPE_STICK_THR_IDX { 3 }; // TODO is there a function to determine index?
|
||||
constexpr int SOURCE_TYPE_SPECIAL_TIMER1_IDX { 2 }; // TODO temp const until Timers own source type
|
||||
|
||||
class RawSourceRange
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(RawSourceRange)
|
||||
@@ -252,6 +255,8 @@ class RawSource {
|
||||
bool isAvailable(const ModelData * const model = NULL, const GeneralSettings * const gs = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
bool isSet() const { return type != SOURCE_TYPE_NONE || index != 0; }
|
||||
void clear() { type = SOURCE_TYPE_NONE; index = 0; }
|
||||
QStringList getStickList(Boards board) const;
|
||||
QStringList getSwitchList(Boards board) const;
|
||||
|
||||
bool operator == ( const RawSource & other) const {
|
||||
return (this->type == other.type) && (this->index == other.index);
|
||||
|
||||
@@ -59,7 +59,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
tr("THs"), tr("TH%"), tr("THt")
|
||||
};
|
||||
|
||||
const QStringList directionIndicators = QStringList()
|
||||
static const QStringList directionIndicators = QStringList()
|
||||
<< CPN_STR_SW_INDICATOR_UP
|
||||
<< CPN_STR_SW_INDICATOR_NEUT
|
||||
<< CPN_STR_SW_INDICATOR_DN;
|
||||
@@ -184,77 +184,39 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate)
|
||||
RadioDataConversionState::EventType evt = RadioDataConversionState::EVT_NONE;
|
||||
RadioDataConversionState::LogField oldData(index, toString(cstate.fromType, cstate.fromGS(), cstate.fromModel()));
|
||||
|
||||
int newIdx = 0;
|
||||
|
||||
if (type == SWITCH_TYPE_SWITCH) {
|
||||
int srcIdx = div(abs(index)-1, 3).quot; // raw source index
|
||||
int delta = 0;
|
||||
|
||||
// SWI to SWR don't exist on !X9E board
|
||||
if (!IS_TARANIS_X9E(cstate.toType) && IS_TARANIS_X9E(cstate.fromType)) {
|
||||
if (srcIdx > 7) {
|
||||
index %= 24;
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
}
|
||||
|
||||
// No SE and SG on X7 board
|
||||
if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
if (srcIdx == 4 || srcIdx == 5) {
|
||||
delta = 3; // SE to SD & SF to SF
|
||||
if (srcIdx == 4)
|
||||
div_t swtch = div(abs(index) - 1, 3); // rawsource index
|
||||
QStringList fromSwitchList(getSwitchList(cstate.fromBoard));
|
||||
QStringList toSwitchList(getSwitchList(cstate.toBoard));
|
||||
// set to -1 if no match found
|
||||
newIdx = toSwitchList.indexOf(fromSwitchList.at(swtch.quot));
|
||||
// perform forced mapping
|
||||
if (newIdx < 0) {
|
||||
if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
// No SE and SG on X7 board
|
||||
newIdx = toSwitchList.indexOf("SD");
|
||||
if (newIdx >= 0)
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
else if (srcIdx == 6) {
|
||||
delta = 9; // SG to SD
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
else if (srcIdx == 7) {
|
||||
delta = 6; // SH to SH
|
||||
}
|
||||
}
|
||||
else if (IS_JUMPER_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
if (srcIdx == 4 || srcIdx == 5) {
|
||||
delta = 3; // SE to SD & SF to SF
|
||||
if (srcIdx == 4)
|
||||
else if (IS_FAMILY_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType))) {
|
||||
// No SE and SG on T12 board
|
||||
newIdx = toSwitchList.indexOf("SD");
|
||||
if (newIdx >= 0)
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
else if (srcIdx == 6) {
|
||||
delta = 9; // SG to SD
|
||||
evt = RadioDataConversionState::EVT_CVRT;
|
||||
}
|
||||
else if (srcIdx == 7) {
|
||||
delta = 6; // SH to SH
|
||||
}
|
||||
}
|
||||
// Compensate for SE and SG on X9/Horus board if converting from X7
|
||||
else if ((IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) && IS_TARANIS_X7(cstate.fromType)) {
|
||||
if (srcIdx == 4) {
|
||||
delta = -3; // SF to SF
|
||||
}
|
||||
else if (srcIdx == 5) {
|
||||
delta = -6; // SH to SH
|
||||
}
|
||||
}
|
||||
else if ((IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) {
|
||||
if (srcIdx == 4) {
|
||||
delta = -3; // SF to SF
|
||||
}
|
||||
else if (srcIdx == 5) {
|
||||
delta = -6; // SH to SH
|
||||
}
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
delta = -delta; // invert for !switch
|
||||
}
|
||||
|
||||
index -= delta;
|
||||
|
||||
if (newIdx >= 0)
|
||||
index = (newIdx * 3 + 1 + swtch.rem) * (index < 0 ? -1 : 1);
|
||||
} // SWITCH_TYPE_SWITCH
|
||||
|
||||
// final validation (we do not pass model to isAvailable() because we don't know what has or hasn't been converted)
|
||||
if (!isAvailable(NULL, cstate.toGS(), cstate.toType)) {
|
||||
if (newIdx < 0 || !isAvailable(NULL, cstate.toGS(), cstate.toType)) {
|
||||
cstate.setInvalid(oldData);
|
||||
type = MAX_SWITCH_TYPE; // TODO: better way to flag invalid switches?
|
||||
// no switch is safer than an invalid one
|
||||
clear();
|
||||
}
|
||||
else if (evt == RadioDataConversionState::EVT_CVRT) {
|
||||
cstate.setConverted(oldData, RadioDataConversionState::LogField(index, toString(cstate.toType, cstate.toGS(), cstate.toModel())));
|
||||
@@ -266,3 +228,13 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate)
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QStringList RawSwitch::getSwitchList(Boards board) const
|
||||
{
|
||||
QStringList ret;
|
||||
|
||||
for (int i = 0; i < board.getCapability(Board::Switches); i++) {
|
||||
ret.append(board.getSwitchInfo(i).name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ class RawSwitch {
|
||||
bool isAvailable(const ModelData * const model = NULL, const GeneralSettings * const gs = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
|
||||
bool isSet() const { return type != SWITCH_TYPE_NONE || index != 0; }
|
||||
void clear() { type = SWITCH_TYPE_NONE; index = 0; }
|
||||
QStringList getSwitchList(Boards board) const;
|
||||
|
||||
bool operator== ( const RawSwitch& other) const {
|
||||
return (this->type == other.type) && (this->index == other.index);
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
*/
|
||||
|
||||
#include "sensordata.h"
|
||||
|
||||
#include "radiodata.h"
|
||||
#include "modeldata.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "compounditemmodels.h"
|
||||
|
||||
void SensorData::updateUnit()
|
||||
{
|
||||
@@ -31,9 +31,322 @@ void SensorData::updateUnit()
|
||||
}
|
||||
}
|
||||
|
||||
QString SensorData::unitString() const
|
||||
QString SensorData::nameToString(int index) const
|
||||
{
|
||||
switch (unit) {
|
||||
return DataHelpers::getElementName(tr("TELE"), index + 1, label);
|
||||
}
|
||||
|
||||
QString SensorData::getOrigin(const ModelData * model) const
|
||||
{
|
||||
if (type != TELEM_TYPE_CUSTOM || !id)
|
||||
return QString();
|
||||
|
||||
const ModuleData & module = model->moduleData[moduleIdx];
|
||||
if (module.isPxx2Module() && rxIdx <= 2 && module.access.receivers & (1 << rxIdx)) {
|
||||
return QString(module.access.receiverName[rxIdx]);
|
||||
}
|
||||
else {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
bool SensorData::isEmpty() const
|
||||
{
|
||||
return (!isAvailable() && type == 0 && id == 0 && subid == 0 && instance == 0 && rxIdx == 0 && moduleIdx == 0 && unit == 0 && ratio == 0 && prec == 0 && offset == 0 && autoOffset == 0 && filter == 0 && onlyPositive == 0 && logs == 0);
|
||||
}
|
||||
|
||||
QString SensorData::idToString() const
|
||||
{
|
||||
return idToString(id);
|
||||
}
|
||||
|
||||
QString SensorData::typeToString() const
|
||||
{
|
||||
return typeToString(type);
|
||||
}
|
||||
|
||||
QString SensorData::formulaToString() const
|
||||
{
|
||||
return formulaToString(formula);
|
||||
}
|
||||
|
||||
QString SensorData::cellIndexToString() const
|
||||
{
|
||||
return cellIndexToString(index);
|
||||
}
|
||||
|
||||
QString SensorData::unitToString() const
|
||||
{
|
||||
return unitToString(unit);
|
||||
}
|
||||
|
||||
QString SensorData::precToString() const
|
||||
{
|
||||
return precToString(prec);
|
||||
}
|
||||
|
||||
int SensorData::getMask() const
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
if (type == TELEM_TYPE_CALCULATED) {
|
||||
if (formula < TELEM_FORMULA_CELL)
|
||||
mask |= SENSOR_ISCONFIGURABLE | SENSOR_HAS_POSITIVE;
|
||||
if (formula == TELEM_FORMULA_DIST)
|
||||
mask |= SENSOR_HAS_GPS;
|
||||
if (formula == TELEM_FORMULA_CELL)
|
||||
mask |= SENSOR_HAS_CELLS;
|
||||
if (formula == TELEM_FORMULA_CONSUMPTION)
|
||||
mask |= SENSOR_HAS_CONSUMPTION;
|
||||
if (formula <= TELEM_FORMULA_MULTIPLY)
|
||||
mask |= SENSOR_HAS_SOURCES_12;
|
||||
if (formula < TELEM_FORMULA_MULTIPLY)
|
||||
mask |= SENSOR_HAS_SOURCES_34;
|
||||
if (formula == TELEM_FORMULA_TOTALIZE)
|
||||
mask |= SENSOR_HAS_TOTALIZE;
|
||||
}
|
||||
else {
|
||||
if (unit < UNIT_FIRST_VIRTUAL)
|
||||
mask |= (SENSOR_ISCONFIGURABLE | SENSOR_HAS_RATIO | SENSOR_HAS_POSITIVE);
|
||||
}
|
||||
|
||||
if (mask & SENSOR_ISCONFIGURABLE && unit != UNIT_FAHRENHEIT)
|
||||
mask |= SENSOR_HAS_PRECISION;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
constexpr char FMT_LABEL[] { "<b>%1:</b> " };
|
||||
constexpr char FMT_VALUE[] { "%1 " };
|
||||
constexpr char FMT_LABEL_VALUE[] { "<b>%1:</b> %2 " };
|
||||
|
||||
QString SensorData::paramsToString(const ModelData * model) const
|
||||
{
|
||||
if (!isAvailable())
|
||||
return "";
|
||||
|
||||
QString str;
|
||||
int mask = getMask();
|
||||
|
||||
if (type == TELEM_TYPE_CALCULATED) {
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Formula")).arg(formulaToString()));
|
||||
}
|
||||
else {
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Id")).arg(idToString()));
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Instance")).arg(instance));
|
||||
}
|
||||
|
||||
if (mask & SENSOR_HAS_CELLS) {
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Sensor")).arg(sourceToString(model, source)));
|
||||
str.append(QString(FMT_VALUE).arg(cellIndexToString()));
|
||||
}
|
||||
|
||||
if (mask & SENSOR_HAS_SOURCES_12) {
|
||||
str.append(QString(FMT_LABEL).arg(tr("Sources")));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (i < 2 || mask & SENSOR_HAS_SOURCES_34) {
|
||||
str.append(QString(FMT_VALUE).arg(sourceToString(model, sources[i])));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & SENSOR_HAS_CONSUMPTION || mask & SENSOR_HAS_TOTALIZE)
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Sensor")).arg(sourceToString(model, amps)));
|
||||
|
||||
if (mask & SENSOR_HAS_GPS) {
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("GPS")).arg(sourceToString(model, gps)));
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Alt")).arg(sourceToString(model, alt)));
|
||||
}
|
||||
|
||||
if (mask & SENSOR_ISCONFIGURABLE)
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Unit")).arg(unitToString()));
|
||||
|
||||
if (mask & SENSOR_HAS_PRECISION)
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Precision")).arg(precToString()));
|
||||
|
||||
if (mask & SENSOR_HAS_RATIO) {
|
||||
if (unit != UNIT_RPMS) {
|
||||
int precsn = prec == 0 ? 1 : pow(10, prec);
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Ratio")).arg((float)ratio / 10));
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Offset")).arg(QString::number((float)offset / precsn, 'f', prec)));
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Auto Offset")).arg(DataHelpers::boolToString(autoOffset, DataHelpers::BOOL_FMT_YN)));
|
||||
}
|
||||
else {
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Blades")).arg(ratio)); // TODO refactor to dedicated RPMS field
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Multiplier")).arg(offset)); // TODO refactor to dedicated RPMS field
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & SENSOR_ISCONFIGURABLE)
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Filter")).arg(DataHelpers::boolToString(filter, DataHelpers::BOOL_FMT_YN)));
|
||||
|
||||
if (type == TELEM_TYPE_CALCULATED)
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Persist")).arg(DataHelpers::boolToString(persistent, DataHelpers::BOOL_FMT_YN)));
|
||||
|
||||
if (mask & SENSOR_HAS_POSITIVE)
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Positive")).arg(DataHelpers::boolToString(onlyPositive, DataHelpers::BOOL_FMT_YN)));
|
||||
|
||||
str.append(QString(FMT_LABEL_VALUE).arg(tr("Log")).arg(DataHelpers::boolToString(logs, DataHelpers::BOOL_FMT_YN)));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
FieldRange SensorData::getRatioRange() const
|
||||
{
|
||||
FieldRange result;
|
||||
|
||||
if (unit == SensorData::UNIT_RPMS) {
|
||||
result.decimals = 0;
|
||||
result.max = 30000;
|
||||
result.min = 1;
|
||||
result.step = 1;
|
||||
}
|
||||
else {
|
||||
result.decimals = 1;
|
||||
result.max = 30000;
|
||||
result.min = 0;
|
||||
result.step = 0.1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FieldRange SensorData::getOffsetRange() const
|
||||
{
|
||||
FieldRange result;
|
||||
|
||||
if (unit == SensorData::UNIT_RPMS) {
|
||||
result.decimals = 0;
|
||||
result.max = 30000;
|
||||
result.min = 1;
|
||||
result.step = 1;
|
||||
}
|
||||
else {
|
||||
result.decimals = prec;
|
||||
result.max = 30000.0f / powf(10.0f, prec);
|
||||
result.min = -result.max;
|
||||
result.step = pow(0.1, prec);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SensorData::formulaChanged()
|
||||
{
|
||||
switch (formula) {
|
||||
case TELEM_FORMULA_CELL:
|
||||
prec = 2;
|
||||
unit = UNIT_VOLTS;
|
||||
break;
|
||||
case TELEM_FORMULA_CONSUMPTION:
|
||||
prec = 0;
|
||||
unit = UNIT_MAH;
|
||||
break;
|
||||
case TELEM_FORMULA_DIST:
|
||||
prec = 0;
|
||||
unit = UNIT_METERS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SensorData::unitChanged()
|
||||
{
|
||||
if (unit == UNIT_FAHRENHEIT)
|
||||
prec = 0;
|
||||
}
|
||||
|
||||
// static
|
||||
QString SensorData::idToString(const int value)
|
||||
{
|
||||
return QString::number(value, 16).toUpper();
|
||||
}
|
||||
|
||||
// static
|
||||
QString SensorData::typeToString(const int value)
|
||||
{
|
||||
switch(value) {
|
||||
case TELEM_TYPE_CUSTOM:
|
||||
return tr("Custom");
|
||||
case TELEM_TYPE_CALCULATED:
|
||||
return tr("Calculated");
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
QString SensorData::formulaToString(const int value)
|
||||
{
|
||||
switch(value) {
|
||||
case TELEM_FORMULA_ADD:
|
||||
return tr("Add");
|
||||
case TELEM_FORMULA_AVERAGE:
|
||||
return tr("Average");
|
||||
case TELEM_FORMULA_MIN:
|
||||
return tr("Minimum");
|
||||
case TELEM_FORMULA_MAX:
|
||||
return tr("Maximum");
|
||||
case TELEM_FORMULA_MULTIPLY:
|
||||
return tr("Multiply");
|
||||
case TELEM_FORMULA_TOTALIZE:
|
||||
return tr("Totalize");
|
||||
case TELEM_FORMULA_CELL:
|
||||
return tr("Cell");
|
||||
case TELEM_FORMULA_CONSUMPTION:
|
||||
return tr("Consumption");
|
||||
case TELEM_FORMULA_DIST:
|
||||
return tr("Distance");
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
QString SensorData::cellIndexToString(const int value)
|
||||
{
|
||||
if (value == TELEM_CELL_INDEX_LOWEST)
|
||||
return tr("Lowest");
|
||||
if (value > TELEM_CELL_INDEX_LOWEST && value < TELEM_CELL_INDEX_HIGHEST)
|
||||
return tr("Cell %1").arg(value - TELEM_CELL_INDEX_LOWEST);
|
||||
if (value== TELEM_CELL_INDEX_HIGHEST)
|
||||
return tr("Highest");
|
||||
if (value == TELEM_CELL_INDEX_DELTA)
|
||||
return tr("Delta");
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
|
||||
// static
|
||||
QString SensorData::precToString(const int value)
|
||||
{
|
||||
return QString("0.%1").arg(QString(value, '0'));
|
||||
}
|
||||
|
||||
// static
|
||||
QString SensorData::sourceToString(const ModelData * model, const int index, const bool sign)
|
||||
{
|
||||
if (model) {
|
||||
const QString prfx = sign ? index < 0 ? "-" : "+" : "";
|
||||
|
||||
if (abs(index) > 0) {
|
||||
const SensorData &sd = model->sensorData[abs(index) - 1];
|
||||
if (sd.type == SensorData::TELEM_TYPE_CUSTOM)
|
||||
return QString("%1%2 (%3)").arg(prfx).arg(sd.label).arg(sd.getOrigin(model));
|
||||
else
|
||||
return QString("%1%2").arg(prfx).arg(sd.label);
|
||||
}
|
||||
else
|
||||
return CPN_STR_NONE_ITEM;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
// static
|
||||
QString SensorData::unitToString(const int value)
|
||||
{
|
||||
switch (value) {
|
||||
case UNIT_RAW:
|
||||
return tr("Raw (-)");
|
||||
case UNIT_VOLTS:
|
||||
return tr("V");
|
||||
case UNIT_AMPS:
|
||||
@@ -84,26 +397,118 @@ QString SensorData::unitString() const
|
||||
return tr("V");
|
||||
case UNIT_MILLILITERS_PER_MINUTE:
|
||||
return tr("ml/minute");
|
||||
case UNIT_HERZ:
|
||||
return tr("Hertz");
|
||||
case UNIT_MS:
|
||||
return tr("mS");
|
||||
case UNIT_US:
|
||||
return tr("uS");
|
||||
default:
|
||||
return "";
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
QString SensorData::nameToString(int index) const
|
||||
// static
|
||||
bool SensorData::isSourceAvailable(const ModelData * model, const int index)
|
||||
{
|
||||
return RadioData::getElementName(tr("TELE"), index + 1, label);
|
||||
Firmware * firmware = getCurrentFirmware();
|
||||
const int sensorcnt = firmware->getCapability(Sensors);
|
||||
const int i = abs(index);
|
||||
|
||||
if (model && sensorcnt > 0 && i <= sensorcnt) {
|
||||
if (i > 0)
|
||||
return model->sensorData[i - 1].isAvailable();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QString SensorData::getOrigin(const ModelData * model) const
|
||||
#define RSSI_ID 0xF101
|
||||
|
||||
// static
|
||||
bool SensorData::isRssiSensorAvailable(const ModelData * model, const int value)
|
||||
{
|
||||
if (type != TELEM_TYPE_CUSTOM || !id)
|
||||
return QString();
|
||||
|
||||
const ModuleData & module = model->moduleData[moduleIdx];
|
||||
if (module.isPxx2Module() && rxIdx <= 2 && module.access.receivers & (1 << rxIdx)) {
|
||||
return QString(module.access.receiverName[rxIdx]);
|
||||
}
|
||||
if (value == 0)
|
||||
return true;
|
||||
else {
|
||||
return QString();
|
||||
const SensorData &sensor = model->sensorData[abs(value) - 1];
|
||||
return (sensor.isAvailable() && sensor.id == RSSI_ID);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
QString SensorData::rssiSensorToString(const ModelData * model, const int value)
|
||||
{
|
||||
if (value == 0)
|
||||
return tr("(default)");
|
||||
else
|
||||
return sourceToString(model, value);
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * SensorData::typeItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName("sensordata.type");
|
||||
|
||||
for (int i = 0; i <= TELEM_TYPE_LAST; i++) {
|
||||
mdl->appendToItemList(typeToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * SensorData::formulaItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName("sensordata.formula");
|
||||
|
||||
for (int i = 0; i <= TELEM_FORMULA_LAST; i++) {
|
||||
mdl->appendToItemList(formulaToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * SensorData::cellIndexItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName("sensordata.cellindex");
|
||||
|
||||
for (int i = 0; i <= TELEM_CELL_INDEX_LAST; i++) {
|
||||
mdl->appendToItemList(cellIndexToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * SensorData::unitItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName("sensordata.unit");
|
||||
|
||||
for (int i = 0; i <= UNIT_MAX; i++) {
|
||||
QString str = unitToString(i);
|
||||
if (str != CPN_STR_UNKNOWN_ITEM)
|
||||
mdl->appendToItemList(str, i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// static
|
||||
PrecisionItemModel * SensorData::precisionItemModel()
|
||||
{
|
||||
PrecisionItemModel * mdl = new PrecisionItemModel(0, 2);
|
||||
mdl->setName("sensordata.precision");
|
||||
return mdl;
|
||||
}
|
||||
|
||||
@@ -18,16 +18,32 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef SENSORDATA_H
|
||||
#define SENSORDATA_H
|
||||
#pragma once
|
||||
|
||||
#include "datahelpers.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
constexpr int CPN_MAX_SENSORS = 60;
|
||||
constexpr int CPN_MAX_SENSORS { 60 };
|
||||
constexpr int SENSOR_LABEL_LEN { 4 };
|
||||
|
||||
constexpr int SENSOR_ISCONFIGURABLE { 1 << 1 };
|
||||
constexpr int SENSOR_HAS_GPS { 1 << 2 };
|
||||
constexpr int SENSOR_HAS_CELLS { 1 << 3 };
|
||||
constexpr int SENSOR_HAS_CONSUMPTION { 1 << 4 };
|
||||
constexpr int SENSOR_HAS_RATIO { 1 << 5 };
|
||||
constexpr int SENSOR_HAS_TOTALIZE { 1 << 6 };
|
||||
constexpr int SENSOR_HAS_SOURCES_12 { 1 << 7 };
|
||||
constexpr int SENSOR_HAS_SOURCES_34 { 1 << 8 };
|
||||
constexpr int SENSOR_HAS_POSITIVE { 1 << 9 };
|
||||
constexpr int SENSOR_HAS_PRECISION { 1 << 10 };
|
||||
|
||||
class ModelData;
|
||||
class AbstractStaticItemModel;
|
||||
class PrecisionItemModel;
|
||||
|
||||
class SensorData {
|
||||
|
||||
Q_DECLARE_TR_FUNCTIONS(SensorData)
|
||||
|
||||
public:
|
||||
@@ -35,7 +51,8 @@ class SensorData {
|
||||
enum
|
||||
{
|
||||
TELEM_TYPE_CUSTOM,
|
||||
TELEM_TYPE_CALCULATED
|
||||
TELEM_TYPE_CALCULATED,
|
||||
TELEM_TYPE_LAST = TELEM_TYPE_CALCULATED
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -62,6 +79,7 @@ class SensorData {
|
||||
TELEM_CELL_INDEX_6,
|
||||
TELEM_CELL_INDEX_HIGHEST,
|
||||
TELEM_CELL_INDEX_DELTA,
|
||||
TELEM_CELL_INDEX_LAST = TELEM_CELL_INDEX_DELTA
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -94,10 +112,10 @@ class SensorData {
|
||||
UNIT_MILLILITERS,
|
||||
UNIT_FLOZ,
|
||||
UNIT_MILLILITERS_PER_MINUTE,
|
||||
UNIT_MAX = UNIT_MILLILITERS_PER_MINUTE,
|
||||
UNIT_SPARE1,
|
||||
UNIT_SPARE2,
|
||||
UNIT_SPARE3,
|
||||
UNIT_HERZ,
|
||||
UNIT_MS,
|
||||
UNIT_US,
|
||||
UNIT_MAX = UNIT_US,
|
||||
UNIT_SPARE4,
|
||||
UNIT_SPARE5,
|
||||
UNIT_SPARE6,
|
||||
@@ -133,7 +151,7 @@ class SensorData {
|
||||
unsigned int moduleIdx;
|
||||
unsigned int persistentValue;
|
||||
unsigned int formula;
|
||||
char label[4+1];
|
||||
char label[SENSOR_LABEL_LEN + 1];
|
||||
unsigned int unit;
|
||||
unsigned int prec;
|
||||
bool autoOffset;
|
||||
@@ -162,10 +180,37 @@ class SensorData {
|
||||
|
||||
bool isAvailable() const { return strlen(label) > 0; }
|
||||
void updateUnit();
|
||||
QString unitString() const;
|
||||
QString nameToString(int index) const;
|
||||
QString getOrigin(const ModelData* model) const;
|
||||
void clear() { memset(this, 0, sizeof(SensorData)); }
|
||||
};
|
||||
bool isEmpty() const;
|
||||
QString idToString() const;
|
||||
QString typeToString() const;
|
||||
QString formulaToString() const;
|
||||
QString cellIndexToString() const;
|
||||
QString unitToString() const;
|
||||
QString precToString() const;
|
||||
int getMask() const;
|
||||
QString paramsToString(const ModelData * model) const;
|
||||
FieldRange getRatioRange() const;
|
||||
FieldRange getOffsetRange() const;
|
||||
void formulaChanged();
|
||||
void unitChanged();
|
||||
|
||||
#endif // SENSORDATA_H
|
||||
static QString sourceToString(const ModelData * model, const int index, const bool sign = false);
|
||||
static bool isSourceAvailable(const ModelData * model, const int index);
|
||||
static QString idToString(const int value);
|
||||
static QString typeToString(const int value);
|
||||
static QString formulaToString(const int value);
|
||||
static QString cellIndexToString(const int value);
|
||||
static QString unitToString(const int value);
|
||||
static QString precToString(const int value);
|
||||
static bool isRssiSensorAvailable(const ModelData * model, const int value);
|
||||
static QString rssiSensorToString(const ModelData * model, const int value);
|
||||
|
||||
static AbstractStaticItemModel * typeItemModel();
|
||||
static AbstractStaticItemModel * formulaItemModel();
|
||||
static AbstractStaticItemModel * cellIndexItemModel();
|
||||
static AbstractStaticItemModel * unitItemModel();
|
||||
static PrecisionItemModel * precisionItemModel();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "timerdata.h"
|
||||
#include "radiodataconversionstate.h"
|
||||
#include "compounditemmodels.h"
|
||||
|
||||
void TimerData::convert(RadioDataConversionState & cstate)
|
||||
{
|
||||
cstate.setComponent(tr("TMR"), 1);
|
||||
cstate.setSubComp(tr("Timer %1").arg(cstate.subCompIdx + 1));
|
||||
mode.convert(cstate);
|
||||
}
|
||||
|
||||
void TimerData::clear()
|
||||
{
|
||||
memset(reinterpret_cast<void *>(this), 0, sizeof(TimerData));
|
||||
mode = RawSwitch(SWITCH_TYPE_TIMER_MODE, 0);
|
||||
}
|
||||
|
||||
bool TimerData::isEmpty()
|
||||
{
|
||||
return (mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0) && name[0] == '\0' && minuteBeep == 0 && countdownBeep == COUNTDOWNBEEP_SILENT && val == 0 && persistent == 0 /*&& pvalue == 0*/);
|
||||
}
|
||||
|
||||
bool TimerData::isModeOff()
|
||||
{
|
||||
return mode == RawSwitch(SWITCH_TYPE_TIMER_MODE, 0);
|
||||
}
|
||||
|
||||
QString TimerData::nameToString(int index) const
|
||||
{
|
||||
return DataHelpers::getElementName(tr("TMR", "as in Timer"), index + 1, name);
|
||||
}
|
||||
|
||||
QString TimerData::countdownBeepToString() const
|
||||
{
|
||||
return countdownBeepToString(countdownBeep);
|
||||
}
|
||||
|
||||
QString TimerData::countdownStartToString() const
|
||||
{
|
||||
if (countdownBeep == COUNTDOWNBEEP_SILENT)
|
||||
return "";
|
||||
else
|
||||
return countdownStartToString(countdownStart);
|
||||
}
|
||||
|
||||
QString TimerData::persistentToString(const bool verbose) const
|
||||
{
|
||||
return persistentToString(persistent, verbose);
|
||||
}
|
||||
|
||||
QString TimerData::pvalueToString() const
|
||||
{
|
||||
return pvalueToString(pvalue);
|
||||
}
|
||||
|
||||
QString TimerData::valToString() const
|
||||
{
|
||||
return valToString(val);
|
||||
}
|
||||
|
||||
void TimerData::countdownBeepChanged()
|
||||
{
|
||||
if (countdownBeep == COUNTDOWNBEEP_SILENT)
|
||||
countdownStart = 0;
|
||||
}
|
||||
|
||||
// static
|
||||
QString TimerData::countdownBeepToString(const int value)
|
||||
{
|
||||
switch(value) {
|
||||
case COUNTDOWNBEEP_SILENT:
|
||||
return tr("Silent");
|
||||
case COUNTDOWNBEEP_BEEPS:
|
||||
return tr("Beeps");
|
||||
case COUNTDOWNBEEP_VOICE:
|
||||
return tr("Voice");
|
||||
case COUNTDOWNBEEP_HAPTIC:
|
||||
return tr("Haptic");
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
QString TimerData::countdownStartToString(const int value)
|
||||
{
|
||||
switch(value) {
|
||||
case COUNTDOWNSTART_5:
|
||||
return tr("5s");
|
||||
case COUNTDOWNSTART_10:
|
||||
return tr("10s");
|
||||
case COUNTDOWNSTART_20:
|
||||
return tr("20s");
|
||||
case COUNTDOWNSTART_30:
|
||||
return tr("30s");
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
QString TimerData::persistentToString(const int value, const bool verbose)
|
||||
{
|
||||
switch(value) {
|
||||
case PERSISTENT_NOT:
|
||||
return verbose ? tr("Not persistent") : tr("NOT");
|
||||
case PERSISTENT_FLIGHT:
|
||||
return verbose ? tr("Persistent (flight)") : tr("Flight");
|
||||
case PERSISTENT_MANUALRESET:
|
||||
return verbose ? tr("Persistent (manual reset)") : tr("Manual reset");
|
||||
default:
|
||||
return CPN_STR_UNKNOWN_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
QString TimerData::pvalueToString(const int value)
|
||||
{
|
||||
return DataHelpers::timeToString(value, TIMESTR_MASK_HRSMINS | TIMESTR_MASK_ZEROHRS);
|
||||
}
|
||||
|
||||
// static
|
||||
QString TimerData::valToString(const int value)
|
||||
{
|
||||
return DataHelpers::timeToString(value, TIMESTR_MASK_HRSMINS | TIMESTR_MASK_ZEROHRS);
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * TimerData::countdownBeepItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName(AIM_TIMER_COUNTDOWNBEEP);
|
||||
|
||||
for (int i = 0; i < COUNTDOWNBEEP_COUNT; i++) {
|
||||
mdl->appendToItemList(countdownBeepToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * TimerData::countdownStartItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName(AIM_TIMER_COUNTDOWNSTART);
|
||||
|
||||
for (int i = COUNTDOWNSTART_LAST; i >= COUNTDOWNSTART_FIRST; i--) {
|
||||
mdl->appendToItemList(countdownStartToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
|
||||
// static
|
||||
AbstractStaticItemModel * TimerData::persistentItemModel()
|
||||
{
|
||||
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
|
||||
mdl->setName(AIM_TIMER_PERSISTENT);
|
||||
|
||||
for (int i = 0; i < PERSISTENT_COUNT; i++) {
|
||||
mdl->appendToItemList(persistentToString(i), i);
|
||||
}
|
||||
|
||||
mdl->loadItemList();
|
||||
return mdl;
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "rawswitch.h"
|
||||
#include "datahelpers.h"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class RadioDataConversionState;
|
||||
class AbstractStaticItemModel;
|
||||
|
||||
constexpr char AIM_TIMER_COUNTDOWNBEEP[] {"timerdata.countdownBeep"};
|
||||
constexpr char AIM_TIMER_COUNTDOWNSTART[] {"timerdata.countdownStart"};
|
||||
constexpr char AIM_TIMER_PERSISTENT[] {"timerdata.persistent"};
|
||||
|
||||
constexpr int TIMER_NAME_LEN {8};
|
||||
|
||||
class TimerData {
|
||||
Q_DECLARE_TR_FUNCTIONS(TimerData)
|
||||
|
||||
public:
|
||||
enum CountDownBeepType {
|
||||
COUNTDOWNBEEP_SILENT,
|
||||
COUNTDOWNBEEP_BEEPS,
|
||||
COUNTDOWNBEEP_VOICE,
|
||||
COUNTDOWNBEEP_HAPTIC,
|
||||
COUNTDOWNBEEP_COUNT
|
||||
};
|
||||
|
||||
enum CountDownStart {
|
||||
COUNTDOWNSTART_30 = -2,
|
||||
COUNTDOWNSTART_FIRST = COUNTDOWNSTART_30,
|
||||
COUNTDOWNSTART_20,
|
||||
COUNTDOWNSTART_10,
|
||||
COUNTDOWNSTART_5,
|
||||
COUNTDOWNSTART_LAST = COUNTDOWNSTART_5
|
||||
};
|
||||
|
||||
enum PersistentType {
|
||||
PERSISTENT_NOT,
|
||||
PERSISTENT_FLIGHT,
|
||||
PERSISTENT_MANUALRESET,
|
||||
PERSISTENT_COUNT
|
||||
};
|
||||
|
||||
TimerData() { clear(); }
|
||||
|
||||
RawSwitch mode;
|
||||
char name[TIMER_NAME_LEN + 1];
|
||||
bool minuteBeep;
|
||||
unsigned int countdownBeep;
|
||||
unsigned int val;
|
||||
unsigned int persistent;
|
||||
int countdownStart;
|
||||
unsigned int direction;
|
||||
int pvalue;
|
||||
|
||||
void convert(RadioDataConversionState & cstate);
|
||||
void clear();
|
||||
bool isEmpty();
|
||||
bool isModeOff();
|
||||
QString nameToString(int index) const;
|
||||
QString countdownBeepToString() const;
|
||||
QString countdownStartToString() const;
|
||||
QString persistentToString(const bool verbose = true) const;
|
||||
QString pvalueToString() const;
|
||||
QString valToString() const;
|
||||
void countdownBeepChanged();
|
||||
|
||||
static QString countdownBeepToString(const int value);
|
||||
static QString countdownStartToString(const int value);
|
||||
static QString persistentToString(const int value, const bool verbose = true);
|
||||
static QString pvalueToString(const int value);
|
||||
static QString valToString(const int value);
|
||||
static AbstractStaticItemModel * countdownBeepItemModel();
|
||||
static AbstractStaticItemModel * countdownStartItemModel();
|
||||
static AbstractStaticItemModel * persistentItemModel();
|
||||
|
||||
};
|
||||
@@ -275,11 +275,12 @@ void FlashFirmwareDialog::startFlash(const QString &filename)
|
||||
ProgressDialog progressDialog(this, tr("Write Firmware to Radio"), CompanionIcon("write_flash.png"));
|
||||
|
||||
// check hardware compatibility if requested
|
||||
bool checkPassed = true;
|
||||
if (g.checkHardwareCompatibility()) {
|
||||
QString tempFirmware = generateProcessUniqueTempFileName("flash-check.bin");
|
||||
if (!readFirmware(tempFirmware, progressDialog.progress())) {
|
||||
QMessageBox::warning(this, tr("Firmware check failed"), tr("Could not check firmware from radio"));
|
||||
return;
|
||||
checkPassed = false;
|
||||
}
|
||||
FirmwareInterface previousFirmware(tempFirmware);
|
||||
qunlink(tempFirmware);
|
||||
@@ -291,41 +292,44 @@ void FlashFirmwareDialog::startFlash(const QString &filename)
|
||||
qDebug() << "startFlash: removing temporary file" << filename;
|
||||
qunlink(filename);
|
||||
}
|
||||
return;
|
||||
checkPassed = false;
|
||||
}
|
||||
}
|
||||
|
||||
// backup if requested
|
||||
bool result = true;
|
||||
QString backupFilename;
|
||||
QString backupPath;
|
||||
if (backup) {
|
||||
backupPath = g.profile[g.id()].pBackupDir();
|
||||
if (backupPath.isEmpty()) {
|
||||
backupPath=g.backupDir();
|
||||
if (checkPassed) {
|
||||
// backup if requested
|
||||
bool result = true;
|
||||
QString backupFilename;
|
||||
QString backupPath;
|
||||
if (backup) {
|
||||
backupPath = g.profile[g.id()].pBackupDir();
|
||||
if (backupPath.isEmpty()) {
|
||||
backupPath=g.backupDir();
|
||||
}
|
||||
backupFilename = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin";
|
||||
result = readEeprom(backupFilename, progressDialog.progress());
|
||||
sleep(2);
|
||||
}
|
||||
backupFilename = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin";
|
||||
result = readEeprom(backupFilename, progressDialog.progress());
|
||||
sleep(2);
|
||||
|
||||
// flash
|
||||
result = (result && writeFirmware(filename, progressDialog.progress()));
|
||||
|
||||
// restore if backup requested
|
||||
if (backup && result) {
|
||||
sleep(2);
|
||||
QString restoreFilename = generateProcessUniqueTempFileName("restore.bin");
|
||||
if (!convertEEprom(backupFilename, restoreFilename, filename)) {
|
||||
QMessageBox::warning(this, tr("Conversion failed"), tr("Cannot convert Models and Settings for use with this firmware, original data will be used"));
|
||||
restoreFilename = backupFilename;
|
||||
}
|
||||
if (!writeEeprom(restoreFilename, progressDialog.progress())) {
|
||||
QMessageBox::warning(this, tr("Restore failed"), tr("Could not restore Models and Settings to Radio. The models and settings data file can be found at: %1").arg(backupFilename));
|
||||
}
|
||||
}
|
||||
|
||||
progressDialog.progress()->setInfo(tr("Flashing done"));
|
||||
}
|
||||
|
||||
// flash
|
||||
result = (result && writeFirmware(filename, progressDialog.progress()));
|
||||
|
||||
// restore if backup requested
|
||||
if (backup && result) {
|
||||
sleep(2);
|
||||
QString restoreFilename = generateProcessUniqueTempFileName("restore.bin");
|
||||
if (!convertEEprom(backupFilename, restoreFilename, filename)) {
|
||||
QMessageBox::warning(this, tr("Conversion failed"), tr("Cannot convert Models and Settings for use with this firmware, original data will be used"));
|
||||
restoreFilename = backupFilename;
|
||||
}
|
||||
if (!writeEeprom(restoreFilename, progressDialog.progress())) {
|
||||
QMessageBox::warning(this, tr("Restore failed"), tr("Could not restore Models and Settings to Radio. The models and settings data file can be found at: %1").arg(backupFilename));
|
||||
}
|
||||
}
|
||||
|
||||
progressDialog.progress()->setInfo(tr("Flashing done"));
|
||||
|
||||
progressDialog.exec();
|
||||
|
||||
if (isTempFileName(filename)) {
|
||||
|
||||
@@ -28,4 +28,4 @@ qt5_wrap_ui(generaledit_SRCS ${generaledit_UIS})
|
||||
qt5_wrap_cpp(generaledit_SRCS ${generaledit_HDRS})
|
||||
|
||||
add_library(generaledit ${generaledit_SRCS})
|
||||
target_link_libraries(generaledit PRIVATE ${CPN_COMMON_LIB} Qt5::Multimedia)
|
||||
target_link_libraries(generaledit PRIVATE datamodels ${CPN_COMMON_LIB} Qt5::Multimedia)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "hardware.h"
|
||||
#include "../modeledit/customfunctions.h"
|
||||
#include "verticalscrollarea.h"
|
||||
#include "compounditemmodels.h"
|
||||
|
||||
GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * firmware) :
|
||||
QDialog(parent),
|
||||
@@ -55,8 +56,14 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir
|
||||
}
|
||||
}
|
||||
|
||||
sharedItemModels = new CompoundItemModelFactory(&generalSettings, nullptr);
|
||||
sharedItemModels->addItemModel(AbstractItemModel::IMID_RawSource);
|
||||
sharedItemModels->addItemModel(AbstractItemModel::IMID_RawSwitch);
|
||||
sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncAction);
|
||||
sharedItemModels->addItemModel(AbstractItemModel::IMID_CustomFuncResetParam);
|
||||
|
||||
addTab(new GeneralSetupPanel(this, generalSettings, firmware), tr("Setup"));
|
||||
addTab(new CustomFunctionsPanel(this, NULL, generalSettings, firmware), tr("Global Functions"));
|
||||
addTab(new CustomFunctionsPanel(this, nullptr, generalSettings, firmware, sharedItemModels), tr("Global Functions"));
|
||||
addTab(new TrainerPanel(this, generalSettings, firmware), tr("Trainer"));
|
||||
addTab(new HardwarePanel(this, generalSettings, firmware), tr("Hardware"));
|
||||
addTab(new CalibrationPanel(this, generalSettings, firmware), tr("Calibration"));
|
||||
@@ -67,6 +74,7 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir
|
||||
GeneralEdit::~GeneralEdit()
|
||||
{
|
||||
delete ui;
|
||||
delete sharedItemModels;
|
||||
}
|
||||
|
||||
void GeneralEdit::closeEvent(QCloseEvent *event)
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "eeprominterface.h"
|
||||
#include "genericpanel.h"
|
||||
|
||||
class CompoundItemModelFactory;
|
||||
|
||||
namespace Ui {
|
||||
class GeneralEdit;
|
||||
}
|
||||
@@ -56,7 +58,7 @@ class GeneralEdit : public QDialog
|
||||
void getGeneralSwitchDefPos(int i, bool val);
|
||||
void setSwitchDefPos();
|
||||
void updateVarioPitchRange();
|
||||
|
||||
|
||||
signals:
|
||||
void modified();
|
||||
|
||||
@@ -71,7 +73,7 @@ class GeneralEdit : public QDialog
|
||||
QVector<GenericPanel *> panels;
|
||||
void addTab(GenericPanel *panel, QString text);
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
CompoundItemModelFactory *sharedItemModels;
|
||||
};
|
||||
|
||||
#endif // _GENERALEDIT_H_
|
||||
|
||||
@@ -158,7 +158,7 @@ ui(new Ui::GeneralSetup)
|
||||
ui->usbModeLabel->hide();
|
||||
ui->usbModeCB->hide();
|
||||
}
|
||||
|
||||
|
||||
if (firmware->getCapability(HasSwitchableJack)) {
|
||||
ui->jackModeCB->setCurrentIndex(generalSettings.jackMode);
|
||||
}
|
||||
@@ -266,7 +266,7 @@ ui(new Ui::GeneralSetup)
|
||||
ui->pwrOnDelayLabel->hide();
|
||||
ui->pwrOnDelay->hide();
|
||||
}
|
||||
|
||||
|
||||
setValues();
|
||||
|
||||
lock = false;
|
||||
@@ -505,13 +505,13 @@ void GeneralSetupPanel::on_splashScreenDuration_currentIndexChanged(int index)
|
||||
emit modified();
|
||||
}
|
||||
|
||||
void GeneralSetupPanel::on_pwrOnDelay_valueChanged()
|
||||
void GeneralSetupPanel::on_pwrOnDelay_valueChanged(int)
|
||||
{
|
||||
generalSettings.pwrOnSpeed = 2 - ui->pwrOnDelay->value();
|
||||
emit modified();
|
||||
}
|
||||
|
||||
void GeneralSetupPanel::on_pwrOffDelay_valueChanged()
|
||||
void GeneralSetupPanel::on_pwrOffDelay_valueChanged(int)
|
||||
{
|
||||
generalSettings.pwrOffSpeed = 2 - ui->pwrOffDelay->value();
|
||||
emit modified();
|
||||
@@ -650,7 +650,7 @@ void GeneralSetupPanel::on_backlightautoSB_editingFinished()
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralSetupPanel::on_switchesDelay_valueChanged()
|
||||
void GeneralSetupPanel::on_switchesDelay_valueChanged(int)
|
||||
{
|
||||
generalSettings.switchesDelay = (ui->switchesDelay->value() / 10) - 15;
|
||||
emit modified();
|
||||
|
||||
@@ -65,7 +65,7 @@ class GeneralSetupPanel : public GeneralPanel
|
||||
void on_mavbaud_CB_currentIndexChanged(int index);
|
||||
void on_voiceLang_CB_currentIndexChanged(int index);
|
||||
void stickReverseEdited();
|
||||
void on_switchesDelay_valueChanged();
|
||||
void on_switchesDelay_valueChanged(int);
|
||||
void on_blAlarm_ChkB_stateChanged();
|
||||
void unlockSwitchEdited();
|
||||
void on_beepVolume_SL_valueChanged();
|
||||
@@ -89,8 +89,8 @@ class GeneralSetupPanel : public GeneralPanel
|
||||
void on_contrastSB_editingFinished();
|
||||
void on_registrationId_editingFinished();
|
||||
|
||||
void on_pwrOnDelay_valueChanged();
|
||||
void on_pwrOffDelay_valueChanged();
|
||||
void on_pwrOnDelay_valueChanged(int);
|
||||
void on_pwrOffDelay_valueChanged(int);
|
||||
|
||||
private:
|
||||
Ui::GeneralSetup *ui;
|
||||
|
||||
@@ -1527,7 +1527,7 @@ Mode 4:
|
||||
<string>Battery warning voltage.
|
||||
This is the threashhold where the battery warning sounds.
|
||||
|
||||
Acceptable values are 5v..10v</string>
|
||||
Acceptable values are 3v..12v</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string notr="true"/>
|
||||
@@ -1539,7 +1539,7 @@ Acceptable values are 5v..10v</string>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>4.000000000000000</double>
|
||||
<double>3.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>12.000000000000000</double>
|
||||
@@ -1679,7 +1679,7 @@ Acceptable values are 5v..10v</string>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>4.000000000000000</double>
|
||||
<double>3.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>16.000000000000000</double>
|
||||
@@ -1708,7 +1708,7 @@ Acceptable values are 5v..10v</string>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>4.000000000000000</double>
|
||||
<double>3.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>16.000000000000000</double>
|
||||
|
||||
@@ -47,7 +47,15 @@ void HardwarePanel::setupSwitchType(int index, QLabel * label, AutoLineEdit * na
|
||||
label->setText("SJ");
|
||||
}
|
||||
}
|
||||
if (IS_JUMPER_T12(board)) {
|
||||
else if (IS_RADIOMASTER_TX12(board)) {
|
||||
if (index == 6) {
|
||||
label->setText("SI");
|
||||
}
|
||||
else if (index == 7) {
|
||||
label->setText("SJ");
|
||||
}
|
||||
}
|
||||
else if (IS_FAMILY_T12(board)) {
|
||||
if (index == 4) {
|
||||
label->setText("SG");
|
||||
}
|
||||
@@ -101,6 +109,15 @@ void HardwarePanel::setupSliderType(int index, QLabel *label, AutoLineEdit *name
|
||||
}
|
||||
}
|
||||
|
||||
bool HardwarePanel::isSwitch3Pos(int idx)
|
||||
{
|
||||
Board::Type board = firmware->getBoard();
|
||||
Board::SwitchInfo switchInfo = Boards::getSwitchInfo(board, idx);
|
||||
|
||||
switchInfo.config = Board::SwitchType(generalSettings.switchConfig[idx]);
|
||||
return switchInfo.config == Board::SWITCH_3POS;
|
||||
};
|
||||
|
||||
HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings, Firmware * firmware):
|
||||
GeneralPanel(parent, generalSettings, firmware),
|
||||
ui(new Ui::Hardware)
|
||||
@@ -127,6 +144,14 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
|
||||
ui->potsTypeSeparator_1->hide();
|
||||
ui->potsTypeSeparator_2->hide();
|
||||
}
|
||||
|
||||
if (firmware->getCapability(HasSportConnector)) {
|
||||
ui->sportPower->setChecked(generalSettings.sportPower);
|
||||
}
|
||||
else {
|
||||
ui->sportPower->hide();
|
||||
ui->sportPowerLabel->hide();
|
||||
}
|
||||
|
||||
setupPotType(0, ui->pot1Label, ui->pot1Name, ui->pot1Type);
|
||||
setupPotType(1, ui->pot2Label, ui->pot2Name, ui->pot2Type);
|
||||
@@ -139,17 +164,17 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
|
||||
setupSliderType(2, ui->ls2Label, ui->ls2Name, ui->ls2Type);
|
||||
setupSliderType(3, ui->rs2Label, ui->rs2Name, ui->rs2Type);
|
||||
|
||||
setupSwitchType(0, ui->saLabel, ui->saName, ui->saType);
|
||||
setupSwitchType(1, ui->sbLabel, ui->sbName, ui->sbType);
|
||||
setupSwitchType(2, ui->scLabel, ui->scName, ui->scType);
|
||||
setupSwitchType(3, ui->sdLabel, ui->sdName, ui->sdType);
|
||||
setupSwitchType(4, ui->seLabel, ui->seName, ui->seType);
|
||||
setupSwitchType(5, ui->sfLabel, ui->sfName, ui->sfType, false); //switch does not support 3POS
|
||||
setupSwitchType(6, ui->sgLabel, ui->sgName, ui->sgType);
|
||||
setupSwitchType(7, ui->shLabel, ui->shName, ui->shType, false); //switch does not support 3POS
|
||||
setupSwitchType(8, ui->siLabel, ui->siName, ui->siType);
|
||||
setupSwitchType(9, ui->sjLabel, ui->sjName, ui->sjType);
|
||||
setupSwitchType(10, ui->skLabel, ui->skName, ui->skType);
|
||||
setupSwitchType(0, ui->saLabel, ui->saName, ui->saType, isSwitch3Pos(0));
|
||||
setupSwitchType(1, ui->sbLabel, ui->sbName, ui->sbType, isSwitch3Pos(1));
|
||||
setupSwitchType(2, ui->scLabel, ui->scName, ui->scType, isSwitch3Pos(2));
|
||||
setupSwitchType(3, ui->sdLabel, ui->sdName, ui->sdType, isSwitch3Pos(3));
|
||||
setupSwitchType(4, ui->seLabel, ui->seName, ui->seType, isSwitch3Pos(4));
|
||||
setupSwitchType(5, ui->sfLabel, ui->sfName, ui->sfType, isSwitch3Pos(5));
|
||||
setupSwitchType(6, ui->sgLabel, ui->sgName, ui->sgType, isSwitch3Pos(6));
|
||||
setupSwitchType(7, ui->shLabel, ui->shName, ui->shType, isSwitch3Pos(7));
|
||||
setupSwitchType(8, ui->siLabel, ui->siName, ui->siType, isSwitch3Pos(8));
|
||||
setupSwitchType(9, ui->sjLabel, ui->sjName, ui->sjType, isSwitch3Pos(9));
|
||||
setupSwitchType(10, ui->skLabel, ui->skName, ui->skType); // Here starts X9E, only 3 switches
|
||||
setupSwitchType(11, ui->slLabel, ui->slName, ui->slType);
|
||||
setupSwitchType(12, ui->smLabel, ui->smName, ui->smType);
|
||||
setupSwitchType(13, ui->snLabel, ui->snName, ui->snType);
|
||||
@@ -232,6 +257,11 @@ void HardwarePanel::on_filterEnable_stateChanged()
|
||||
generalSettings.jitterFilter = !ui->filterEnable->isChecked();
|
||||
}
|
||||
|
||||
void HardwarePanel::on_sportPower_stateChanged()
|
||||
{
|
||||
generalSettings.sportPower = ui->sportPower->isChecked();
|
||||
}
|
||||
|
||||
void HardwarePanel::on_rtcCheckDisable_stateChanged()
|
||||
{
|
||||
generalSettings.rtcCheckDisable = !ui->rtcCheckDisable->isChecked();
|
||||
|
||||
@@ -50,6 +50,7 @@ class HardwarePanel : public GeneralPanel
|
||||
void on_txVoltageCalibration_editingFinished();
|
||||
void on_filterEnable_stateChanged();
|
||||
void on_rtcCheckDisable_stateChanged();
|
||||
void on_sportPower_stateChanged();
|
||||
|
||||
void on_serialPortMode_currentIndexChanged(int index);
|
||||
|
||||
@@ -62,6 +63,7 @@ class HardwarePanel : public GeneralPanel
|
||||
Ui::Hardware *ui;
|
||||
|
||||
void setValues();
|
||||
bool isSwitch3Pos(int idx);
|
||||
};
|
||||
|
||||
#endif // _HARDWARE_H_
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "simulatorinterface.h"
|
||||
#include "simulatormainwindow.h"
|
||||
#include "storage/sdcard.h"
|
||||
#include "filtereditemmodels.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QLabel>
|
||||
@@ -117,7 +118,8 @@ void CompanionIcon::addImage(const QString & baseimage, Mode mode, State state)
|
||||
* GVarGroup
|
||||
*/
|
||||
|
||||
GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step, bool allowGvars):
|
||||
GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model,
|
||||
const int deflt, const int mini, const int maxi, const double step, FilteredItemModel * gvarModel):
|
||||
QObject(),
|
||||
weightGV(weightGV),
|
||||
weightSB(weightSB),
|
||||
@@ -131,8 +133,8 @@ GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBo
|
||||
step(step),
|
||||
lock(true)
|
||||
{
|
||||
if (allowGvars && getCurrentFirmware()->getCapability(Gvars)) {
|
||||
Helpers::populateGVCB(*weightCB, weight, model);
|
||||
if (gvarModel && gvarModel->rowCount() > 0) {
|
||||
weightCB->setModel(gvarModel);
|
||||
connect(weightGV, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int)));
|
||||
connect(weightCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged()));
|
||||
}
|
||||
@@ -152,12 +154,19 @@ GVarGroup::GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBo
|
||||
|
||||
void GVarGroup::gvarCBChanged(int state)
|
||||
{
|
||||
weightCB->setVisible(state);
|
||||
if (weightSB)
|
||||
if (!lock) {
|
||||
weightCB->setVisible(state);
|
||||
if (weightGV->isChecked()) {
|
||||
// set CB to +GV1
|
||||
int cnt = getCurrentFirmware()->getCapability(Gvars);
|
||||
if (weightCB->count() > cnt)
|
||||
weightCB->setCurrentIndex(cnt);
|
||||
else
|
||||
weightCB->setCurrentIndex(0);
|
||||
}
|
||||
weightSB->setVisible(!state);
|
||||
else
|
||||
weightSB->setVisible(!state);
|
||||
valuesChanged();
|
||||
valuesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void GVarGroup::valuesChanged()
|
||||
@@ -168,7 +177,7 @@ void GVarGroup::valuesChanged()
|
||||
else if (sb)
|
||||
weight = sb->value();
|
||||
else
|
||||
weight = round(dsb->value()/step);
|
||||
weight = round(dsb->value() / step);
|
||||
|
||||
emit valueChanged();
|
||||
}
|
||||
@@ -180,7 +189,7 @@ void GVarGroup::setWeight(int val)
|
||||
|
||||
int tval;
|
||||
|
||||
if (val>maxi || val<mini) {
|
||||
if (val > maxi || val < mini) {
|
||||
tval = deflt;
|
||||
weightGV->setChecked(true);
|
||||
weightSB->hide();
|
||||
@@ -210,215 +219,10 @@ void GVarGroup::setWeight(int val)
|
||||
lock = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* CurveGroup
|
||||
*/
|
||||
|
||||
CurveGroup::CurveGroup(QComboBox * curveTypeCB, QCheckBox * curveGVarCB, QComboBox * curveValueCB, QSpinBox * curveValueSB, CurveReference & curve, const ModelData & model, unsigned int flags):
|
||||
QObject(),
|
||||
curveTypeCB(curveTypeCB),
|
||||
curveGVarCB(curveGVarCB),
|
||||
curveValueCB(curveValueCB),
|
||||
curveValueSB(curveValueSB),
|
||||
curve(curve),
|
||||
model(model),
|
||||
flags(flags),
|
||||
lock(false),
|
||||
lastType(-1)
|
||||
{
|
||||
if (!(flags & HIDE_DIFF)) curveTypeCB->addItem(tr("Diff"), 0);
|
||||
if (!(flags & HIDE_EXPO)) curveTypeCB->addItem(tr("Expo"), 1);
|
||||
curveTypeCB->addItem(tr("Func"), 2);
|
||||
curveTypeCB->addItem(tr("Curve"), 3);
|
||||
|
||||
curveValueCB->setMaxVisibleItems(10);
|
||||
|
||||
connect(curveTypeCB, SIGNAL(currentIndexChanged(int)), this, SLOT(typeChanged(int)));
|
||||
connect(curveGVarCB, SIGNAL(stateChanged(int)), this, SLOT(gvarCBChanged(int)));
|
||||
connect(curveValueCB, SIGNAL(currentIndexChanged(int)), this, SLOT(valuesChanged()));
|
||||
connect(curveValueSB, SIGNAL(editingFinished()), this, SLOT(valuesChanged()));
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void CurveGroup::update()
|
||||
{
|
||||
lock = true;
|
||||
|
||||
int found = curveTypeCB->findData(curve.type);
|
||||
if (found < 0) found = 0;
|
||||
curveTypeCB->setCurrentIndex(found);
|
||||
|
||||
if (curve.type == CurveReference::CURVE_REF_DIFF || curve.type == CurveReference::CURVE_REF_EXPO) {
|
||||
curveGVarCB->setVisible(getCurrentFirmware()->getCapability(Gvars));
|
||||
if (curve.value > 100 || curve.value < -100) {
|
||||
curveGVarCB->setChecked(true);
|
||||
if (lastType != CurveReference::CURVE_REF_DIFF && lastType != CurveReference::CURVE_REF_EXPO) {
|
||||
lastType = curve.type;
|
||||
Helpers::populateGVCB(*curveValueCB, curve.value, model);
|
||||
}
|
||||
curveValueCB->show();
|
||||
curveValueSB->hide();
|
||||
}
|
||||
else {
|
||||
curveGVarCB->setChecked(false);
|
||||
curveValueSB->setMinimum(-100);
|
||||
curveValueSB->setMaximum(100);
|
||||
curveValueSB->setValue(curve.value);
|
||||
curveValueSB->show();
|
||||
curveValueCB->hide();
|
||||
}
|
||||
}
|
||||
else {
|
||||
curveGVarCB->hide();
|
||||
curveValueSB->hide();
|
||||
curveValueCB->show();
|
||||
switch (curve.type) {
|
||||
case CurveReference::CURVE_REF_FUNC:
|
||||
if (lastType != curve.type) {
|
||||
lastType = curve.type;
|
||||
curveValueCB->clear();
|
||||
for (int i=0; i<=6/*TODO constant*/; i++) {
|
||||
curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_FUNC, i).toString(&model, false));
|
||||
}
|
||||
}
|
||||
curveValueCB->setCurrentIndex(curve.value);
|
||||
break;
|
||||
case CurveReference::CURVE_REF_CUSTOM:
|
||||
{
|
||||
int numcurves = getCurrentFirmware()->getCapability(NumCurves);
|
||||
if (lastType != curve.type) {
|
||||
lastType = curve.type;
|
||||
curveValueCB->clear();
|
||||
for (int i= ((flags & HIDE_NEGATIVE_CURVES) ? 0 : -numcurves); i<=numcurves; i++) {
|
||||
curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, i).toString(&model, false), i);
|
||||
if (i == curve.value) {
|
||||
curveValueCB->setCurrentIndex(curveValueCB->count() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lock = false;
|
||||
}
|
||||
|
||||
void CurveGroup::gvarCBChanged(int state)
|
||||
{
|
||||
if (!lock) {
|
||||
if (state) {
|
||||
curve.value = 10000+1; // TODO constant in EEpromInterface ...
|
||||
lastType = -1; // quickfix for issue #3518: force refresh of curveValueCB at next update() to set current index to GV1
|
||||
}
|
||||
else {
|
||||
curve.value = 0; // TODO could be better
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void CurveGroup::typeChanged(int value)
|
||||
{
|
||||
if (!lock) {
|
||||
int type = curveTypeCB->itemData(curveTypeCB->currentIndex()).toInt();
|
||||
switch (type) {
|
||||
case 0:
|
||||
curve = CurveReference(CurveReference::CURVE_REF_DIFF, 0);
|
||||
break;
|
||||
case 1:
|
||||
curve = CurveReference(CurveReference::CURVE_REF_EXPO, 0);
|
||||
break;
|
||||
case 2:
|
||||
curve = CurveReference(CurveReference::CURVE_REF_FUNC, 0);
|
||||
break;
|
||||
case 3:
|
||||
curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void CurveGroup::valuesChanged()
|
||||
{
|
||||
if (!lock) {
|
||||
switch (curveTypeCB->itemData(curveTypeCB->currentIndex()).toInt()) {
|
||||
case 0:
|
||||
case 1:
|
||||
{
|
||||
int value;
|
||||
if (curveGVarCB->isChecked())
|
||||
value = curveValueCB->itemData(curveValueCB->currentIndex()).toInt();
|
||||
else
|
||||
value = curveValueSB->value();
|
||||
curve = CurveReference(curveTypeCB->itemData(curveTypeCB->currentIndex()).toInt() == 0 ? CurveReference::CURVE_REF_DIFF : CurveReference::CURVE_REF_EXPO, value);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
curve = CurveReference(CurveReference::CURVE_REF_FUNC, curveValueCB->currentIndex());
|
||||
break;
|
||||
case 3:
|
||||
curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, curveValueCB->itemData(curveValueCB->currentIndex()).toInt());
|
||||
break;
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Helpers namespace functions
|
||||
*/
|
||||
|
||||
void Helpers::populateGVCB(QComboBox & b, int value, const ModelData & model)
|
||||
{
|
||||
int count = getCurrentFirmware()->getCapability(Gvars);
|
||||
|
||||
b.clear();
|
||||
|
||||
for (int i=-count; i<=-1; i++) {
|
||||
int16_t gval = (int16_t)(-10000+i);
|
||||
b.addItem("-" + RawSource(SOURCE_TYPE_GVAR, abs(i)-1).toString(&model), gval);
|
||||
}
|
||||
|
||||
for (int i=1; i<=count; i++) {
|
||||
int16_t gval = (int16_t)(10000+i);
|
||||
b.addItem(RawSource(SOURCE_TYPE_GVAR, i-1).toString(&model), gval);
|
||||
}
|
||||
|
||||
b.setCurrentIndex(b.findData(value));
|
||||
if (b.currentIndex() == -1)
|
||||
b.setCurrentIndex(count);
|
||||
}
|
||||
|
||||
// Returns Diff/Expo/Weight/Offset adjustment value as either a percentage or a global variable name.
|
||||
QString Helpers::getAdjustmentString(int16_t val, const ModelData * model, bool sign)
|
||||
{
|
||||
QString ret;
|
||||
if (val >= -10000 && val <= 10000) {
|
||||
ret = "%1%";
|
||||
if (sign && val > 0)
|
||||
ret.prepend("+");
|
||||
ret = ret.arg(val);
|
||||
}
|
||||
else {
|
||||
ret = RawSource(SOURCE_TYPE_GVAR, abs(val) - 10001).toString(model);
|
||||
if (val < 0)
|
||||
ret.prepend("-");
|
||||
else if (sign)
|
||||
ret.prepend("+");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// TODO: Move lookup to GVarData class (w/out combobox)
|
||||
void Helpers::populateGvarUseCB(QComboBox * b, unsigned int phase)
|
||||
{
|
||||
@@ -742,7 +546,8 @@ GpsCoord extractGpsCoordinates(const QString & position)
|
||||
return result;
|
||||
}
|
||||
|
||||
TableLayout::TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels)
|
||||
TableLayout::TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels) :
|
||||
QObject(parent)
|
||||
{
|
||||
#if defined(TABLE_LAYOUT)
|
||||
tableWidget = new QTableWidget(parent);
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _HELPERS_H_
|
||||
#define _HELPERS_H_
|
||||
#pragma once
|
||||
|
||||
#include "eeprominterface.h"
|
||||
#include <QCheckBox>
|
||||
@@ -60,12 +59,15 @@ class CompanionIcon: public QIcon {
|
||||
void addImage(const QString &baseimage, Mode mode = Normal, State state = Off);
|
||||
};
|
||||
|
||||
class FilteredItemModel;
|
||||
|
||||
class GVarGroup: public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model, const int deflt, const int mini, const int maxi, const double step=1.0, bool allowGVars=true);
|
||||
GVarGroup(QCheckBox * weightGV, QAbstractSpinBox * weightSB, QComboBox * weightCB, int & weight, const ModelData & model,
|
||||
const int deflt, const int mini, const int maxi, const double step = 1.0, FilteredItemModel * gvarModel = nullptr);
|
||||
|
||||
void setWeight(int val);
|
||||
|
||||
@@ -98,40 +100,9 @@ class GVarGroup: public QObject {
|
||||
bool lock;
|
||||
};
|
||||
|
||||
#define HIDE_DIFF 0x01
|
||||
#define HIDE_EXPO 0x02
|
||||
#define HIDE_NEGATIVE_CURVES 0x04
|
||||
|
||||
class CurveGroup : public QObject {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CurveGroup(QComboBox *curveTypeCB, QCheckBox *curveGVarCB, QComboBox *curveValueCB, QSpinBox *curveValueSB, CurveReference & curve, const ModelData & model, unsigned int flags=0);
|
||||
void update();
|
||||
|
||||
protected slots:
|
||||
void gvarCBChanged(int);
|
||||
void typeChanged(int);
|
||||
void valuesChanged();
|
||||
|
||||
protected:
|
||||
QComboBox *curveTypeCB;
|
||||
QCheckBox *curveGVarCB;
|
||||
QComboBox *curveValueCB;
|
||||
QSpinBox *curveValueSB;
|
||||
CurveReference & curve;
|
||||
const ModelData & model;
|
||||
unsigned int flags;
|
||||
bool lock;
|
||||
int lastType;
|
||||
};
|
||||
|
||||
namespace Helpers
|
||||
{
|
||||
void populateGvarUseCB(QComboBox *b, unsigned int phase);
|
||||
void populateGVCB(QComboBox & b, int value, const ModelData & model);
|
||||
QString getAdjustmentString(int16_t val, const ModelData * model = NULL, bool sign = false);
|
||||
|
||||
void populateFileComboBox(QComboBox * b, const QSet<QString> & set, const QString & current);
|
||||
void getFileComboBoxValue(QComboBox * b, char * dest, int length);
|
||||
@@ -208,8 +179,9 @@ private:
|
||||
|
||||
GpsCoord extractGpsCoordinates(const QString & position);
|
||||
|
||||
class TableLayout
|
||||
class TableLayout: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TableLayout(QWidget * parent, int rowCount, const QStringList & headerLabels);
|
||||
// ~TableLayout() ;
|
||||
@@ -263,5 +235,3 @@ private:
|
||||
};
|
||||
|
||||
extern Stopwatch gStopwatch;
|
||||
|
||||
#endif // _HELPERS_H_
|
||||
|
||||
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 472 B |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 64 KiB |