Merge pull request #1 from opentx/2.3

Merge to head of development.
This commit is contained in:
richardclli
2020-07-25 13:44:17 +08:00
committed by GitHub
480 changed files with 36805 additions and 20081 deletions
+12
View File
@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ['PayPal.Me/opentx']
+2 -2
View File
@@ -2,11 +2,11 @@ project(OpenTX)
set(VERSION_MAJOR "2")
set(VERSION_MINOR "3")
set(VERSION_REVISION "3")
set(VERSION_REVISION "10")
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 "0025")
set(SDCARD_REVISION "0029")
set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
cmake_minimum_required(VERSION 2.8)
+174 -2
View File
@@ -8,9 +8,11 @@ Romolo Manfredini (romoloman)
Martin Hotař (mhotar)
Maxim (Max) Paperno (mpaperno)
Arne Schwabe (schwabe)
Daniel Gorbea (dgatf)
[Translators]
[fr] Sebastien Charpentier (LapinFou)
[es] Daniel Gorbea (dgatf)
[Other contributors]
Rob Thomson
@@ -29,6 +31,7 @@ Michael Byrne
<a href="https://www.frsky-rc.com">FrSky (monthly)</a>
<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="https://alofthobbies.com">Aloft Hobbies</a>
<a href="https://jonathan.it">Jonathan Modellismo</a>
<a href="http://wstech.de">WsTech</a>
@@ -421,7 +424,6 @@ Pablo Gomez Martinez
Alan Thoren
Jack Clodfelter
William Simon
James Houck
Peter Fithern
Thomas Svedman
TechFixPros
@@ -686,7 +688,6 @@ Shaun Currier
Danilo Schiara
John Hennig
RK Custom Homes
James Houck
Piet Teekens
Tommy Widenflycht
Johan Petrus Theophilus
@@ -1666,3 +1667,174 @@ Justin Farnsworth
James Snodgrass
Peter Schneider
Norman Schenck
Boris Hemmer
Gilles Arbona
Patrice Germain
Mart Rogers
Stefan Möst
John Beech
John Rodgers
Stanton Sweet
Peter Suphan
FGS
Outward Ideas
Sylvie Le Madec
James Houck (monthly)
Frank Steinmetz
Gary Garland
Stefano Boggia
Jean-Jacques Pointel
Ferenc Kunkli
Sven Müller
Taavi Tuisk
Thomas Floyd
Matthew LePard
Peter Schneider
Michel Garbarino
Achim Stolze
Fernando Rimoldi
Bernard Delpy
Daniel Dubovsky
Jonathan Starch
Coolwind
Benoit Pichereau
Darko Perković
Burt Pickard-Richardson
Roland Nittby
Frank Barbas
Scott McCoy
Fabrice Debonnet
James Laver
Kevin Bowens
David Frech
Udo Kastenholz
Julio Margarido
Uwe Muendelein
James Jewitt
Daniel Ferreira
Michael Charlston
Leopoldo Cicero
Tom Van Driel
Karl Vetter
Johannes Janssen
François Blondé
Precision Aero
Thomas Håkansson
Gordon Evans
Benny Simonsen
George Kennedy
Stefano Boggia
Maksym Arshynkin
Tomas Sodergren
Jörg Lemnitz
TMac FPV
Josef Schaeffler
Mike Frizell
MeCodeGoodSomeday
Timothy Fry
John Beech
Wojciech Winiarski
Armin Kuepfer
Alain Bregand
James Thompson
Dautremépuis Benoit
Adriano Emanuele Figliola
Stefano Bortolotti
Gerald Zierer
Alessio Noto
Walter Fowler
Robert Black
Klaus Kernstock
Michael Wittich
AG-Software
Dietmar Drees
Winfried Goers
Steve Schoonover
N. Haasnoot (monthly)
Wolfram Bahmann
Florian Reck
Gary Bancroft
Karl-Heinz Behn
Stuart Godsmark
Josko Povse
David Reese
Paul Pearson
Stuart Olson
Pierre Connan
Henk Eeltink
Robert Miller
George Walker
Александр Щитов
Heiko Polig
Gary Wild
Peter Sarcher
Steve Schoonover
Francisco Orcera Exposito
Alan Powell
Martin Eriksson
Wayne J Podaima
Tom Wilkinson
Fred Ceratt
Stefan Grunenberg
Aram Parsamyan
Wolfgang Rauser
John Wall
Martin Haggas
Denis Kelly
James Houck
Brian Stephanik
William McNeice
Sven De Boeck
SB Europe Ltd
Evening Shade Pottery
D van Oostveen
Michael Grosso
Carlos Marcal
d@taweb
Justin Digby
Hermann Vocat
Michael Francini
Michael Chambers
Harold H Youngren
Yann Orselli
Dieter Schaad
Ernst Camenzind
Ciobanu Rivelino Costel
David Jolly
Aram Parsamyan
Stewart Davies
Karsten Schwarz
Robert Mckay
Michael Oeschger
Randy Ling
Jonathan Wise
David Gardner
Christophe Judas
Lachlan Peters
Patrick C Kutschke
Thomas Halenbeck
Barry Wright
Nicolas Ducher
Giampiero Sintoni
Sidney B Harden
John Moody
Sylvain Cubizolles
Adam Kouse
FCG Kas
Dennis Marinus
James Donelson
Stefan Hassler
Reinhard Prix
Jeffrey Johnson
Michael Conway
Ryan Buffington
Thomas Horns
Michael Carnes
William Hallman
James Snodgrass
Michal Mesaros
James Lindner
Laurence Gerrard
Nico Wagner
Christoph Rössner
Ruben Flores
+1 -1
View File
@@ -1,7 +1,7 @@
## OpenTX 2.3 Branch
[![Travis build Status](https://travis-ci.org/opentx/opentx.svg?branch=2.3)](https://travis-ci.org/opentx/opentx)
[![Join the chat at https://chat.open-tx.org](https://camo.githubusercontent.com/3d659054abd6ce21c0e47cf3b83a51bda69ca282/68747470733a2f2f64656d6f2e726f636b65742e636861742f696d616765732f6a6f696e2d636861742e737667)](https://chat.open-tx.org)
[![Join the Discord chat](https://img.shields.io/badge/discord-join_chat-yellow.svg)](https://discord.gg/CZCwVx2)
[![Donate using Paypal](https://img.shields.io/badge/paypal-donate-yellow.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DJ9MASSKVW8WN)
The ongoing development on 2.3.x is done in this branch.
+15 -14
View File
@@ -24,8 +24,6 @@ set(COMPANION_OSX_APP_BUNDLE_NAME "OpenTX Companion ${VERSION_MAJOR}.${VERSION_M
# On OS X we copy dfu-util to the application bundle. This the path from which we copy
# the binary (default homebrew path)
set(DFU_UTIL_PATH "/usr/local/bin/dfu-util")
set(AVRDUDE_PATH "/usr/local/bin/avrdude")
set(AVRDUDE_CONF "/usr/local/etc/avrdude.conf")
option(ALLOW_NIGHTLY_BUILDS "Allow nightly builds download / update") # Disabled by default
if(ALLOW_NIGHTLY_BUILDS)
@@ -123,7 +121,7 @@ configure_file(${COMPANION_SRC_DIRECTORY}/simulator.desktop.in ${CMAKE_CURRENT_B
### Generate .qm files and assemble resource (qrc) file.
# available Companion translations (src/translations/*.ts)
set(LANGUAGES cs de en es fi fr it pl sv zh_CN ja)
set(LANGUAGES cs de en es fi fr it pl ru sv zh_CN ja)
foreach(language ${LANGUAGES})
list(APPEND companion_TS translations/companion_${language}.ts)
endforeach(language)
@@ -239,7 +237,6 @@ set(companion_SRCS
flasheepromdialog.cpp
printdialog.cpp
modelprinter.cpp
fusesdialog.cpp
logsdialog.cpp
downloaddialog.cpp
splashlibrarydialog.cpp
@@ -250,6 +247,7 @@ set(companion_SRCS
wizarddialog.cpp
styleeditdialog.cpp
dialogs/filesyncdialog.cpp # TODO move to own lib with other dialogs
profilechooser.cpp
)
set(companion_MOC_HDRS
@@ -258,7 +256,6 @@ set(companion_MOC_HDRS
burnconfigdialog.h
comparedialog.h
printdialog.h
fusesdialog.h
logsdialog.h
creditsdialog.h
releasenotesdialog.h
@@ -284,12 +281,12 @@ set(companion_MOC_HDRS
styleeditdialog.h
helpers_html.h
dialogs/filesyncdialog.h
profilechooser.h
)
set(companion_UIS
mdichild.ui
comparedialog.ui
fusesdialog.ui
logsdialog.ui
apppreferencesdialog.ui
fwpreferencesdialog.ui
@@ -305,6 +302,7 @@ set(companion_UIS
flasheepromdialog.ui
radionotfound.ui
styleeditdialog.ui
profilechooser.ui
)
if(WIN32)
@@ -341,7 +339,9 @@ endif()
# the current flavour is not automatically added if build in the current cmake iteration, so always
# add its library name to be sure
if(PCB STREQUAL X7 AND PCBREV STREQUAL T12)
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 X9D+ AND PCBREV STREQUAL 2019)
set(FLAVOUR x9d+2019)
@@ -349,6 +349,10 @@ elseif(PCB STREQUAL X10 AND PCBREV STREQUAL EXPRESS)
set(FLAVOUR x10express)
elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T16)
set(FLAVOUR t16)
elseif(PCB STREQUAL X10 AND PCBREV STREQUAL TX16S)
set(FLAVOUR tx16s)
elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T18)
set(FLAVOUR t18)
else()
string(TOLOWER ${PCB} FLAVOUR)
endif()
@@ -400,7 +404,7 @@ elseif(WIN32)
install(TARGETS ${SIMULATOR_NAME} DESTINATION ${INSTALL_DESTINATION})
install(FILES ${simulator_plugins} DESTINATION "${INSTALL_DESTINATION}")
# supporting utilities
set(INSTALL_TEMP_FILES avrdude.exe avrdude.conf dfu-util.exe libusb0.dll libusb-1.0.dll license.txt)
set(INSTALL_TEMP_FILES dfu-util.exe libusb0.dll libusb-1.0.dll license.txt)
foreach(tmpfile ${INSTALL_TEMP_FILES})
install(FILES "${COMPANION_SRC_DIRECTORY}/../targets/windows/${tmpfile}" DESTINATION ${INSTALL_DESTINATION})
endforeach()
@@ -547,14 +551,11 @@ IF(APPLE)
set(${COMPANION_SOURCES} ${COMPANION_SOURCES} ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE})
install(FILES ${MAC_ICON_FILE} DESTINATION ${companion_res_dir} COMPONENT Runtime)
# Copy dfu-util and avrdude, resolve symlink first
# Copy dfu-util, resolve symlink first
get_filename_component(DFU_UTIL_ABSOLUTE_PATH ${DFU_UTIL_PATH} REALPATH)
get_filename_component(AVRDUDE_ABSOLUTE_PATH ${AVRDUDE_PATH} REALPATH)
get_filename_component(AVRDUDECONF_ABSOLUTE_PATH ${AVRDUDE_CONF} REALPATH)
install(PROGRAMS ${DFU_UTIL_ABSOLUTE_PATH} ${AVRDUDE_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
install(FILES ${AVRDUDECONF_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
install(PROGRAMS ${DFU_UTIL_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
set(bundle_tools_path "\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/dfu-util;\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/avrdude")
set(bundle_tools_path "\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/dfu-util;")
# Include depencies (adding frameworks, fixing the embbeded libraries)
+10 -1
View File
@@ -73,6 +73,7 @@ void AppPreferencesDialog::accept()
g.OpenTxBranch(AppData::DownloadBranchType(ui->OpenTxBranch->currentIndex()));
g.autoCheckFw(ui->autoCheckFirmware->isChecked());
g.showSplash(ui->showSplash->isChecked());
g.promptProfile(ui->chkPromptProfile->isChecked());
g.simuSW(ui->simuSW->isChecked());
g.removeModelSlots(ui->opt_removeBlankSlots->isChecked());
g.newModelAction(ui->opt_newMdl_useWizard->isChecked() ? AppData::MODEL_ACT_WIZARD : ui->opt_newMdl_useEditor->isChecked() ? AppData::MODEL_ACT_EDITOR : AppData::MODEL_ACT_NONE);
@@ -185,6 +186,7 @@ void AppPreferencesDialog::initSettings()
ui->autoCheckCompanion->setChecked(g.autoCheckApp());
ui->autoCheckFirmware->setChecked(g.autoCheckFw());
ui->showSplash->setChecked(g.showSplash());
ui->chkPromptProfile->setChecked(g.promptProfile());
ui->historySize->setValue(g.historySize());
ui->backLightColor->setCurrentIndex(g.backLight());
ui->volumeGain->setValue(profile.volumeGain() / 10.0);
@@ -352,6 +354,13 @@ void AppPreferencesDialog::on_ge_pathButton_clicked()
}
}
void AppPreferencesDialog::on_btnClearPos_clicked()
{
SimulatorOptions opts = g.profile[g.sessionId()].simulatorOptions();
opts.controlsState.clear();
g.profile[g.sessionId()].simulatorOptions(opts);
}
#if defined(JOYSTICKS)
void AppPreferencesDialog::on_joystickChkB_clicked() {
if (ui->joystickChkB->isChecked()) {
@@ -541,7 +550,7 @@ void AppPreferencesDialog::populateFirmwareOptions(const Firmware * firmware)
// TODO: Remove once splash replacement supported on Horus
// NOTE: 480x272 image causes issues on screens <800px high, needs a solution like scrolling once reinstated
if (IS_HORUS(baseFw->getBoard())) {
if (IS_FAMILY_HORUS_OR_T16(baseFw->getBoard())) {
ui->widget_splashImage->hide();
ui->SplashFileName->setText("");
}
+1
View File
@@ -66,6 +66,7 @@ class AppPreferencesDialog : public QDialog
void on_SplashSelect_clicked();
void on_clearImageButton_clicked();
void on_btn_appLogsDir_clicked();
void on_btnClearPos_clicked();
#if defined(JOYSTICKS)
void on_joystickChkB_clicked();
+395 -356
View File
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>741</width>
<width>864</width>
<height>668</height>
</rect>
</property>
@@ -45,7 +45,7 @@
</sizepolicy>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="profileTab">
<attribute name="title">
@@ -61,22 +61,40 @@
</sizepolicy>
</property>
<layout class="QGridLayout" name="optionsLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>5</number>
</property>
<property name="verticalSpacing">
<number>4</number>
</property>
<property name="margin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item row="7" column="0" colspan="4">
<widget class="QWidget" name="widget_splashImage" native="true">
<layout class="QGridLayout" name="gridLayout_5">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
@@ -704,29 +722,90 @@ Mode 4:
<property name="spacing">
<number>6</number>
</property>
<item row="7" column="1">
<layout class="QVBoxLayout" name="updatesLayout">
<item row="15" column="1">
<widget class="QCheckBox" name="backupEnable">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable automatic backup before writing firmware</string>
</property>
</widget>
</item>
<item row="22" column="0">
<widget class="QLabel" name="ge_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Google Earth Executable</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QComboBox" name="OpenTxBranch">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<widget class="QCheckBox" name="autoCheckFirmware">
<property name="text">
<string>Automatic check for OpenTX firmware updates</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<property name="text">
<string>Releases (stable)</string>
</property>
</item>
<item>
<widget class="QCheckBox" name="autoCheckCompanion">
<property name="text">
<string>Automatic check for Companion updates</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
<property name="text">
<string>Release candidates (testing)</string>
</property>
</item>
</layout>
<item>
<property name="text">
<string>Nightly builds (unstable)</string>
</property>
</item>
</widget>
</item>
<item row="18" column="1">
<widget class="QComboBox" name="splashincludeCB">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Only show user splash images</string>
</property>
</item>
<item>
<property name="text">
<string>Show user and companion splash images</string>
</property>
</item>
</widget>
</item>
<item row="12" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="16" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_10" stretch="0,1">
@@ -764,120 +843,27 @@ Mode 4:
</item>
</layout>
</item>
<item row="6" column="0" rowspan="2">
<widget class="QLabel" name="label_16">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Startup Settings</string>
</property>
</widget>
</item>
<item row="21" column="0">
<widget class="QLabel" name="ge_label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Google Earth Executable</string>
</property>
</widget>
</item>
<item row="11" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="showSplash">
<property name="text">
<string>Show splash screen when Companion starts</string>
<string>Show splash screen</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_17">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Automatic Backup Folder</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Remember</string>
</property>
</widget>
</item>
<item row="13" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item row="22" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QLineEdit" name="backupPath">
<widget class="QLineEdit" name="ge_lineedit">
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="backupPathButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select Folder</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="18" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLineEdit" name="libraryPath">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="libraryPathButton">
<widget class="QPushButton" name="ge_pathButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -885,49 +871,13 @@ Mode 4:
</sizepolicy>
</property>
<property name="text">
<string>Select Folder</string>
<string>Select Executable</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="opt_removeBlankSlots">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option maintains the behaviour from older OpenTx versions where empty model slots are preserved when a model is deleted or moved. &lt;/p&gt;&lt;p&gt;When this option is de-selected, the other models may be re-arranged to fill the gap left by the removed model.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Remove empty model slots when deleting models (only applies for radios w/out categories)</string>
</property>
</widget>
</item>
<item row="24" column="0">
<widget class="QLabel" name="lbl_appLogsDir">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Output Logs Folder</string>
</property>
</widget>
</item>
<item row="23" column="0">
<widget class="QLabel" name="label_12">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Debug Output Logging</string>
</property>
</widget>
</item>
<item row="9" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QRadioButton" name="opt_newMdl_useWizard">
@@ -962,90 +912,22 @@ Mode 4:
</layout>
</item>
<item row="14" column="1">
<widget class="QCheckBox" name="backupEnable">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable automatic backup before writing firmware</string>
</property>
</widget>
</item>
<item row="19" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="17" column="1">
<widget class="QComboBox" name="splashincludeCB">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<property name="text">
<string>Only show user splash images</string>
</property>
</item>
<item>
<property name="text">
<string>Show user and companion splash images</string>
</property>
</item>
</widget>
</item>
<item row="15" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="21" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QLineEdit" name="ge_lineedit">
<widget class="QLineEdit" name="backupPath">
<property name="readOnly">
<bool>true</bool>
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="ge_pathButton">
<widget class="QPushButton" name="backupPathButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select Executable</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="24" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="appLogsDir">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_appLogsDir">
<property name="text">
<string>Select Folder</string>
</property>
@@ -1053,14 +935,56 @@ Mode 4:
</item>
</layout>
</item>
<item row="22" column="0" colspan="2">
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Remember</string>
</property>
</widget>
</item>
<item row="18" column="0">
<item row="25" column="0">
<widget class="QLabel" name="lbl_appLogsDir">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Output Logs Folder</string>
</property>
</widget>
</item>
<item row="6" column="0" rowspan="3">
<widget class="QLabel" name="label_16">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Startup Settings</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QCheckBox" name="opt_removeBlankSlots">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;This option maintains the behaviour from older OpenTx versions where empty model slots are preserved when a model is deleted or moved. &lt;/p&gt;&lt;p&gt;When this option is de-selected, the other models may be re-arranged to fill the gap left by the removed model.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Remove empty model slots when deleting models (only applies for radios w/out categories)</string>
</property>
</widget>
</item>
<item row="19" column="0">
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -1073,33 +997,7 @@ Mode 4:
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Splash Screen Library</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Action on New Model</string>
</property>
</widget>
</item>
<item row="23" column="1">
<item row="24" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="opt_appDebugLog">
@@ -1123,36 +1021,163 @@ Mode 4:
</item>
</layout>
</item>
<item row="8" column="0">
<item row="25" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="appLogsDir">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btn_appLogsDir">
<property name="text">
<string>Select Folder</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Action on New Model</string>
</property>
</widget>
</item>
<item row="19" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QLineEdit" name="libraryPath">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="libraryPathButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Select Folder</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="18" column="0">
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Splash Screen Library</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_18">
<property name="text">
<string>Release channel</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QComboBox" name="OpenTxBranch">
<item row="4" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="24" column="0">
<widget class="QLabel" name="label_12">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Debug Output Logging</string>
</property>
</widget>
</item>
<item row="23" column="0" colspan="2">
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="label_17">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Automatic Backup Folder</string>
</property>
</widget>
</item>
<item row="8" column="1">
<layout class="QVBoxLayout" name="updatesLayout">
<item>
<property name="text">
<string>Releases (stable)</string>
</property>
<widget class="QCheckBox" name="autoCheckFirmware">
<property name="text">
<string>Automatic check for OpenTX firmware updates</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<property name="text">
<string>Release candidates (testing)</string>
</property>
</item>
<item>
<property name="text">
<string>Nightly builds (unstable)</string>
</property>
<widget class="QCheckBox" name="autoCheckCompanion">
<property name="text">
<string>Automatic check for Companion updates</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="20" column="0" rowspan="2" colspan="2">
<widget class="Line" name="line_7">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="chkPromptProfile">
<property name="text">
<string>Prompt for radio profile</string>
</property>
</widget>
</item>
</layout>
@@ -1180,7 +1205,38 @@ Mode 4:
<property name="spacing">
<number>6</number>
</property>
<item row="5" column="1">
<item row="10" column="1">
<widget class="QDoubleSpinBox" name="volumeGain">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.500000000000000</double>
</property>
<property name="maximum">
<double>3.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QComboBox" name="joystickCB">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@@ -1193,14 +1249,20 @@ Mode 4:
</property>
</widget>
</item>
<item row="5" column="3">
<widget class="QPushButton" name="joystickcalButton">
<item row="0" column="0">
<widget class="QLabel" name="label_19">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Calibrate</string>
<string>Screenshot capture folder</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="7" column="1">
<widget class="QComboBox" name="backLightColor">
<property name="maximumSize">
<size>
@@ -1235,31 +1297,22 @@ Mode 4:
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_19">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="9" column="3">
<widget class="QPushButton" name="joystickcalButton">
<property name="text">
<string>Screenshot capture folder</string>
<string>Calibrate</string>
</property>
</widget>
</item>
<item row="8" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<item row="0" column="3">
<widget class="QPushButton" name="snapshotPathButton">
<property name="text">
<string>Select Folder</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
<property name="flat">
<bool>false</bool>
</property>
</spacer>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QCheckBox" name="snapshotClipboardCKB">
@@ -1274,7 +1327,7 @@ Mode 4:
</property>
</widget>
</item>
<item row="5" column="2">
<item row="9" column="2">
<widget class="QCheckBox" name="joystickChkB">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@@ -1287,17 +1340,20 @@ Mode 4:
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QPushButton" name="snapshotPathButton">
<property name="text">
<string>Select Folder</string>
<item row="12" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="flat">
<bool>false</bool>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</widget>
</spacer>
</item>
<item row="5" column="0">
<item row="9" column="0">
<widget class="QLabel" name="label_11">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -1310,7 +1366,20 @@ Mode 4:
</property>
</widget>
</item>
<item row="3" column="0">
<item row="10" column="0">
<widget class="QLabel" name="label_volumeGain">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Simulator Volume Gain</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -1348,60 +1417,30 @@ Mode 4:
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
<item row="2" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
<string>Simulator controls</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QCheckBox" name="simuSW">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Remember simulator switch values</string>
<string>Save switch/pot positions on simulator exit</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_volumeGain">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="2" column="3">
<widget class="QPushButton" name="btnClearPos">
<property name="text">
<string>Simulator Volume Gain</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QDoubleSpinBox" name="volumeGain">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>0.500000000000000</double>
</property>
<property name="maximum">
<double>3.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
<string>Clear saved positions</string>
</property>
</widget>
</item>
+3 -194
View File
@@ -36,61 +36,23 @@ burnConfigDialog::burnConfigDialog(QWidget *parent) :
{
ui->setupUi(this);
setWindowIcon(CompanionIcon("configure.png"));
ui->avrdude_programmer->model()->sort(0);
getSettings();
populateProgrammers();
Board::Type board = getCurrentBoard();
if (IS_STM32(board)) {
setWindowTitle(tr("DFU-UTIL Configuration"));
ui->avrArgs->hide();
ui->avrdude_location->hide();
ui->avrdude_port->hide();
ui->avrdude_programmer->hide();
ui->label_av1->hide();
ui->label_av2->hide();
ui->label_av4->hide();
ui->label_av5->hide();
ui->pushButton->hide();
ui->pushButton_3->hide();
ui->pushButton_4->hide();
ui->label_sb1->hide();
ui->label_sb3->hide();
ui->samba_location->hide();
ui->samba_port->hide();
ui->sb_browse->hide();
}
else if (IS_SKY9X(board)) {
setWindowTitle(tr("SAM-BA Configuration"));
ui->avrArgs->hide();
ui->avrdude_location->hide();
ui->avrdude_port->hide();
ui->avrdude_programmer->hide();
ui->label_av1->hide();
ui->label_av2->hide();
ui->label_av4->hide();
ui->label_av5->hide();
ui->pushButton->hide();
ui->pushButton_3->hide();
ui->pushButton_4->hide();
ui->label_dfu1->hide();
ui->dfu_location->hide();
ui->dfu_browse->hide();
}
else {
setWindowTitle(tr("AVRDUDE Configuration"));
ui->label_sb1->hide();
ui->label_sb3->hide();
ui->samba_location->hide();
ui->samba_port->hide();
ui->sb_browse->hide();
setWindowTitle(tr("SAM-BA Configuration"));
ui->label_dfu1->hide();
ui->label_dfu2->hide();
ui->dfu_location->hide();
ui->dfu_browse->hide();
}
ui->label_av3->hide();
ui->avrdude_mcu->hide();
ui->label_sb2->hide();
ui->arm_mcu->hide();
ui->label_dfu2->hide();
@@ -105,46 +67,26 @@ burnConfigDialog::~burnConfigDialog()
delete ui;
}
QStringList burnConfigDialog::getAvrdudeArgs()
{
QStringList args = avrArgs;
if (!avrPort.isEmpty())
args << "-P" << avrPort;
#if defined(__APPLE__)
args << "-C" << QFileInfo(QApplication::applicationDirPath() + "/../Resources/avrdude.conf").absoluteFilePath();
#endif
return args;
}
void burnConfigDialog::getSettings()
{
avrLoc = g.avrdudeLocation();
sambaLoc = g.sambaLocation();
dfuLoc = g.dfuLocation();
#if defined WIN32 || !defined __GNUC__
if ( avrLoc.isEmpty())
avrLoc = QFileInfo("avrdude.exe").absoluteFilePath();
if ( sambaLoc.isEmpty())
sambaLoc = QFileInfo("sam-ba.exe").absoluteFilePath();
if ( dfuLoc.isEmpty())
dfuLoc = QFileInfo("dfu-util.exe").absoluteFilePath();
#elif defined __APPLE__
if ( avrLoc.isEmpty())
avrLoc = QFileInfo(QApplication::applicationDirPath() + "/../Resources/avrdude").absoluteFilePath();
if ( sambaLoc.isEmpty())
sambaLoc = "/usr/local/bin/sam-ba";
if ( dfuLoc.isEmpty())
dfuLoc = QFileInfo(QApplication::applicationDirPath() + "/../Resources/dfu-util").absoluteFilePath();
#elif defined __FreeBSD__
if (avrLoc.isEmpty())
avrLoc = "/usr/local/bin/avrdude";
if (dfuLoc.isEmpty())
dfuLoc = "/usr/local/bin/dfu-util";
#else
if ( avrLoc.isEmpty())
avrLoc = "/usr/bin/avrdude";
if ( sambaLoc.isEmpty())
sambaLoc = "/usr/bin/sam-ba";
if ( dfuLoc.isEmpty())
@@ -152,45 +94,22 @@ void burnConfigDialog::getSettings()
#endif
dfuArgs = g.dfuArguments().split(" ", QString::SkipEmptyParts);
avrArgs = g.avrArguments().split(" ", QString::SkipEmptyParts);
avrProgrammer = g.programmer();
avrPort = g.avrPort();
avrMCU = g.mcu();
armMCU = g.armMcu();
sambaPort = g.sambaPort();
ui->avrdude_location->setText(getAVRDUDE());
ui->avrArgs->setText(avrArgs.join(" "));
ui->samba_location->setText(getSAMBA());
ui->samba_port->setText(getSambaPort());
ui->dfu_location->setText(getDFU());
ui->dfuArgs->setText(getDFUArgs().join(" "));
int idx1 = ui->avrdude_programmer->findText(getProgrammer());
int idx2 = ui->avrdude_port->findText(getPort());
int idx3 = ui->avrdude_mcu->findText(getMCU());
int idx4 = ui->arm_mcu->findText(getArmMCU());
if(idx1>=0) ui->avrdude_programmer->setCurrentIndex(idx1);
if(idx2>=0) ui->avrdude_port->setCurrentIndex(idx2);
if(idx3>=0) ui->avrdude_mcu->setCurrentIndex(idx3);
if(idx4>=0) ui->arm_mcu->setCurrentIndex(idx4);
QFile file;
if (file.exists(avrLoc)) {
ui->pushButton_3->setEnabled(true);
} else {
ui->pushButton_3->setDisabled(true);
}
}
void burnConfigDialog::putSettings()
{
g.avrdudeLocation( avrLoc );
g.programmer( avrProgrammer);
g.mcu( avrMCU );
g.avrPort( avrPort );
g.avrArguments( avrArgs.join(" ") );
g.sambaLocation( sambaLoc );
g.sambaPort( sambaPort );
g.armMcu( armMCU );
@@ -198,73 +117,6 @@ void burnConfigDialog::putSettings()
g.dfuArguments( dfuArgs.join(" ") );
}
void burnConfigDialog::populateProgrammers()
{
QString fileName = QFileInfo(avrLoc).canonicalPath() + "/avrdude.conf"; //for windows
if(!QFileInfo(fileName).exists()) fileName = "/etc/avrdude.conf"; //for linux
if(!QFileInfo(fileName).exists()) fileName = "/etc/avrdude/avrdude.conf"; //for linux
if(!QFileInfo(fileName).exists()) return; // not found avrdude.conf - returning
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
QStringList items;
QString line = "";
QString prevline = "";
QTextStream in(&file);
while (!in.atEnd())
{
prevline = line;
line = in.readLine();
if(prevline.left(10).toLower()=="programmer")
items << line.section('"',1,1);
}
file.close();
items.sort();
QString avrProgrammer_temp = avrProgrammer;
ui->avrdude_programmer->clear();
ui->avrdude_programmer->addItems(items);
int idx1 = ui->avrdude_programmer->findText(avrProgrammer_temp);
if(idx1>=0) ui->avrdude_programmer->setCurrentIndex(idx1);
}
void burnConfigDialog::on_avrdude_programmer_currentIndexChanged(QString )
{
avrProgrammer = ui->avrdude_programmer->currentText();
}
void burnConfigDialog::on_avrdude_mcu_currentIndexChanged(QString )
{
avrMCU = ui->avrdude_mcu->currentText();
}
void burnConfigDialog::on_avrdude_location_editingFinished()
{
avrLoc = ui->avrdude_location->text();
if (avrLoc.isEmpty()) {
ui->pushButton_3->setDisabled(true);
} else {
QFile file;
if (file.exists(avrLoc)) {
ui->pushButton_3->setEnabled(true);
}
}
}
void burnConfigDialog::on_avrArgs_editingFinished()
{
avrArgs = ui->avrArgs->text().split(" ", QString::SkipEmptyParts);
}
void burnConfigDialog::on_avrdude_port_currentIndexChanged(QString )
{
avrPort = ui->avrdude_port->currentText();
}
void burnConfigDialog::on_samba_location_editingFinished()
{
sambaLoc = ui->samba_location->text();
@@ -280,17 +132,6 @@ void burnConfigDialog::on_arm_mcu_currentIndexChanged(QString )
armMCU = ui->arm_mcu->currentText();
}
void burnConfigDialog::on_pushButton_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Location"),ui->avrdude_location->text());
if(!fileName.isEmpty())
{
ui->avrdude_location->setText(fileName);
avrLoc = fileName;
}
}
void burnConfigDialog::on_sb_browse_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Location"),ui->samba_location->text());
@@ -322,27 +163,6 @@ void burnConfigDialog::on_dfuArgs_editingFinished()
dfuArgs = ui->dfuArgs->text().split(" ", QString::SkipEmptyParts);
}
void burnConfigDialog::listAvrdudeProgrammers()
{
ProgressDialog progressDialog(this, tr("List available programmers"), CompanionIcon("list.png"), true);
FlashProcess flashProcess(ui->avrdude_location->text(), QStringList() << "-c?", progressDialog.progress());
flashProcess.run();
}
// TODO choose better name when no merge in progress....
void burnConfigDialog::on_pushButton_3_clicked()
{
listAvrdudeProgrammers();
}
// TODO choose better name when no merge in progress....
void burnConfigDialog::on_pushButton_4_clicked()
{
ProgressDialog progressDialog(this, tr("Avrdude help"), CompanionIcon("configure.png"), true);
FlashProcess flashProcess(ui->avrdude_location->text(), QStringList() << "-?", progressDialog.progress());
flashProcess.run();
}
void burnConfigDialog::on_advCtrChkB_toggled(bool checked)
{
Board::Type board = getCurrentBoard();
@@ -351,31 +171,20 @@ void burnConfigDialog::on_advCtrChkB_toggled(bool checked)
ui->label_dfu2->show();
ui->dfuArgs->show();
}
else if (IS_SKY9X(board)) {
else {
ui->label_sb2->show();
ui->arm_mcu->show();
}
else {
ui->label_av3->show();
ui->avrdude_mcu->show();
QMessageBox::warning(this, CPN_STR_APP_NAME,
tr("<b><u>WARNING!</u></b><br>Normally CPU type is automatically selected according to the chosen firmware.<br>If you change the CPU type the resulting eeprom could be inconsistent."),
QMessageBox::Ok);
}
}
else {
if (IS_STM32(board)) {
ui->label_dfu2->hide();
ui->dfuArgs->hide();
}
else if (IS_SKY9X(board)) {
else {
ui->label_sb2->hide();
ui->arm_mcu->hide();
}
else {
ui->label_av3->hide();
ui->avrdude_mcu->hide();
}
}
QTimer::singleShot(0, this, SLOT(shrink()));
}
-20
View File
@@ -39,45 +39,25 @@ public:
burnConfigDialog(QWidget *parent = 0);
~burnConfigDialog();
QString getAVRDUDE() {return avrLoc;}
QString getSAMBA() {return sambaLoc;}
QString getDFU() {return dfuLoc;}
QStringList getAvrdudeArgs();
QStringList getDFUArgs() {return dfuArgs;}
QString getProgrammer() {return avrProgrammer;}
QString getMCU() {return avrMCU;}
QString getArmMCU() {return armMCU;}
QString getPort() {return avrPort;}
QString getSambaPort() {return sambaPort;}
void listAvrdudeProgrammers();
private:
Ui::burnConfigDialog *ui;
void populateProgrammers();
QString avrLoc;
QString sambaLoc;
QString dfuLoc;
QStringList avrArgs;
QString avrProgrammer;
QString avrMCU;
QString armMCU;
QString avrPort;
QString sambaPort;
QStringList dfuArgs;
private slots:
void shrink();
void on_avrArgs_editingFinished();
void on_pushButton_4_clicked();
void on_pushButton_3_clicked();
void on_pushButton_clicked();
void on_avrdude_location_editingFinished();
void on_avrdude_programmer_currentIndexChanged(QString );
void on_avrdude_mcu_currentIndexChanged(QString );
void on_avrdude_port_currentIndexChanged(QString );
void on_samba_location_editingFinished();
void on_samba_port_editingFinished();
void on_arm_mcu_currentIndexChanged(QString );
+32 -628
View File
@@ -45,615 +45,7 @@
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="9" column="2">
<widget class="QLineEdit" name="dfu_location">
<property name="toolTip">
<string>Location of sam-ba executable</string>
</property>
<property name="whatsThis">
<string>The location of the AVRDUDE executable.</string>
</property>
<property name="text">
<string notr="true">dfu-util</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_dfu1">
<property name="text">
<string>DFU-Util Location</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="avrdude_location">
<property name="toolTip">
<string>Location of AVRDUDE executable</string>
</property>
<property name="whatsThis">
<string>The location of the AVRDUDE executable.</string>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="0" column="4" rowspan="2">
<widget class="QPushButton" name="pushButton">
<property name="whatsThis">
<string>Use this button to browse and look for the AVRDUDE executable file.</string>
</property>
<property name="text">
<string>Browse...</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_av2">
<property name="text">
<string>Programmer</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="avrdude_programmer">
<property name="whatsThis">
<string>Programmer used for communicating with the controller.
Please consult the programmer's documentation and the AVRDUDE documentation to select the appropriate programmer.</string>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAlphabetically</enum>
</property>
<item>
<property name="text">
<string notr="true">c2n232i</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dasa3</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dasa</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">siprog</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">ponyser</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">89isp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">frank-stk200</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">blaster</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">ere-isp-avr</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">atisp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dapa</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">xil</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">futurlec</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">abcmini</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">picoweb</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">sp12</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">alf</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">bascom</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dt006</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">pony-stk200</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">stk200</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">bsd</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">pavr</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dragon_pdi</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dragon_dw</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dragon_hvsp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dragon_pp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dragon_isp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">dragon_jtag</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtag2pdi</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtag2avr32</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtagmkII_avr32</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtag2dw</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtag2isp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtag2</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtag2fast</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtag2slow</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtagmkII</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtag1slow</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtag1</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">jtagmkI</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">avr911</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">avr109</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">butterfly</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">usbtiny</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">usbasp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">avr910</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">stk600hvsp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">stk600pp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">stk600</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">stk500hvsp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">stk500pp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">stk500v2</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">mib510</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">stk500v1</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">stk500</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">buspirate</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">avrisp2</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">avrispmkII</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">avrispv2</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">avrisp</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">arduino</string>
</property>
</item>
</widget>
</item>
<item row="2" column="4">
<widget class="QPushButton" name="pushButton_3">
<property name="whatsThis">
<string>List all available programmers.</string>
</property>
<property name="text">
<string>List Available</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLineEdit" name="avrArgs">
<property name="toolTip">
<string>Extra arguments that will be passed to AVRDUDE on every call</string>
</property>
<property name="whatsThis">
<string>Extra arguments used in AVRDUDE.
This can be used for providing extra information to AVRDUDE.
Please only use this if you know what you are doing. There are no error checks and you could cripple your controller.</string>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_av5">
<property name="text">
<string>Extra Arguments</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="4">
<widget class="QPushButton" name="pushButton_4">
<property name="whatsThis">
<string>Show AVRDUDE help</string>
</property>
<property name="text">
<string>Show Help</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QComboBox" name="avrdude_port">
<property name="whatsThis">
<string>Communication port to the programmer.
</string>
</property>
<item>
<property name="text">
<string notr="true"/>
</property>
</item>
<item>
<property name="text">
<string notr="true">usb</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com1</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com2</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com3</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com4</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com5</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com6</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com7</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com8</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com9</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com10</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com11</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com12</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com13</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com14</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">com15</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">lpt1</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">lpt2</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">lpt3</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">lpt4</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">avrdoper</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">/dev/ttyUSB0</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">/dev/ttyUSB1</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_av4">
<property name="text">
<string>Port</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_av1">
<property name="text">
<string>AVRDUDE Location</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_av3">
<property name="text">
<string>MCU</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QComboBox" name="avrdude_mcu">
<property name="toolTip">
<string>CPU of your TX</string>
</property>
<property name="whatsThis">
<string>CPU present on your 9x radio
Should be m64 for stock radios
m2560 for v4.1 boards</string>
</property>
<property name="insertPolicy">
<enum>QComboBox::InsertAlphabetically</enum>
</property>
<item>
<property name="text">
<string notr="true">m64</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">m128</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">m2560</string>
</property>
</item>
</widget>
</item>
<item row="7" column="2">
<item row="1" column="2">
<widget class="QComboBox" name="arm_mcu">
<property name="toolTip">
<string>CPU of your TX</string>
@@ -678,7 +70,27 @@ m2560 for v4.1 boards</string>
</item>
</widget>
</item>
<item row="6" column="0">
<item row="3" column="2">
<widget class="QLineEdit" name="dfu_location">
<property name="toolTip">
<string>Location of sam-ba executable</string>
</property>
<property name="whatsThis">
<string>The location of the AVRDUDE executable.</string>
</property>
<property name="text">
<string notr="true">dfu-util</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_dfu1">
<property name="text">
<string>DFU-Util Location</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_sb1">
<property name="text">
<string>SAM-BA Location</string>
@@ -688,7 +100,7 @@ m2560 for v4.1 boards</string>
</property>
</widget>
</item>
<item row="6" column="2">
<item row="0" column="2">
<widget class="QLineEdit" name="samba_location">
<property name="toolTip">
<string>Location of sam-ba executable</string>
@@ -701,7 +113,7 @@ m2560 for v4.1 boards</string>
</property>
</widget>
</item>
<item row="7" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label_sb2">
<property name="text">
<string>ARM MCU</string>
@@ -711,7 +123,7 @@ m2560 for v4.1 boards</string>
</property>
</widget>
</item>
<item row="8" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_sb3">
<property name="text">
<string>Port</string>
@@ -721,7 +133,7 @@ m2560 for v4.1 boards</string>
</property>
</widget>
</item>
<item row="8" column="2">
<item row="2" column="2">
<widget class="QLineEdit" name="samba_port">
<property name="toolTip">
<string>sam-ba serial port</string>
@@ -734,14 +146,14 @@ m2560 for v4.1 boards</string>
</property>
</widget>
</item>
<item row="10" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_dfu2">
<property name="text">
<string>Alternate device</string>
</property>
</widget>
</item>
<item row="10" column="2">
<item row="4" column="2">
<widget class="QLineEdit" name="dfuArgs">
<property name="toolTip">
<string>Extra arguments that will be passed to AVRDUDE on every call</string>
@@ -757,7 +169,7 @@ Please only use this if you know what you are doing. There are no error checks
</property>
</widget>
</item>
<item row="6" column="4">
<item row="0" column="4">
<widget class="QPushButton" name="sb_browse">
<property name="whatsThis">
<string>Use this button to browse and look for the AVRDUDE executable file.</string>
@@ -767,7 +179,7 @@ Please only use this if you know what you are doing. There are no error checks
</property>
</widget>
</item>
<item row="9" column="4">
<item row="3" column="4">
<widget class="QPushButton" name="dfu_browse">
<property name="whatsThis">
<string>Use this button to browse and look for the AVRDUDE executable file.</string>
@@ -777,14 +189,14 @@ Please only use this if you know what you are doing. There are no error checks
</property>
</widget>
</item>
<item row="11" column="2">
<item row="5" column="2">
<widget class="QCheckBox" name="advCtrChkB">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="11" column="0">
<item row="5" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Use advanced controls</string>
@@ -809,14 +221,6 @@ Please only use this if you know what you are doing. There are no error checks
</layout>
</widget>
<tabstops>
<tabstop>avrdude_location</tabstop>
<tabstop>pushButton</tabstop>
<tabstop>avrdude_programmer</tabstop>
<tabstop>pushButton_3</tabstop>
<tabstop>avrdude_mcu</tabstop>
<tabstop>avrdude_port</tabstop>
<tabstop>avrArgs</tabstop>
<tabstop>pushButton_4</tabstop>
<tabstop>samba_location</tabstop>
<tabstop>sb_browse</tabstop>
<tabstop>arm_mcu</tabstop>
+21
View File
@@ -190,6 +190,27 @@
<file>images/simulator/JumperT16/left_tele.png</file>
<file>images/simulator/JumperT16/right_ent.png</file>
<file>images/simulator/JumperT16/right_rtn.png</file>
<file>images/simulator/JumperT18/left.png</file>
<file>images/simulator/JumperT18/right.png</file>
<file>images/simulator/JumperT18/top.png</file>
<file>images/simulator/JumperT18/bottom.png</file>
<file>images/simulator/JumperT18/left_mdl.png</file>
<file>images/simulator/JumperT18/left_page.png</file>
<file>images/simulator/JumperT18/left_sys.png</file>
<file>images/simulator/JumperT18/left_tele.png</file>
<file>images/simulator/JumperT18/right_ent.png</file>
<file>images/simulator/JumperT18/right_rtn.png</file>
<file>images/simulator/TX16S/left.png</file>
<file>images/simulator/TX16S/right.png</file>
<file>images/simulator/TX16S/top.png</file>
<file>images/simulator/TX16S/bottom.png</file>
<file>images/simulator/TX16S/left_page.png</file>
<file>images/simulator/TX16S/left_page2.png</file>
<file>images/simulator/TX16S/left_rtn.png</file>
<file>images/simulator/TX16S/left_sys.png</file>
<file>images/simulator/TX16S/left_tele.png</file>
<file>images/simulator/TX16S/right_ent.png</file>
<file>images/simulator/TX16S/right_mdl.png</file>
<file>images/wizard/ailerons.png</file>
<file>images/wizard/airbrakes.png</file>
<file>images/wizard/elevons.png</file>
+2 -2
View File
@@ -54,7 +54,7 @@ DownloadDialog::DownloadDialog(QWidget *parent, QString src, QString tgt):
reply = qnam.get(QNetworkRequest(QUrl(src)));
connect(reply, SIGNAL(finished()), this, SLOT(httpFinished()));
connect(reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDataReadProgress(qint64,qint64)));
connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(updateDataReadProgress(qint64, qint64)));
}
}
@@ -114,7 +114,7 @@ void DownloadDialog::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
void DownloadDialog::fileError()
{
delete file;
file = NULL;
file = nullptr;
reject();
}
+2 -2
View File
@@ -1,5 +1,6 @@
set(firmwares_SRCS
adjustmentreference.cpp
boards.cpp
curvereference.cpp
customfunctiondata.cpp
@@ -17,8 +18,7 @@ set(firmwares_SRCS
rawswitch.cpp
sensordata.cpp
telem_data.cpp
er9x/er9xeeprom.cpp
er9x/er9xinterface.cpp
afhds3.cpp
ersky9x/ersky9xeeprom.cpp
ersky9x/ersky9xinterface.cpp
opentx/opentxeeprom.cpp
@@ -0,0 +1,78 @@
/*
* 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 "adjustmentreference.h"
#include "radiodata.h" // for ModelData
AdjustmentReference::AdjustmentReference(int value)
{
int val = value;
if (abs(val) > ADJUST_REF_GVAR_BASE && abs(val) <= ADJUST_REF_GVAR_BASE + CPN_MAX_GVARS) {
type = ADJUST_REF_GVAR;
val = val >= 0 ? val - ADJUST_REF_GVAR_BASE : val + ADJUST_REF_GVAR_BASE;
}
else
this->type = ADJUST_REF_VALUE;
this->value = val;
}
AdjustmentReference::AdjustmentReference(AdjustRefType type, int value)
{
this->type = type;
if (isValid(value))
this->value = value;
else
clear();
}
bool AdjustmentReference::isValid(const int value) const
{
switch (type) {
case ADJUST_REF_VALUE:
return abs(value) < ADJUST_REF_GVAR_BASE;
case ADJUST_REF_GVAR:
return abs(value) > 0 && abs(value) <= CPN_MAX_GVARS;
}
return false;
}
QString AdjustmentReference::toString(const ModelData * model, const bool sign) const
{
QString ret;
switch(type) {
case ADJUST_REF_GVAR:
ret = RawSource(SOURCE_TYPE_GVAR, abs(value) - 1).toString(model);
if (value < 0)
ret.prepend("-");
else if (sign)
ret.prepend("+");
break;
default:
ret = "%1%";
if (sign && value > 0)
ret.prepend("+");
ret = ret.arg(value);
break;
}
return ret;
}
@@ -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.
*/
#ifndef ADJUSTMENTREFERENCE_H
#define ADJUSTMENTREFERENCE_H
#include <QtCore>
class ModelData;
constexpr int ADJUST_REF_GVAR_BASE { 10000 };
class AdjustmentReference {
Q_DECLARE_TR_FUNCTIONS(AdjustmentReference)
public:
enum AdjustRefType {
ADJUST_REF_VALUE,
ADJUST_REF_GVAR,
};
AdjustmentReference() { clear(); }
explicit AdjustmentReference(int value);
AdjustmentReference(const AdjustRefType type, const int value);
void clear() { memset(this, 0, sizeof(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;
inline const int toValue() const
{
if (type == ADJUST_REF_GVAR)
return value >= 0 ? value + ADJUST_REF_GVAR_BASE : value - ADJUST_REF_GVAR_BASE;
else
return value;
}
bool operator== ( const AdjustmentReference & other) const {
return (this->type == other.type) && (this->value == other.value);
}
bool operator!= ( const AdjustmentReference & other) const {
return (this->type != other.type) || (this->value != other.value);
}
AdjustRefType type;
int value;
};
#endif // ADJUSTMENTREFERENCE_H
+12
View File
@@ -0,0 +1,12 @@
#include "afhds3.h"
#include "macros.h"
QString Afhds3Data::protocolToString(unsigned int protocol) {
const char * const afhds3Protocols[] = {
"PWM/IBUS",
"PWM/SBUS",
"PPM/IBUS",
"PPM/SBUS",
};
return CHECK_IN_ARRAY(afhds3Protocols, protocol);
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef AFHDS3_H
#define AFHDS3_H
#include <QtCore>
class Afhds3Data
{
Q_DECLARE_TR_FUNCTIONS(Afhds3)
public:
static QString protocolToString(unsigned int protocol);
};
#endif // AFHDS3_H
+30 -44
View File
@@ -25,18 +25,13 @@
// Update: These are now all only used within this class.
// External access is only via getEEpromSize() and getFlashSize()
#define EESIZE_STOCK 2048
#define EESIZE_M128 4096
#define EESIZE_GRUVIN9X 4096
#define EESIZE_TARANIS (32*1024)
#define EESIZE_SKY9X (128*4096)
#define EESIZE_9XRPRO (128*4096)
#define EESIZE_MAX EESIZE_9XRPRO
// getFlashSize() (and these macros) is only used by radiointerface::getDfuArgs (perhaps can find a better way?)
#define FSIZE_STOCK (64*1024)
#define FSIZE_M128 (128*1024)
#define FSIZE_GRUVIN9X (256*1024)
#define FSIZE_TARANIS (512*1024)
#define FSIZE_SKY9X (256*1024)
#define FSIZE_9XRPRO (512*1024)
@@ -66,6 +61,7 @@ uint32_t Boards::getFourCC(Type board)
case BOARD_TARANIS_XLITES:
return 0x3B78746F;
case BOARD_TARANIS_X7:
case BOARD_TARANIS_X7_ACCESS:
return 0x3678746F;
case BOARD_TARANIS_X9E:
return 0x3578746F;
@@ -81,16 +77,14 @@ uint32_t Boards::getFourCC(Type board)
case BOARD_AR9X:
case BOARD_9XRPRO:
return 0x3278746F;
case BOARD_MEGA2560:
case BOARD_GRUVIN9X:
return 0x3178746F;
case BOARD_9X_M64:
case BOARD_9X_M128:
return 0;
case BOARD_JUMPER_T12:
return 0x3D78746F;
case BOARD_JUMPER_T16:
return 0x3F78746F;
case BOARD_JUMPER_T18:
return 0x4078746F;
case BOARD_RADIOMASTER_TX16S:
return 0x3878746F;
case BOARD_UNKNOWN:
break;
}
@@ -101,13 +95,6 @@ uint32_t Boards::getFourCC(Type board)
int Boards::getEEpromSize(Board::Type board)
{
switch (board) {
case BOARD_9X_M64:
return EESIZE_STOCK;
case BOARD_9X_M128:
return EESIZE_M128;
case BOARD_MEGA2560:
case BOARD_GRUVIN9X:
return EESIZE_GRUVIN9X;
case BOARD_SKY9X:
return EESIZE_SKY9X;
case BOARD_9XRPRO:
@@ -116,6 +103,7 @@ int Boards::getEEpromSize(Board::Type board)
case BOARD_TARANIS_XLITES:
case BOARD_TARANIS_XLITE:
case BOARD_TARANIS_X7:
case BOARD_TARANIS_X7_ACCESS:
case BOARD_TARANIS_X9LITE:
case BOARD_TARANIS_X9LITES:
case BOARD_TARANIS_X9D:
@@ -130,6 +118,8 @@ int Boards::getEEpromSize(Board::Type board)
case BOARD_X10:
case BOARD_X10_EXPRESS:
case BOARD_JUMPER_T16:
case BOARD_JUMPER_T18:
case BOARD_RADIOMASTER_TX16S:
return 0;
}
@@ -139,13 +129,6 @@ int Boards::getEEpromSize(Board::Type board)
int Boards::getFlashSize(Type board)
{
switch (board) {
case BOARD_9X_M64:
return FSIZE_STOCK;
case BOARD_9X_M128:
return FSIZE_M128;
case BOARD_MEGA2560:
case BOARD_GRUVIN9X:
return FSIZE_GRUVIN9X;
case BOARD_SKY9X:
return FSIZE_SKY9X;
case BOARD_9XRPRO:
@@ -154,6 +137,7 @@ int Boards::getFlashSize(Type board)
case BOARD_TARANIS_XLITES:
case BOARD_TARANIS_XLITE:
case BOARD_TARANIS_X7:
case BOARD_TARANIS_X7_ACCESS:
case BOARD_TARANIS_X9LITE:
case BOARD_TARANIS_X9LITES:
case BOARD_TARANIS_X9D:
@@ -166,6 +150,8 @@ int Boards::getFlashSize(Type board)
case BOARD_X10:
case BOARD_X10_EXPRESS:
case BOARD_JUMPER_T16:
case BOARD_JUMPER_T18:
case BOARD_RADIOMASTER_TX16S:
return FSIZE_HORUS;
case BOARD_UNKNOWN:
return FSIZE_MAX;
@@ -281,7 +267,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
return 2;
else if (IS_TARANIS_X9E(board))
return 4;
else if (IS_HORUS_X10(board) || IS_JUMPER_T16(board))
else if (IS_HORUS_X10(board) || IS_FAMILY_T16(board))
return 5;
else if (IS_HORUS_X12S(board))
return 3;
@@ -297,13 +283,13 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
case Sliders:
if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board))
return 4;
else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board))
else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board))
return 2;
else
return 0;
case MouseAnalogs:
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
return 2;
else
return 0;
@@ -326,8 +312,10 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
case Switches:
if (IS_TARANIS_X9E(board))
return 18;
else if (IS_TARANIS_X9LITE(board))
else if (board == Board::BOARD_TARANIS_X9LITE)
return 5;
else if (board == Board::BOARD_TARANIS_X9LITES)
return 7;
else if (IS_TARANIS_X7(board))
return 8;
else if (IS_JUMPER_T12(board))
@@ -338,7 +326,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
return 9;
else if (IS_TARANIS(board))
return 8;
else if (IS_HORUS(board))
else if (IS_FAMILY_HORUS_OR_T16(board))
return 10;
else
return 7;
@@ -358,7 +346,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability)
return 9;
case NumTrims:
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
return 6;
else
return 4;
@@ -403,7 +391,7 @@ QString Boards::getAnalogInputName(Board::Type board, int index)
index -= getCapability(board, Board::Sticks);
if (IS_9X(board) || IS_2560(board) || IS_SKY9X(board)) {
if (IS_SKY9X(board)) {
const QString pots[] = {
"P1",
"P2",
@@ -452,8 +440,8 @@ QString Boards::getAnalogInputName(Board::Type board, int index)
"S1",
"6P",
"S2",
"S3",
"S4",
"L1",
"L2",
"LS",
"RS",
"JSx",
@@ -462,7 +450,7 @@ QString Boards::getAnalogInputName(Board::Type board, int index)
if (index < DIM(pots))
return pots[index];
}
else if (IS_HORUS_X10(board) || IS_JUMPER_T16(board)) {
else if (IS_HORUS_X10(board) || IS_FAMILY_T16(board)) {
const QString pots[] = {
"S1",
"6P",
@@ -487,16 +475,10 @@ bool Boards::isBoardCompatible(Type board1, Type board2)
QString Boards::getBoardName(Board::Type board)
{
switch (board) {
case BOARD_9X_M64:
return "9X";
case BOARD_9X_M128:
return "9X128";
case BOARD_GRUVIN9X:
return "Gruvin9x";
case BOARD_MEGA2560:
return "MEGA2560";
case BOARD_TARANIS_X7:
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:
@@ -529,6 +511,10 @@ QString Boards::getBoardName(Board::Type board)
return "Horus X10/X10S Express";
case BOARD_JUMPER_T16:
return "Jumper T16";
case BOARD_JUMPER_T18:
return "Jumper T18";
case BOARD_RADIOMASTER_TX16S:
return "Radiomaster TX16S";
default:
return tr("Unknown");
}
+48 -34
View File
@@ -32,14 +32,11 @@ namespace Board {
enum Type
{
BOARD_UNKNOWN = -1,
BOARD_9X_M64 = 0,
BOARD_9X_M128,
BOARD_MEGA2560,
BOARD_GRUVIN9X,
BOARD_SKY9X,
BOARD_9XRPRO,
BOARD_AR9X,
BOARD_TARANIS_X7,
BOARD_TARANIS_X7_ACCESS,
BOARD_TARANIS_X9D,
BOARD_TARANIS_X9DP,
BOARD_TARANIS_X9DP_2019,
@@ -53,9 +50,11 @@ namespace Board {
BOARD_TARANIS_X9LITES,
BOARD_JUMPER_T12,
BOARD_JUMPER_T16,
BOARD_RADIOMASTER_TX16S,
BOARD_JUMPER_T18,
};
constexpr int BOARD_TYPE_MAX = BOARD_JUMPER_T16 ;
constexpr int BOARD_TYPE_MAX = BOARD_JUMPER_T18;
enum PotType
{
@@ -189,26 +188,6 @@ class Boards
// temporary aliases for transition period, use Boards class instead.
#define getBoardCapability(b__, c__) Boards::getCapability(b__, c__)
inline bool IS_9X(Board::Type board)
{
return board == Board::BOARD_9X_M64 || board == Board::BOARD_9X_M128;
}
inline bool IS_STOCK(Board::Type board)
{
return board == Board::BOARD_9X_M64;
}
inline bool IS_M128(Board::Type board)
{
return board == Board::BOARD_9X_M128;
}
inline bool IS_2560(Board::Type board)
{
return board == Board::BOARD_GRUVIN9X || board == Board::BOARD_MEGA2560;
}
inline bool IS_SKY9X(Board::Type board)
{
return board == Board::BOARD_SKY9X || board == Board::BOARD_9XRPRO || board == Board::BOARD_AR9X;
@@ -229,6 +208,21 @@ inline bool IS_JUMPER_T16(Board::Type board)
return board == Board::BOARD_JUMPER_T16;
}
inline bool IS_JUMPER_T18(Board::Type board)
{
return board == Board::BOARD_JUMPER_T18;
}
inline bool IS_RADIOMASTER_TX16S(Board::Type board)
{
return board == Board::BOARD_RADIOMASTER_TX16S;
}
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_TARANIS_XLITE(Board::Type board)
{
return board == Board::BOARD_TARANIS_XLITE || board == Board::BOARD_TARANIS_XLITES;
@@ -241,7 +235,12 @@ inline bool IS_TARANIS_XLITES(Board::Type board)
inline bool IS_TARANIS_X7(Board::Type board)
{
return board == Board::BOARD_TARANIS_X7;
return board == Board::BOARD_TARANIS_X7 || board == Board::BOARD_TARANIS_X7_ACCESS;
}
inline bool IS_TARANIS_X7_ACCESS(Board::Type board)
{
return board == Board::BOARD_TARANIS_X7_ACCESS;
}
inline bool IS_TARANIS_X9LITE(Board::Type board)
@@ -249,6 +248,11 @@ inline bool IS_TARANIS_X9LITE(Board::Type board)
return board == Board::BOARD_TARANIS_X9LITE || board == Board::BOARD_TARANIS_X9LITES;
}
inline bool IS_TARANIS_X9LITES(Board::Type board)
{
return board == Board::BOARD_TARANIS_X9LITES;
}
inline bool IS_TARANIS_X9(Board::Type board)
{
return board==Board::BOARD_TARANIS_X9D || board==Board::BOARD_TARANIS_X9DP || board==Board::BOARD_TARANIS_X9DP_2019 || board==Board::BOARD_TARANIS_X9E;
@@ -289,19 +293,24 @@ inline bool IS_HORUS_X12S(Board::Type board)
return board == Board::BOARD_HORUS_X12S;
}
inline bool IS_HORUS(Board::Type board)
inline bool IS_FAMILY_HORUS(Board::Type board)
{
return IS_HORUS_X12S(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board);
return IS_HORUS_X12S(board) || IS_HORUS_X10(board);
}
inline bool IS_FAMILY_HORUS_OR_T16(Board::Type board)
{
return IS_FAMILY_HORUS(board) || IS_FAMILY_T16(board);
}
inline bool IS_HORUS_OR_TARANIS(Board::Type board)
{
return IS_HORUS(board) || IS_TARANIS(board);
return IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS(board);
}
inline bool IS_STM32(Board::Type board)
{
return IS_TARANIS(board) || IS_HORUS(board);
return IS_TARANIS(board) || IS_FAMILY_HORUS_OR_T16(board);
}
inline bool IS_ARM(Board::Type board)
@@ -311,7 +320,7 @@ inline bool IS_ARM(Board::Type board)
inline bool HAS_LARGE_LCD(Board::Type board)
{
return IS_HORUS(board) || IS_TARANIS_X9(board);
return IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS_X9(board);
}
inline bool HAS_EXTERNAL_ANTENNA(Board::Type board)
@@ -319,10 +328,15 @@ inline bool HAS_EXTERNAL_ANTENNA(Board::Type board)
return (board == Board::BOARD_X10 || board == Board::BOARD_HORUS_X12S || (IS_TARANIS_XLITE(board) && !IS_TARANIS_XLITES(board)));
}
inline bool IS_ACCESS_RADIO(Board::Type board, QString &id)
inline bool IS_TARANIS_X9DP_2019(Board::Type board)
{
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || board == Board::BOARD_TARANIS_X9DP_2019 || board == Board::BOARD_X10_EXPRESS ||
(IS_HORUS(board) && id.contains("internalaccess")));
return (board == Board::BOARD_TARANIS_X9DP_2019);
}
inline bool IS_ACCESS_RADIO(Board::Type board, const QString & id)
{
return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || board == Board::BOARD_TARANIS_X9DP_2019 || board == Board::BOARD_X10_EXPRESS || IS_TARANIS_X7_ACCESS(board) ||
(IS_FAMILY_HORUS_OR_T16(board) && id.contains("internalaccess")));
}
#endif // _BOARDS_H_
+1
View File
@@ -50,6 +50,7 @@ class CurveReference {
int value;
QString toString(const ModelData * model = NULL, bool verbose = true) const;
bool isSet() const { return type != CURVE_REF_DIFF || value != 0; }
};
#endif // CURVEREFERENCE_H
+7 -14
View File
@@ -55,6 +55,8 @@ QString CustomFunctionData::funcToString(const ModelData * model) const
return tr("Trainer THR");
else if (func == FuncTrainerAIL)
return tr("Trainer AIL");
else if (func == FuncTrainerChannels)
return tr("Trainer Channels");
else if (func == FuncInstantTrim)
return tr("Instant Trim");
else if (func == FuncPlaySound)
@@ -110,13 +112,10 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox
{
int val = 0;
Firmware * firmware = Firmware::getCurrentVariant();
Board::Type board = firmware->getBoard();
b->addItem(tr("Timer1"), val++);
b->addItem(tr("Timer2"), val++);
if (IS_ARM(board)) {
b->addItem( tr("Timer3"), val++);
}
b->addItem( tr("Timer3"), val++);
b->addItem(tr("Flight"), val++);
b->addItem(tr("Telemetry"), val++);
int reCount = firmware->getCapability(RotaryEncoders);
@@ -130,7 +129,7 @@ void CustomFunctionData::populateResetParams(const ModelData * model, QComboBox
if ((int)value < b->count()) {
b->setCurrentIndex(value);
}
if (model && IS_ARM(board)) {
if (model) {
for (unsigned i=0; i<CPN_MAX_SENSORS; ++i) {
if (model->sensorData[i].isAvailable()) {
RawSource item = RawSource(SOURCE_TYPE_TELEMETRY, 3*i);
@@ -208,14 +207,8 @@ QString CustomFunctionData::paramToString(const ModelData * model) const
case FUNC_ADJUST_GVAR_INCDEC:
float val;
QString unit;
if (IS_ARM(getCurrentBoard())) {
val = param * model->gvarData[func - FuncAdjustGV1].multiplierGet();
unit = model->gvarData[func - FuncAdjustGV1].unitToString();
}
else {
val = param;
unit = "";
}
val = param * model->gvarData[func - FuncAdjustGV1].multiplierGet();
unit = model->gvarData[func - FuncAdjustGV1].unitToString();
return QString("Increment: %1%2").arg(val).arg(unit);
}
}
@@ -231,7 +224,7 @@ QString CustomFunctionData::repeatToString() const
return "";
}
else {
unsigned int step = IS_ARM(getCurrentBoard()) ? 1 : 10;
unsigned int step = 1;
return tr("repeat(%1s)").arg(step*repeatParam);
}
}
@@ -41,6 +41,7 @@ enum AssignFunc {
FuncTrainerELE,
FuncTrainerTHR,
FuncTrainerAIL,
FuncTrainerChannels,
FuncInstantTrim,
FuncPlaySound,
FuncPlayHaptic,
@@ -75,10 +75,7 @@ void EEPROMInterface::showEepromErrors(QWidget *parent, const QString &title, co
if (errors.test(UNSUPPORTED_NEWER_VERSION)) { errorsList << tr("- Eeprom is from a newer version of OpenTX"); }
if (errors.test(NOT_OPENTX)) { errorsList << tr("- Eeprom is not from OpenTX"); }
if (errors.test(NOT_TH9X)) { errorsList << tr("- Eeprom is not from Th9X"); }
if (errors.test(NOT_GRUVIN9X)) { errorsList << tr("- Eeprom is not from Gruvin9X"); }
if (errors.test(NOT_ERSKY9X)) { errorsList << tr("- Eeprom is not from ErSky9X"); }
if (errors.test(NOT_ER9X)) { errorsList << tr("- Eeprom is not from Er9X"); }
if (errors.test(WRONG_SIZE)) { errorsList << tr("- Eeprom size is invalid"); }
if (errors.test(WRONG_FILE_SYSTEM)) { errorsList << tr("- Eeprom file system is invalid"); }
if (errors.test(UNKNOWN_BOARD)) { errorsList << tr("- Eeprom is from a unknown board"); }
+4 -4
View File
@@ -100,6 +100,8 @@ enum Capability {
GvarsName,
NoTelemetryProtocol,
TelemetryCustomScreens,
TelemetryCustomScreensBars,
TelemetryCustomScreensLines,
TelemetryCustomScreensFieldsPerLine,
TelemetryMaxMultiplier,
HasVario,
@@ -149,7 +151,8 @@ enum Capability {
DangerousFunctions,
HasModelCategories,
HasSwitchableJack,
PwrButtonPress
PwrButtonPress,
Sensors
};
class EEPROMInterface
@@ -232,10 +235,7 @@ enum EepromLoadErrors {
WRONG_SIZE,
WRONG_FILE_SYSTEM,
NOT_OPENTX,
NOT_TH9X,
NOT_GRUVIN9X,
NOT_ERSKY9X,
NOT_ER9X,
UNKNOWN_BOARD,
WRONG_BOARD,
BACKUP_NOT_SUPPORTED,
+21 -15
View File
@@ -88,7 +88,7 @@ GeneralSettings::GeneralSettings()
vBatMin = -5; //8,5V
vBatMax = -5; //11,5V
}
else if (IS_TARANIS_XLITE(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board)) {
else if (IS_TARANIS_XLITE(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board)) {
// Lipo 2S
vBatWarn = 66;
vBatMin = -23; // 6.7V
@@ -106,19 +106,25 @@ GeneralSettings::GeneralSettings()
backlightMode = 3; // keys and sticks
// backlightBright = 0; // 0 = 100%
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
backlightOffBright = 20;
}
if (IS_ARM(board)) {
speakerVolume = 12;
}
speakerVolume = 12;
if (IS_HORUS(board)) {
strcpy(bluetoothName, "Horus");
if (IS_JUMPER_T16(board))
strcpy(bluetoothName, "t16");
else if (IS_FAMILY_HORUS_OR_T16(board)) {
strcpy(bluetoothName, "horus");
}
else if (IS_TARANIS_X9E(board) || IS_TARANIS_SMALL(board)) {
strcpy(bluetoothName, "Taranis");
strcpy(bluetoothName, "taranis");
}
for (uint8_t i = 0; i < 4; i++) {
trainer.mix[i].mode = 2; // replace (:=)
trainer.mix[i].src = i;
trainer.mix[i].weight = 100;
}
templateSetup = g.profile[g.sessionId()].channelOrder();
@@ -234,7 +240,7 @@ void GeneralSettings::setDefaultControlTypes(Board::Type board)
}
// TODO: move to Boards, like with switches
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
potConfig[0] = Board::POT_WITH_DETENT;
potConfig[1] = Board::POT_MULTIPOS_SWITCH;
potConfig[2] = Board::POT_WITH_DETENT;
@@ -267,7 +273,7 @@ void GeneralSettings::setDefaultControlTypes(Board::Type board)
sliderConfig[2] = Board::SLIDER_WITH_DETENT;
sliderConfig[3] = Board::SLIDER_WITH_DETENT;
}
else if (IS_TARANIS_X9(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board)) {
else if (IS_TARANIS_X9(board) || IS_HORUS_X10(board) || IS_FAMILY_T16(board)) {
sliderConfig[0] = Board::SLIDER_WITH_DETENT;
sliderConfig[1] = Board::SLIDER_WITH_DETENT;
}
@@ -311,27 +317,27 @@ void GeneralSettings::convert(RadioDataConversionState & cstate)
// SE and SG are skipped on X7 board
if (IS_TARANIS_X7(cstate.toType)) {
if (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType)) {
if (IS_TARANIS_X9(cstate.fromType) || IS_FAMILY_HORUS_OR_T16(cstate.fromType)) {
strncpy(switchName[4], switchName[5], sizeof(switchName[4]));
strncpy(switchName[5], switchName[7], sizeof(switchName[5]));
}
}
else if (IS_TARANIS_X7(cstate.fromType)) {
if (IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) {
if (IS_TARANIS_X9(cstate.toType) || IS_FAMILY_HORUS_OR_T16(cstate.toType)) {
strncpy(switchName[5], switchName[4], sizeof(switchName[5]));
strncpy(switchName[7], switchName[5], sizeof(switchName[7]));
}
}
if (IS_JUMPER_T12(cstate.toType)) {
if (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType)) {
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)) {
if (IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) {
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]));
}
@@ -347,7 +353,7 @@ void GeneralSettings::convert(RadioDataConversionState & cstate)
strncpy(sliderName[3], sliderName[1], sizeof(sliderName[3]));
}
if (IS_HORUS(cstate.toType)) {
if (IS_FAMILY_HORUS_OR_T16(cstate.toType)) {
// 6P switch is only on Horus (by default)
if (cstate.fromBoard.getCapability(Board::FactoryInstalledPots) == 2) {
strncpy(potName[2], potName[1], sizeof(potName[2]));
@@ -142,6 +142,7 @@ class GeneralSettings {
unsigned int countryCode;
bool jitterFilter;
bool rtcCheckDisable;
bool keysBacklight;
unsigned int imperial;
char ttsLanguage[2+1];
int beepVolume;
+5
View File
@@ -90,3 +90,8 @@ float GVarData::getMaxPrec() const
{
return getMax() * multiplierGet();
}
bool GVarData::isEmpty() const
{
return (name[0] == '\0' && min == 0 && max == 0 && (!popup) && prec == 0 && unit == 0);
}
+2 -1
View File
@@ -43,7 +43,7 @@ class GVarData {
GVAR_PREC_MUL1
};
char name[GVAR_NAME_LEN+1];
char name[GVAR_NAME_LEN + 1];
int min;
int max;
bool popup;
@@ -62,6 +62,7 @@ class GVarData {
int getMax() const;
float getMinPrec() const;
float getMaxPrec() const;
bool isEmpty() const;
};
+68 -13
View File
@@ -35,6 +35,10 @@ void ExpoData::convert(RadioDataConversionState & cstate)
swtch.convert(cstate);
}
bool ExpoData::isEmpty() const
{
return (chn == 0 && mode == INPUT_MODE_NONE);
}
/*
* MixData
@@ -48,6 +52,10 @@ void MixData::convert(RadioDataConversionState & cstate)
swtch.convert(cstate);
}
bool MixData::isEmpty() const
{
return (destCh == 0);
}
/*
* LimitData
@@ -87,17 +95,16 @@ void LimitData::clear()
bool LimitData::isEmpty() const
{
return (min == -1000 && max == 1000 && !revert && !offset && !ppmCenter && !symetrical && name[0] == '\0');
return (min == -1000 && max == 1000 && !revert && !offset && !ppmCenter && !symetrical && name[0] == '\0' && !curve.isSet());
}
/*
* CurveData
*/
CurveData::CurveData()
{
clear(5);
clear();
}
void CurveData::clear(int count)
@@ -126,22 +133,20 @@ QString CurveData::nameToString(const int idx) const
* FlightModeData
*/
void FlightModeData::clear(const int phase)
void FlightModeData::clear(const int phaseIdx)
{
memset(reinterpret_cast<void *>(this), 0, sizeof(FlightModeData));
if (phase != 0) {
for (int idx=0; idx<CPN_MAX_GVARS; idx++) {
gvars[idx] = 1025;
}
for (int idx=0; idx<CPN_MAX_ENCODERS; idx++) {
rotaryEncoders[idx] = 1025;
}
for (int i = 0; i < CPN_MAX_GVARS; i++) {
gvars[i] = linkedGVarFlightModeZero(phaseIdx);
}
for (int i = 0; i < CPN_MAX_ENCODERS; i++) {
rotaryEncoders[i] = linkedREncFlightModeZero(phaseIdx);
}
}
QString FlightModeData::nameToString(int index) const
QString FlightModeData::nameToString(int phaseIdx) const
{
return RadioData::getElementName(tr("FM"), index, name); // names are zero-based, FM0, FM1, etc
return RadioData::getElementName(tr("FM"), phaseIdx, name); // names are zero-based, FM0, FM1, etc
}
void FlightModeData::convert(RadioDataConversionState & cstate)
@@ -150,3 +155,53 @@ void FlightModeData::convert(RadioDataConversionState & cstate)
cstate.setSubComp(nameToString(cstate.subCompIdx));
swtch.convert(cstate);
}
bool FlightModeData::isEmpty(int phaseIdx) const
{
if (name[0] != '\0' || swtch.isSet() || fadeIn != 0 || fadeOut != 0)
return false;
for (int i = 0; i < CPN_MAX_TRIMS; i++) {
if (trim[i] != 0 || trimRef[i] != 0 || trimMode[i] != 0)
return false;
}
for (int i = 0; i < CPN_MAX_GVARS; i++) {
if (!isGVarEmpty(phaseIdx, i))
return false;
}
for (int i = 0; i < CPN_MAX_ENCODERS; i++) {
if (!isREncEmpty(phaseIdx, i))
return false;
}
return true;
}
bool FlightModeData::isGVarEmpty(int phaseIdx, int gvIdx) const
{
if ((phaseIdx == 0 && gvars[gvIdx] == 0) || (phaseIdx != 0 && gvars[gvIdx] == linkedGVarFlightModeZero(phaseIdx)))
return true;
return false;
}
bool FlightModeData::isREncEmpty(int phaseIdx, int reIdx) const
{
if ((phaseIdx == 0 && rotaryEncoders[reIdx] == 0) || (phaseIdx != 0 && rotaryEncoders[reIdx] == linkedREncFlightModeZero(phaseIdx)))
return true;
return false;
}
int FlightModeData::linkedFlightModeZero(int phaseIdx, int maxOwnValue) const
{
if (phaseIdx == 0)
return 0;
return maxOwnValue + 1;
}
int FlightModeData::linkedGVarFlightModeZero(int phaseIdx) const
{
return linkedFlightModeZero(phaseIdx, GVAR_MAX_VALUE);
}
int FlightModeData::linkedREncFlightModeZero(int phaseIdx) const
{
return linkedFlightModeZero(phaseIdx, RENC_MAX_VALUE);
}
+26 -7
View File
@@ -37,6 +37,8 @@ enum InputMode {
INPUT_MODE_BOTH
};
#define EXPODATA_NAME_LEN 10
class ExpoData {
Q_DECLARE_TR_FUNCTIONS(ExpoData)
@@ -52,9 +54,10 @@ class ExpoData {
int offset;
CurveReference curve;
int carryTrim;
char name[10+1];
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 {
@@ -90,8 +93,11 @@ class MixData {
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)
@@ -103,7 +109,8 @@ class LimitData {
int offset;
int ppmCenter;
bool symetrical;
char name[6+1];
int failsafe;
char name[LIMITDATA_NAME_LEN + 1];
CurveReference curve;
QString minToString() const;
QString maxToString() const;
@@ -120,6 +127,8 @@ class CurvePoint {
int8_t y;
};
#define CURVEDATA_NAME_LEN 6
class CurveData {
Q_DECLARE_TR_FUNCTIONS(CurveData)
@@ -131,7 +140,7 @@ class CurveData {
};
CurveData();
void clear(int count);
void clear(int count = 5);
bool isEmpty() const;
QString nameToString(const int idx) const;
@@ -139,9 +148,13 @@ class CurveData {
bool smooth;
int count;
CurvePoint points[CPN_MAX_POINTS];
char name[6+1];
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)
@@ -151,14 +164,20 @@ class FlightModeData {
int trimRef[CPN_MAX_TRIMS];
int trim[CPN_MAX_TRIMS];
RawSwitch swtch;
char name[10+1];
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 phase);
QString nameToString(int index) const;
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 {
File diff suppressed because it is too large Load Diff
+106 -6
View File
@@ -41,13 +41,10 @@ class RadioDataConversionState;
class RSSIAlarmData {
public:
RSSIAlarmData() { clear(); }
unsigned int level[2]; // AVR Only
int warning;
int critical;
bool disabled;
void clear() {
this->level[0] = 2;
this->level[1] = 3;
this->warning = 45;
this->critical = 42;
this->disabled = false;
@@ -76,6 +73,8 @@ class TimerData {
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
@@ -128,6 +127,8 @@ enum TrainerMode {
TRAINER_MODE_MULTI
};
#define INPUT_NAME_LEN 4
class ModelData {
Q_DECLARE_TR_FUNCTIONS(ModelData)
@@ -170,7 +171,7 @@ class ModelData {
MixData mixData[CPN_MAX_MIXERS];
LimitData limitData[CPN_MAX_CHNOUT];
char inputNames[CPN_MAX_INPUTS][4+1];
char inputNames[CPN_MAX_INPUTS][INPUT_NAME_LEN+1];
ExpoData expoData[CPN_MAX_EXPOS];
CurveData curves[CPN_MAX_CURVES];
@@ -219,11 +220,23 @@ class ModelData {
void setTrimValue(int phaseIdx, int trimIdx, int value);
bool isGVarLinked(int phaseIdx, int gvarIdx);
int getGVarFieldValue(int phaseIdx, int gvarIdx);
float getGVarFieldValuePrec(int phaseIdx, int gvarIdx);
bool isGVarLinkedCircular(int phaseIdx, int gvarIdx);
int getGVarValue(int phaseIdx, int gvarIdx);
float getGVarValuePrec(int phaseIdx, int gvarIdx);
int getGVarFlightModeIndex(const int phaseIdx, const int gvarIdx);
void setGVarFlightModeIndexToValue(const int phaseIdx, const int gvarIdx, const int useFmIdx);
bool isREncLinked(int phaseIdx, int reIdx);
bool isREncLinkedCircular(int phaseIdx, int reIdx);
int getREncValue(int phaseIdx, int reIdx);
int getREncFlightModeIndex(const int phaseIdx, const int reIdx);
void setREncFlightModeIndexToValue(const int phaseIdx, const int reIdx, const int useFmIdx);
ModelData removeGlobalVars();
int linkedFlightModeIndexToValue(const int phaseIdx, const int useFmIdx, const int maxOwnValue);
int linkedFlightModeValueToIndex(const int phaseIdx, const int val, const int maxOwnValue);
void clearMixes();
void clearInputs();
@@ -231,8 +244,95 @@ class ModelData {
bool isAvailable(const RawSwitch & swtch) const;
enum ReferenceUpdateAction {
REF_UPD_ACT_CLEAR,
REF_UPD_ACT_SHIFT,
REF_UPD_ACT_SWAP,
};
enum ReferenceUpdateType {
REF_UPD_TYPE_CHANNEL,
REF_UPD_TYPE_CURVE,
REF_UPD_TYPE_FLIGHT_MODE,
REF_UPD_TYPE_GLOBAL_VARIABLE,
REF_UPD_TYPE_INPUT,
REF_UPD_TYPE_LOGICAL_SWITCH,
REF_UPD_TYPE_SCRIPT,
REF_UPD_TYPE_SENSOR,
REF_UPD_TYPE_TIMER,
};
struct UpdateReferenceParams
{
ReferenceUpdateType type;
ReferenceUpdateAction action;
int index1;
int index2;
int shift;
UpdateReferenceParams() {}
UpdateReferenceParams(ReferenceUpdateType t, ReferenceUpdateAction a, int i1, int i2 = 0, int s = 0) :
type(t), action(a), index1(i1), index2(i2), shift(s) {}
};
int updateAllReferences(const ReferenceUpdateType type, const ReferenceUpdateAction action, const int index1, const int index2 = 0, const int shift = 0);
bool isExpoParent(const int index);
bool isExpoChild(const int index);
bool hasExpoChildren(const int index);
bool hasExpoSiblings(const int index);
void removeMix(const int idx);
protected:
void removeGlobalVar(int & var);
private:
QVector<UpdateReferenceParams> *updRefList = nullptr;
struct UpdateReferenceInfo
{
ReferenceUpdateType type;
ReferenceUpdateAction action;
int index1;
int index2;
int shift;
int updcnt;
int maxindex;
RawSourceType srcType;
RawSwitchType swtchType;
};
UpdateReferenceInfo updRefInfo;
int updateReference();
void appendUpdateReferenceParams(const ReferenceUpdateType type, const ReferenceUpdateAction action, const int index1, const int index2 = 0, const int shift = 0);
template <class R, typename T>
void updateTypeIndexRef(R & curref, const T type, const int idxAdj = 0, const bool defClear = true, const int defType = 0, const int defIndex = 0);
template <class R, typename T>
void updateTypeValueRef(R & curref, const T type, const int idxAdj = 0, const bool defClear = true, const int defType = 0, const int defValue = 0);
void updateAdjustRef(int & adj);
void updateAssignFunc(CustomFunctionData * cfd);
void updateCurveRef(CurveReference & crv);
void updateDestCh(MixData * md);
void updateLimitCurveRef(CurveReference & crv);
void updateFlightModeFlags(unsigned int & flags);
void updateTelemetryRef(unsigned int & idx);
void updateModuleFailsafes(ModuleData * md);
inline void updateSourceRef(RawSource & src) { updateTypeIndexRef<RawSource, RawSourceType>(src, updRefInfo.srcType); }
inline void updateSwitchRef(RawSwitch & swtch) { updateTypeIndexRef<RawSwitch, RawSwitchType>(swtch, updRefInfo.swtchType, 1); }
inline void updateTimerMode(RawSwitch & swtch) { updateTypeIndexRef<RawSwitch, RawSwitchType>(swtch, updRefInfo.swtchType, 1, false, (int)SWITCH_TYPE_TIMER_MODE, 0); }
inline void updateSourceIntRef(int & value)
{
RawSource src = RawSource(value);
updateTypeIndexRef<RawSource, RawSourceType>(src, updRefInfo.srcType);
if (value != src.toValue())
value = src.toValue();
}
inline void updateSwitchIntRef(int & value)
{
RawSwitch swtch = RawSwitch(value);
updateTypeIndexRef<RawSwitch, RawSwitchType>(swtch, updRefInfo.swtchType, 1);
if (value != swtch.toValue())
value = swtch.toValue();
}
};
#endif // MODELDATA_H
+82 -13
View File
@@ -21,6 +21,7 @@
#include "moduledata.h"
#include "eeprominterface.h"
#include "multiprotocols.h"
#include "afhds3.h"
#include "radiodataconversionstate.h"
void ModuleData::convert(RadioDataConversionState & cstate)
@@ -87,7 +88,6 @@ QString ModuleData::rfProtocolToString() const
switch (protocol) {
case PULSES_MULTIMODULE:
return Multiprotocols::protocolToString((int)multi.rfProtocol);
default:
return CPN_STR_UNKNOWN_ITEM;
}
@@ -108,10 +108,10 @@ QString ModuleData::subTypeToString(int type) const
switch (protocol) {
case PULSES_MULTIMODULE:
return Multiprotocols::subTypeToString((int)multi.rfProtocol, (unsigned)type);
case PULSES_PXX_R9M:
return CHECK_IN_ARRAY(strings, type);
case PULSES_AFHDS3:
return Afhds3Data::protocolToString(type);
default:
return CPN_STR_UNKNOWN_ITEM;
}
@@ -119,8 +119,8 @@ QString ModuleData::subTypeToString(int type) const
QString ModuleData::powerValueToString(Firmware * fw) const
{
const QStringList & strRef = powerValueStrings(subType, fw);
return strRef.value(pxx.power, CPN_STR_UNKNOWN_ITEM);
const QStringList & strRef = powerValueStrings((enum PulsesProtocol)protocol, subType, fw);
return strRef.value(protocol == PULSES_AFHDS3 ? afhds3.rfPower : pxx.power, CPN_STR_UNKNOWN_ITEM);
}
// static
@@ -159,14 +159,15 @@ QString ModuleData::protocolToString(unsigned protocol)
"FrSky ACCESS R9M 2019",
"FrSky ACCESS R9M Lite",
"FrSky ACCESS R9M Lite Pro",
"FrSky XJT lite (D16)", "FrSky XJT lite (D8)", "FrSky XJT lite (LR12)"
"FrSky XJT lite (D16)", "FrSky XJT lite (D8)", "FrSky XJT lite (LR12)",
"AFHDS3"
};
return CHECK_IN_ARRAY(strings, protocol);
}
// static
QStringList ModuleData::powerValueStrings(int subType, Firmware * fw)
QStringList ModuleData::powerValueStrings(enum PulsesProtocol protocol, int subType, Firmware * fw)
{
static const QStringList strings[] = {
{ tr("10mW - 16CH"), tr("100mW - 16CH"), tr("500mW - 16CH"), tr("Auto <= 1W - 16CH") }, // full-size FCC
@@ -174,10 +175,78 @@ QStringList ModuleData::powerValueStrings(int subType, Firmware * fw)
{ tr("100mW - 16CH") }, // mini FCC
{ tr("25mW - 8CH"), tr("25mW - 16CH"), tr("100mW - 16CH (no telemetry)") } // mini EU
};
int strIdx = 0;
if (subType == MODULE_SUBTYPE_R9M_EU)
strIdx += 1;
if (fw->getCapability(HasModuleR9MMini))
strIdx += 2;
return strings[strIdx];
static const QStringList afhds3Strings = {
tr("25 mW"), tr("100 mW"), tr("500 mW"), tr("1 W"), tr("2 W")
};
switch(protocol) {
case PULSES_AFHDS3:
return afhds3Strings;
default:
int strIdx = 0;
if (subType == MODULE_SUBTYPE_R9M_EU)
strIdx += 1;
if (fw->getCapability(HasModuleR9MMini))
strIdx += 2;
return strings[strIdx];
}
}
bool ModuleData::hasFailsafes(Firmware * fw) const
{
return fw->getCapability(HasFailsafe) && (
protocol == PULSES_ACCESS_ISRM ||
protocol == PULSES_ACCST_ISRM_D16 ||
protocol == PULSES_PXX_XJT_X16 ||
protocol == PULSES_PXX_R9M ||
protocol == PULSES_ACCESS_R9M ||
protocol == PULSES_ACCESS_R9M_LITE ||
protocol == PULSES_ACCESS_R9M_LITE_PRO ||
protocol == PULSES_XJT_LITE_X16 ||
protocol == PULSES_MULTIMODULE ||
protocol == PULSES_AFHDS3
);
}
int ModuleData::getMaxChannelCount()
{
switch (protocol) {
case PULSES_ACCESS_ISRM:
return 24;
case PULSES_PXX_R9M:
case PULSES_ACCESS_R9M:
case PULSES_ACCESS_R9M_LITE:
case PULSES_ACCESS_R9M_LITE_PRO:
case PULSES_ACCST_ISRM_D16:
case PULSES_XJT_LITE_X16:
case PULSES_PXX_XJT_X16:
case PULSES_CROSSFIRE:
case PULSES_SBUS:
case PULSES_PPM:
return 16;
case PULSES_XJT_LITE_LR12:
case PULSES_PXX_XJT_LR12:
return 12;
case PULSES_PXX_DJT:
case PULSES_XJT_LITE_D8:
case PULSES_PXX_XJT_D8:
return 8;
case PULSES_LP45:
case PULSES_DSM2:
case PULSES_DSMX:
return 6;
case PULSES_MULTIMODULE:
if (multi.rfProtocol == MODULE_SUBTYPE_MULTI_DSM2)
return 12;
else
return 16;
break;
case PULSES_AFHDS3:
return 18;
case PULSES_OFF:
break;
default:
break;
}
return 8;
}
+32 -5
View File
@@ -58,6 +58,7 @@ enum PulsesProtocol {
PULSES_XJT_LITE_X16,
PULSES_XJT_LITE_D8,
PULSES_XJT_LITE_LR12,
PULSES_AFHDS3,
PULSES_PROTOCOL_LAST
};
@@ -117,7 +118,23 @@ enum MultiModuleRFProtocols {
MODULE_SUBTYPE_MULTI_SCANNER,
MODULE_SUBTYPE_MULTI_FRSKYX_RX,
MODULE_SUBTYPE_MULTI_AFHDS2A_RX,
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_AFHDS2A_RX
MODULE_SUBTYPE_MULTI_HOTT,
MODULE_SUBTYPE_MULTI_FX816,
MODULE_SUBTYPE_MULTI_BAYANG_RX,
MODULE_SUBTYPE_MULTI_PELIKAN,
MODULE_SUBTYPE_MULTI_TIGER,
MODULE_SUBTYPE_MULTI_XK,
MODULE_SUBTYPE_MULTI_XN297DUMP,
MODULE_SUBTYPE_MULTI_FRSKYX2,
MODULE_SUBTYPE_MULTI_FRSKY_R9,
MODULE_SUBTYPE_MULTI_PROPEL,
MODULE_SUBTYPE_MULTI_FRSKYL,
MODULE_SUBTYPE_MULTI_SKYARTEC,
MODULE_SUBTYPE_MULTI_ESKY150V2,
MODULE_SUBTYPE_MULTI_DSM_RX,
MODULE_SUBTYPE_MULTI_JJRC345,
MODULE_SUBTYPE_MULTI_Q90C,
MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_Q90C
};
enum TrainerProtocol {
@@ -143,17 +160,20 @@ class ModuleData {
Q_DECLARE_TR_FUNCTIONS(ModuleData)
public:
ModuleData() { clear(); }
ModuleData()
{
clear();
}
unsigned int modelId;
unsigned int protocol; // type in datastructs.h
int rfProtocol; // rfProtocol in datastructs.h
unsigned int subType;
bool invertedSerial;
unsigned int channelsStart;
int channelsCount; // 0=8 channels
unsigned int failsafeMode;
int failsafeChannels[CPN_MAX_CHNOUT];
struct PPM {
int delay;
@@ -171,6 +191,11 @@ class ModuleData {
int optionValue;
} multi;
struct Afhds3 {
unsigned int rxFreq;
unsigned int rfPower;
} afhds3;
struct PXX {
unsigned int power; // 0 10 mW, 1 100 mW, 2 500 mW, 3 1W
bool receiverTelemetryOff; // false = receiver telem enabled
@@ -194,7 +219,9 @@ class ModuleData {
QString powerValueToString(Firmware * fw) const;
static QString indexToString(int index, Firmware * fw);
static QString protocolToString(unsigned protocol);
static QStringList powerValueStrings(int subType, Firmware * fw);
static QStringList powerValueStrings(enum PulsesProtocol protocol, int subType, Firmware * fw);
bool hasFailsafes(Firmware * fw) const;
int getMaxChannelCount();
};
#endif // MODULEDATA_H
+50 -19
View File
@@ -26,8 +26,8 @@
#define STR_MULTI_SUBTYPE QT_TRANSLATE_NOOP("Multiprotocols", "Subtype")
#define STR_MULTI_VIDFREQ QT_TRANSLATE_NOOP("Multiprotocols", "Video TX frequency")
#define STR_MULTI_RFTUNE QT_TRANSLATE_NOOP("Multiprotocols", "CC2500 frequency fine tune")
#define STR_MULTI_RFPOWER QT_TRANSLATE_NOOP("Multiprotocols", "RF power")
#define STR_MULTI_TELEMETRY QT_TRANSLATE_NOOP("Multiprotocols", "Telemetry")
#define STR_MULTI_RFPOWER QT_TRANSLATE_NOOP("Multiprotocols", "Radio output power")
#define STR_MULTI_SERVOFREQ QT_TRANSLATE_NOOP("Multiprotocols", "Servo output frequency")
#define STR_MULTI_OPTION QT_TRANSLATE_NOOP("Multiprotocols", "Option value")
#define STR_MULTI_FIXEDID QT_TRANSLATE_NOOP("Multiprotocols", "Fixed ID value")
@@ -39,10 +39,10 @@ static const QStringList STR_SUBTYPE_CUSTOM ({
});
static const QStringList STR_SUBTYPE_FLYSKY {"Standard", "V9x9", "V6x6", "V912", "CX20"};
static const QStringList STR_SUBTYPE_HUBSAN {"H107", "H301", "H501"};
static const QStringList STR_SUBTYPE_FRSKY {"D16", "D8", "D16 8ch", "V8", "D16 EU-LBT", "D16 EU-LBT 8ch"};
static const QStringList STR_SUBTYPE_FRSKY {"D16", "D8", "D16 8ch", "V8", "D16 EU-LBT", "D16 EU-LBT 8ch", "D8 Cloned", "D16 Cloned"};
static const QStringList STR_SUBTYPE_HISKY {"Standard", "HK310"};
static const QStringList STR_SUBTYPE_V2X2 {"Standard", "JXD506"};
static const QStringList STR_SUBTYPE_DSM {"DSM2 22ms", "DSM2 11ms", "DSMX 22ms", "DSMX 11ms"};
static const QStringList STR_SUBTYPE_V2X2 {"Standard", "JXD506", "MR101"};
static const QStringList STR_SUBTYPE_DSM {"DSM2 1F", "DSM2 2F", "DSMX 1F", "DSMX 2F"};
static const QStringList STR_SUBTYPE_DEVO {"8 Channel", "10 Channel", "12 Channel", "6 Channel", "7 Channel"};
static const QStringList STR_SUBTYPE_YD717 {"Standard", "Skywalker", "Syma X4", "XINXUN", "NIHUI"};
static const QStringList STR_SUBTYPE_KN {"WLtoys", "FeiLun"};
@@ -50,7 +50,8 @@ static const QStringList STR_SUBTYPE_SYMAX {"Standard", "Syma X5C"};
static const QStringList STR_SUBTYPE_SLT {"V1 (6 Channel)", "V2 (8 Channel)", "Q100", "Q200", "MR100"};
static const QStringList STR_SUBTYPE_CX10 {"Green", "Blue", "DM007", "-", "JC3015a", "JC3015b", "MK33041"};
static const QStringList STR_SUBTYPE_CG023 {"Standard", "YD829"};
static const QStringList STR_SUBTYPE_BAYANG {"Standard", "H8S3D", "X16 AH", "IRDRONE", "DHD D4"};
static const QStringList STR_SUBTYPE_BAYANG {"Standard", "H8S3D", "X16 AH", "IRDRONE", "DHD D4", "QX100"};
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"};
@@ -60,18 +61,32 @@ 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"};
static const QStringList STR_SUBTYPE_CABELL {"Cabell V3", "Cab V3 Telem", "-", "-", "-", "-", "Set FailSafe", "Unbind"};
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_TRAXXAS {"6519 RX"};
static const QStringList STR_SUBTYPE_WFLY {"WFR0xS"};
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"};
static const QStringList STR_SUBTYPE_V911S {"Standard", "E119"};
static const QStringList STR_SUBTYPE_GD00X {"GD V1", "GD V2"};
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_FRSKYX_RX {"D16 FCC", "D16 LBT"};
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_PROPEL {"74-Z"};
static const QStringList STR_SUBTYPE_FRSKYL {"LR12", "LR12 6-Channel"};
static const QStringList STR_SUBTYPE_ESKY150V2 {"150 V2"};
static const QStringList NO_SUBTYPE {STR_MULTI_DEFAULT};
@@ -81,22 +96,24 @@ static const QStringList NO_SUBTYPE {STR_MULTI_DEFAULT};
const Multiprotocols multiProtocols {
{MODULE_SUBTYPE_MULTI_FLYSKY, 4, false, STR_SUBTYPE_FLYSKY, nullptr},
{MODULE_SUBTYPE_MULTI_HUBSAN, 2, false, STR_SUBTYPE_HUBSAN, STR_MULTI_VIDFREQ},
{MODULE_SUBTYPE_MULTI_FRSKY, 5, false, STR_SUBTYPE_FRSKY, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_FRSKY, 7, false, STR_SUBTYPE_FRSKY, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_HISKY, 1, false, STR_SUBTYPE_HISKY, nullptr},
{MODULE_SUBTYPE_MULTI_V2X2, 1, false, STR_SUBTYPE_V2X2, nullptr},
{MODULE_SUBTYPE_MULTI_V2X2, 2, false, STR_SUBTYPE_V2X2, nullptr},
{MODULE_SUBTYPE_MULTI_DSM2, 3, false, STR_SUBTYPE_DSM, nullptr},
{MODULE_SUBTYPE_MULTI_DEVO, 4, false, STR_SUBTYPE_DEVO, STR_MULTI_FIXEDID},
{MODULE_SUBTYPE_MULTI_YD717, 4, false, STR_SUBTYPE_YD717, nullptr},
{MODULE_SUBTYPE_MULTI_KN, 1, false, STR_SUBTYPE_KN, nullptr},
{MODULE_SUBTYPE_MULTI_SYMAX, 1, false, STR_SUBTYPE_SYMAX, nullptr},
{MODULE_SUBTYPE_MULTI_SLT, 4, false, STR_SUBTYPE_SLT, nullptr},
{MODULE_SUBTYPE_MULTI_SLT, 4, false, STR_SUBTYPE_SLT, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_CX10, 6, false, STR_SUBTYPE_CX10, nullptr},
{MODULE_SUBTYPE_MULTI_CG023, 1, false, STR_SUBTYPE_CG023, nullptr},
{MODULE_SUBTYPE_MULTI_BAYANG, 4, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY},
{MODULE_SUBTYPE_MULTI_BAYANG, 5, false, STR_SUBTYPE_BAYANG, STR_MULTI_TELEMETRY},
{MODULE_SUBTYPE_MULTI_ESky, 1, false, STR_SUBTYPE_ESky, nullptr},
{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_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},
@@ -104,20 +121,35 @@ const Multiprotocols multiProtocols {
{MODULE_SUBTYPE_MULTI_WK_2X01, 5, false, STR_SUBTYPE_WK2x01, nullptr},
{MODULE_SUBTYPE_MULTI_Q303, 3, false, STR_SUBTYPE_Q303, nullptr},
{MODULE_SUBTYPE_MULTI_CABELL, 7, false, STR_SUBTYPE_CABELL, STR_MULTI_OPTION},
{MODULE_SUBTYPE_MULTI_ESKY150, 1, false, STR_SUBTYPE_ESKY150, nullptr},
{MODULE_SUBTYPE_MULTI_H83D, 3, false, STR_SUBTYPE_H83D, nullptr},
{MODULE_SUBTYPE_MULTI_CORONA, 2, false, STR_SUBTYPE_CORONA, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_HITEC, 2, false, STR_SUBTYPE_HITEC, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_WFLY, 0, false, STR_SUBTYPE_WFLY, nullptr},
{MODULE_SUBTYPE_MULTI_BUGS_MINI, 1, false, STR_SUBTYPE_BUGS_MINI, nullptr},
{MODULE_SUBTYPE_MULTI_TRAXXAS, 0, false, STR_SUBTYPE_TRAXXAS, nullptr},
{MODULE_SUBTYPE_MULTI_E01X, 2, false, STR_SUBTYPE_E01X, STR_MULTI_OPTION},
{MODULE_SUBTYPE_MULTI_V911S, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_GD00X, 1, false, STR_SUBTYPE_GD00X, nullptr},
{MODULE_SUBTYPE_MULTI_V911S, 1, false, STR_SUBTYPE_V911S, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_GD00X, 1, false, STR_SUBTYPE_GD00X, STR_MULTI_RFTUNE},
{MODULE_SUBTYPE_MULTI_V761, 1, false, STR_SUBTYPE_V761, nullptr},
{MODULE_SUBTYPE_MULTI_KF606, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE},
{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_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_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_Q90C, 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)
@@ -158,15 +190,14 @@ 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",
"FlySky AFHDS2A", "Q2x2", "Walkera", "Q303", "GW008", "DM002", "Cabell", "ESky 150", "H8 3D", "Corona", "CFlie",
"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", "ZXS", "FlyZone", "Scanner", "FrSky RX", "FlySky AFHDS2A RX"
"KFPlan KF606", "Redpine", "Potensic", "ZSX", "FlyZone", "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"
});
if (protocol == MM_RF_CUSTOM_SELECTED || custom)
return tr("Custom - proto %1)").arg(protocol);
else
return strings.value(protocol, CPN_STR_UNKNOWN_ITEM);
return strings.value(protocol, CPN_STR_UNKNOWN_ITEM);
}
// static
+111 -82
View File
@@ -36,7 +36,7 @@ inline int MAX_SWITCHES(Board::Type board, int version)
if (version <= 218) {
if (IS_TARANIS_X7(board))
return 6;
if (IS_TARANIS_X9D(board) || IS_HORUS(board))
if (IS_TARANIS_X9D(board) || IS_FAMILY_HORUS_OR_T16(board))
return 8;
if (IS_TARANIS_XLITE(board))
return 4;
@@ -63,7 +63,7 @@ inline int MAX_SWITCHES_POSITION(Board::Type board, int version)
inline int POTS_CONFIG_SIZE(Board::Type board, int version)
{
if (version >= 219 && IS_HORUS(board))
if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board))
return 16;
return 8;
@@ -71,44 +71,44 @@ inline int POTS_CONFIG_SIZE(Board::Type board, int version)
inline int MAX_POTS(Board::Type board, int version)
{
if (version <= 218 && IS_HORUS(board))
if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board))
return 3;
return Boards::getCapability(board, Board::Pots);
}
inline int MAX_POTS_STORAGE(Board::Type board, int version)
{
if (version <= 218 && IS_HORUS(board))
if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board))
return 3;
if (version >= 219 && IS_HORUS(board))
if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board))
return 5;
return Boards::getCapability(board, Board::Pots);
}
inline int MAX_POTS_SOURCES(Board::Type board, int version)
{
if (version <= 218 && IS_HORUS(board))
if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board))
return 5;
return Boards::getCapability(board, Board::Pots);
}
inline int MAX_SLIDERS_STORAGE(Board::Type board, int version)
{
if (version >= 219 && IS_HORUS(board))
if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board))
return 4;
return Boards::getCapability(board, Board::Sliders);
}
inline int MAX_SLIDERS_SOURCES(Board::Type board, int version)
{
if (version <= 218 && IS_HORUS(board))
if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board))
return 2;
return Boards::getCapability(board, Board::Sliders);
}
inline int SLIDERS_CONFIG_SIZE(Board::Type board, int version)
{
if (version >= 219 && IS_HORUS(board))
if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board))
return 8;
return 4;
@@ -119,7 +119,7 @@ inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version)
if (IS_TARANIS_X9E(board))
return 64;
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
return 32;
if (version >= 219 && IS_TARANIS_X9D(board))
@@ -128,7 +128,7 @@ inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version)
return 16;
}
#define MAX_ROTARY_ENCODERS(board) (IS_SKY9X(board) ? 1 : 0)
#define MAX_ROTARY_ENCODERS(board) 0
#define MAX_FLIGHT_MODES(board, version) 9
#define MAX_TIMERS(board, version) 3
#define MAX_MIXERS(board, version) 64
@@ -139,11 +139,11 @@ inline int SWITCHES_CONFIG_SIZE(Board::Type board, int version)
#define MAX_CUSTOM_FUNCTIONS(board, version) 64
#define MAX_CURVES(board, version) ((version >= 219 || HAS_LARGE_LCD(board)) ? 32 : 16)
#define MAX_GVARS(board, version) 9
#define MAX_SCRIPTS(board) (IS_HORUS(board) ? 9 : 7)
#define MAX_TELEMETRY_SENSORS(board, version) (version <= 218 ? 32 : ((IS_HORUS(board) || IS_TARANIS_X9(board)) ? 60 : 40))
#define MAX_SCRIPTS(board) (IS_FAMILY_HORUS_OR_T16(board) ? 9 : 7)
#define MAX_TELEMETRY_SENSORS(board, version) (version <= 218 ? 32 : ((IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS_X9(board)) ? 60 : 40))
#define NUM_PPM_INPUTS(board, version) 16
#define ROTENC_COUNT(board, version) ((IS_STM32(board) && version >= 218) ? 0 : 1)
#define MAX_AUX_TRIMS(board) (IS_HORUS(board) ? 2 : 0)
#define MAX_AUX_TRIMS(board) (IS_FAMILY_HORUS_OR_T16(board) ? 2 : 0)
inline int switchIndex(int i, Board::Type board, unsigned int version)
{
@@ -693,11 +693,13 @@ class FlightModeField: public TransformedField {
internalField.Append(new UnsignedField<8>(this, phase.fadeIn));
internalField.Append(new UnsignedField<8>(this, phase.fadeOut));
for (int i=0; i<rotencCount; i++) {
internalField.Append(new SignedField<16>(this, phase.rotaryEncoders[i]));
if (version < 219) {
for (int i = 0; i < rotencCount; i++) {
internalField.Append(new SignedField<16>(this, phase.rotaryEncoders[i]));
}
}
for (int i=0; i<MAX_GVARS(board, version); i++) {
for (int i = 0; i < MAX_GVARS(board, version); i++) {
internalField.Append(new SignedField<16>(this, phase.gvars[i]));
}
}
@@ -719,13 +721,7 @@ class FlightModeField: public TransformedField {
trim = 501 + phase.trimRef[i] - (phase.trimRef[i] > index ? 1 : 0);
else
trim = std::max(-500, std::min(500, phase.trim[i]));
if (board == BOARD_9X_M64 || (board == BOARD_9X_M128 && version >= 215)) {
trimBase[i] = trim >> 2;
trimExt[i] = (trim & 0x03);
}
else {
trimBase[i] = trim;
}
trimBase[i] = trim;
}
}
}
@@ -749,11 +745,7 @@ class FlightModeField: public TransformedField {
phase.trim[i] = 0;
}
else {
int trim;
if (board == BOARD_9X_M64 || (board == BOARD_9X_M128 && version >= 215))
trim = ((trimBase[i]) << 2) + (trimExt[i] & 0x03);
else
trim = trimBase[i];
int trim = trimBase[i];
if (trim > 500) {
phase.trimRef[i] = trim - 501;
if (phase.trimRef[i] >= index)
@@ -810,7 +802,7 @@ class MixField: public TransformedField {
internalField.Append(new UnsignedField<8>(this, mix.delayDown));
internalField.Append(new UnsignedField<8>(this, mix.speedUp));
internalField.Append(new UnsignedField<8>(this, mix.speedDown));
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
internalField.Append(new ZCharField<6>(this, mix.name));
else if (HAS_LARGE_LCD(board) && version <= 218)
internalField.Append(new ZCharField<8>(this, mix.name));
@@ -946,7 +938,7 @@ class InputField: public TransformedField {
internalField.Append(new UnsignedField<9>(this, expo.flightModes));
internalField.Append(new SignedField<8>(this, _weight, "Weight"));
internalField.Append(new SpareBitsField<1>(this));
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
internalField.Append(new ZCharField<6>(this, expo.name));
else if (HAS_LARGE_LCD(board) && version <= 218)
internalField.Append(new ZCharField<8>(this, expo.name));
@@ -1392,6 +1384,7 @@ class CustomFunctionsConversionTable: public ConversionTable {
addConversion(FuncTrainerELE, val);
addConversion(FuncTrainerTHR, val);
addConversion(FuncTrainerAIL, val);
addConversion(FuncTrainerChannels, val);
val++;
addConversion(FuncInstantTrim, val++);
@@ -1512,7 +1505,7 @@ class ArmCustomFunctionField: public TransformedField {
*((uint16_t *)_param) = fn.param;
*((uint8_t *)(_param+3)) = fn.func - FuncOverrideCH1;
}
else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerAIL) {
else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerChannels) {
*((uint8_t *)(_param+3)) = fn.func - FuncTrainer;
}
else if (fn.func >= FuncSetTimer1 && fn.func <= FuncSetTimer3) {
@@ -1579,7 +1572,7 @@ class ArmCustomFunctionField: public TransformedField {
fn.func = AssignFunc(fn.func + index);
fn.param = (int)value;
}
else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerAIL) {
else if (fn.func >= FuncTrainer && fn.func <= FuncTrainerChannels) {
fn.func = AssignFunc(fn.func + index);
fn.param = value;
}
@@ -1808,7 +1801,7 @@ class Frsky218Field: public StructField {
rssiConversionTable[0] = RSSIConversionTable(0);
rssiConversionTable[1] = RSSIConversionTable(1);
if (!IS_HORUS(board)) {
if (!IS_FAMILY_HORUS_OR_T16(board)) {
Append(new UnsignedField<8>(this, frsky.voltsSource, "Volts Source"));
Append(new UnsignedField<8>(this, frsky.altitudeSource, "Altitude Source"));
@@ -1877,7 +1870,7 @@ class CustomScreenField: public StructField {
class SensorField: public TransformedField {
public:
SensorField(DataField * parent, const ModelData& model, SensorData & sensor, Board::Type board, unsigned int version):
SensorField(DataField * parent, const ModelData & model, SensorData & sensor, Board::Type board, unsigned int version):
TransformedField(parent, internalField),
internalField(this, "Sensor"),
sensor(sensor),
@@ -1913,7 +1906,7 @@ class SensorField: public TransformedField {
internalField.Append(new UnsignedField<32>(this, _param, "param"));
}
virtual void beforeExport()
void beforeExport() override
{
if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) {
_id = sensor.id;
@@ -1945,16 +1938,9 @@ class SensorField: public TransformedField {
else {
sensor.id = _id;
sensor.subid = _subid;
if (model.moduleData[0].isPxx1Module() || model.moduleData[1].isPxx1Module()) {
sensor.instance = (_instance & 0x1F) + (version <= 218 ? 0 : 1); // 5 bits instance
sensor.rxIdx = 0x03; // 2 bits Rx idx
sensor.moduleIdx = 0x01; // 1 bit module idx
}
else {
sensor.instance = (_instance & 0x1F) + 1;
sensor.rxIdx = (_instance >> 5) & 0x03; // 2 bits Rx idx
sensor.moduleIdx = (_instance >> 7) & 0x1; // 1 bit module idx
}
sensor.instance = (_instance & 0x1F) + (version <= 218 ? 0 : 1); // 5 bits instance
sensor.rxIdx = (_instance >> 5) & 0x03; // 2 bits Rx idx
sensor.moduleIdx = (_instance >> 7) & 0x1; // 1 bit module idx
sensor.ratio = _ratio;
sensor.offset = _offset;
}
@@ -1980,6 +1966,12 @@ class SensorField: public TransformedField {
sensor.unit++;
}
if (version < 219) {
if (sensor.unit > SensorData::UNIT_FLOZ) {
sensor.unit += 11;
}
}
qCDebug(eepromImport) << QString("imported %1").arg(internalField.getName());
}
@@ -2036,7 +2028,7 @@ class ModuleUnionField: public UnionField<unsigned int> {
module(module),
rfProtExtra(0)
{
ModuleData::Multi& multi = module.multi;
ModuleData::Multi & multi = module.multi;
internalField.Append(new UnsignedField<3>(this, rfProtExtra));
internalField.Append(new BoolField<1>(this, multi.disableTelemetry));
internalField.Append(new BoolField<1>(this, multi.disableMapping));
@@ -2053,22 +2045,17 @@ class ModuleUnionField: public UnionField<unsigned int> {
void beforeExport() override
{
if (module.multi.rfProtocol > MODULE_SUBTYPE_MULTI_LAST)
module.multi.rfProtocol += 3;
rfProtExtra = (module.multi.rfProtocol & 0x70) >> 4;
module.multi.rfProtocol &= 0x0f;
}
void afterImport() override
{
module.multi.rfProtocol = (rfProtExtra << 4) + (module.rfProtocol & 0xf);
if (module.multi.rfProtocol > MODULE_SUBTYPE_MULTI_LAST)
module.multi.rfProtocol -= 3;
}
private:
StructField internalField;
ModuleData& module;
ModuleData & module;
unsigned int rfProtExtra;
};
@@ -2116,6 +2103,40 @@ class ModuleUnionField: public UnionField<unsigned int> {
unsigned int version;
};
class Afhds3Field: public UnionField::TransformedMember {
public:
Afhds3Field(DataField * parent, ModuleData& module):
UnionField::TransformedMember(parent, internalField),
internalField(this, "AFHDS3")
{
ModuleData::Afhds3& afhds3 = module.afhds3;
internalField.Append(new UnsignedField<3>(this, minBindPower));
internalField.Append(new UnsignedField<3>(this, afhds3.rfPower));
internalField.Append(new UnsignedField<1>(this, emissionFCC));
internalField.Append(new BoolField<1>(this, operationModeUnicast));
internalField.Append(new BoolField<1>(this, operationModeUnicast));
internalField.Append(new UnsignedField<16>(this, defaultFailSafeTimout));
internalField.Append(new UnsignedField<16>(this, afhds3.rxFreq));
}
bool select(const unsigned int& attr) const override {
return attr == PULSES_AFHDS3;
}
void beforeExport() override {}
void afterImport() override {}
private:
StructField internalField;
unsigned int minBindPower = 0;
unsigned int emissionFCC = 0;
unsigned int defaultFailSafeTimout = 1000;
bool operationModeUnicast = true;
};
class AccessField: public UnionField::TransformedMember {
public:
AccessField(DataField * parent, ModuleData& module):
@@ -2132,7 +2153,8 @@ class ModuleUnionField: public UnionField<unsigned int> {
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;
}
@@ -2140,7 +2162,6 @@ class ModuleUnionField: public UnionField<unsigned int> {
{
for (int i=0; i<PXX2_MAX_RECEIVERS_PER_MODULE; i++) {
for (int pos=0; pos<PXX2_LEN_RX_NAME+1; pos++) {
if (pos == PXX2_LEN_RX_NAME || module.access.receiverName[i][pos] == '\0') {
memset(module.access.receiverName[i]+pos,'\0',PXX2_LEN_RX_NAME-pos);
break;
@@ -2176,8 +2197,10 @@ class ModuleUnionField: public UnionField<unsigned int> {
ModuleUnionField(DataField * parent, ModuleData & module, Board::Type board, unsigned int version):
UnionField<unsigned int>(parent, module.protocol)
{
if (version >= 219)
if (version >= 219) {
Append(new AccessField(parent, module));
Append(new Afhds3Field(parent, module));
}
Append(new PxxField(parent, module, version));
Append(new MultiField(parent, module));
Append(new PPMField(parent, module.ppm));
@@ -2187,7 +2210,7 @@ class ModuleUnionField: public UnionField<unsigned int> {
class ModuleField: public TransformedField {
public:
ModuleField(DataField * parent, ModuleData & module, Board::Type board, unsigned int version):
ModuleField(DataField * parent, ModuleData & module, ModelData & model, Board::Type board, unsigned int version):
TransformedField(parent, internalField),
internalField(this, "Module"),
module(module),
@@ -2201,8 +2224,8 @@ class ModuleField: public TransformedField {
internalField.Append(new UnsignedField<3>(this, module.subType));
internalField.Append(new BoolField<1>(this, module.invertedSerial));
if (version <= 218) {
for (int i=0; i<32; i++) {
internalField.Append(new SignedField<16>(this, module.failsafeChannels[i]));
for (int i = 0; i < 32; i++) {
internalField.Append(new SignedField<16>(this, model.limitData[i].failsafe));
}
}
@@ -2221,7 +2244,7 @@ class ModuleField: public TransformedField {
module.subType = module.protocol - PULSES_PXX_XJT_X16;
}
else if (module.protocol == PULSES_MULTIMODULE) {
module.rfProtocol = module.multi.rfProtocol & 0xf;
module.rfProtocol = module.multi.rfProtocol & 0x0F;
}
}
@@ -2250,7 +2273,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
qDebug() << QString("OpenTxModelData::OpenTxModelData(name: %1, board: %2, ver: %3, var: %4)").arg(name).arg(board).arg(version).arg(variant);
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
internalField.Append(new ZCharField<15>(this, modelData.name, "Model name"));
else if (HAS_LARGE_LCD(board))
internalField.Append(new ZCharField<12>(this, modelData.name, "Model name"));
@@ -2261,7 +2284,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
internalField.Append(new UnsignedField<8>(this, modelData.moduleData[1].modelId));
if (HAS_LARGE_LCD(board)) {
if (version >= 219 && IS_HORUS(board))
if (version >= 219 && IS_FAMILY_HORUS_OR_T16(board))
internalField.Append(new CharField<14>(this, modelData.bitmap, true, "Model bitmap"));
else
internalField.Append(new CharField<10>(this, modelData.bitmap, true, "Model bitmap"));
@@ -2329,7 +2352,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
internalField.Append(new UnsignedField<8>(this, modelData.thrTraceSrc, "Throttle Source"));
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
internalField.Append(new SwitchesWarningField<32>(this, modelData.switchWarningStates, board, version));
else if (IS_TARANIS_X9E(board))
internalField.Append(new SwitchesWarningField<64>(this, modelData.switchWarningStates, board, version));
@@ -2344,7 +2367,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
internalField.Append(new UnsignedField<32>(this, modelData.switchWarningEnable));
else if (version >= 219 && IS_TARANIS_X9D(board))
internalField.Append(new UnsignedField<16>(this, modelData.switchWarningEnable));
else if (!IS_HORUS(board))
else if (!IS_FAMILY_HORUS_OR_T16(board))
internalField.Append(new UnsignedField<8>(this, modelData.switchWarningEnable));
for (int i=0; i<MAX_GVARS(board, version); i++) {
@@ -2396,12 +2419,12 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
int modulesCount = (version <= 218 ? 3 : 2);
for (int module = 0; module < modulesCount; module++) {
internalField.Append(new ModuleField(this, modelData.moduleData[module], board, version));
internalField.Append(new ModuleField(this, modelData.moduleData[module], modelData, board, version));
}
if (version >= 219) {
for (int i = 0; i < 32; i++) {
internalField.Append(new SignedField<16>(this, modelData.moduleData[0].failsafeChannels[i]));
internalField.Append(new SignedField<16>(this, modelData.limitData[i].failsafe));
}
}
@@ -2481,7 +2504,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
internalField.Append(new UnsignedField<8>(this, modelData.toplcdTimer));
}
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
for (int i = 0; i < 5; i++) {
internalField.Append(new CharField<610>(this, modelData.customScreenData[i], false, "Custom screen blob"));
}
@@ -2507,7 +2530,7 @@ void OpenTxModelData::beforeExport()
{
// qDebug() << QString("before export model") << modelData.name;
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
uint32_t newSwitchWarningStates = 0;
for (int i = 0; i < MAX_SWITCHES(board, version); i++) {
uint8_t value = (modelData.switchWarningStates >> (2*i)) & 0x03;
@@ -2523,7 +2546,7 @@ void OpenTxModelData::afterImport()
{
qCDebug(eepromImport) << QString("OpenTxModelData::afterImport()") << modelData.name;
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
uint32_t newSwitchWarningStates = 0;
for (int i = 0; i < MAX_SWITCHES(board, version); i++) {
uint8_t value = (modelData.switchWarningStates >> (3*i)) & 0x07;
@@ -2571,7 +2594,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
internalField.Append(new UnsignedField<16>(this, chkSum));
if (!IS_HORUS(board)) {
if (!IS_FAMILY_HORUS_OR_T16(board)) {
internalField.Append(new UnsignedField<8>(this, generalData.currModelIndex));
internalField.Append(new UnsignedField<8>(this, generalData.contrast));
}
@@ -2584,7 +2607,13 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
else
internalField.Append(new SpareBitsField<2>(this));
internalField.Append(new BoolField<1>(this, generalData.rtcCheckDisable));
internalField.Append(new SpareBitsField<2>(this));
if (IS_JUMPER_T18(board)) {
internalField.Append(new BoolField<1>(this, generalData.keysBacklight));
internalField.Append(new SpareBitsField<1>(this));
}
else {
internalField.Append(new SpareBitsField<2>(this));
}
for (int i=0; i<4; i++) {
internalField.Append(new SignedField<16>(this, generalData.trainer.calib[i]));
@@ -2616,7 +2645,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
internalField.Append(new UnsignedField<8>(this, generalData.inactivityTimer));
internalField.Append(new UnsignedField<3>(this, generalData.telemetryBaudrate));
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
internalField.Append(new SpareBitsField<3>(this));
else if (IS_TARANIS(board))
internalField.Append(new SignedField<3>(this, generalData.splashDuration));
@@ -2631,11 +2660,11 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
internalField.Append(new SignedField<8>(this, generalData.PPM_Multiplier));
internalField.Append(new SignedField<8>(this, generalData.hapticLength));
if (version < 218 || (!IS_TARANIS(board) && !IS_HORUS(board))) {
if (version < 218 || (!IS_TARANIS(board) && !IS_FAMILY_HORUS_OR_T16(board))) {
internalField.Append(new UnsignedField<8>(this, generalData.reNavigation));
}
if (!IS_TARANIS(board) && !IS_HORUS(board)) {
if (!IS_TARANIS(board) && !IS_FAMILY_HORUS_OR_T16(board)) {
internalField.Append(new UnsignedField<8>(this, generalData.stickReverse));
}
@@ -2714,7 +2743,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
if (IS_STM32(board)) {
if (version >= 218) {
internalField.Append(new UnsignedField<4>(this, generalData.auxSerialMode));
if (IS_HORUS(board) && version >= 219) {
if (IS_FAMILY_HORUS_OR_T16(board) && version >= 219) {
internalField.Append(new SpareBitsField<4>(this));
}
else {
@@ -2734,7 +2763,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
}
}
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
for (int i=0; i<SWITCHES_CONFIG_SIZE(board, version) / 2; i++) {
if (i < MAX_SWITCHES(board, version))
internalField.Append(new UnsignedField<2>(this, generalData.switchConfig[i]));
@@ -2746,7 +2775,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
for (int i=0; i<POTS_CONFIG_SIZE(board, version) / 2; i++) {
int offset = 0;
// 2 new pots for Horus from 219 on
if (version <= 218 && IS_HORUS(board) && (i >= 3))
if (version <= 218 && IS_FAMILY_HORUS_OR_T16(board) && (i >= 3))
offset += 2;
if (i < MAX_POTS_STORAGE(board, version))
@@ -2755,7 +2784,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
internalField.Append(new SpareBitsField<2>(this));
}
if (IS_HORUS(board) && version >= 219) {
if (IS_FAMILY_HORUS_OR_T16(board) && version >= 219) {
for (int i=0; i<SLIDERS_CONFIG_SIZE(board,version); i++) {
if (i < MAX_SLIDERS_STORAGE(board, version))
internalField.Append(new UnsignedField<1>(this, generalData.sliderConfig[i]));
@@ -2764,7 +2793,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
}
}
if (!IS_HORUS(board)) {
if (!IS_FAMILY_HORUS_OR_T16(board)) {
internalField.Append(new UnsignedField<8>(this, generalData.backlightColor));
}
}
@@ -2792,7 +2821,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
}
}
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
for (int i=0; i<MAX_SWITCHES(board, version); ++i) {
internalField.Append(new ZCharField<3>(this, generalData.switchName[i], "Switch name"));
}
@@ -2831,7 +2860,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
}
}
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
internalField.Append(new SpareBitsField<1>(this));
internalField.Append(new UnsignedField<7>(this, generalData.backlightOffBright));
internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name"));
@@ -2841,7 +2870,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name"));
}
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
internalField.Append(new CharField<8>(this, generalData.themeName, true, "Theme name"));
for (int i=0; i<5; i++) {
internalField.Append(new CharField<8>(this, (char *)generalData.themeOptionValue[i], true, "Theme blob"));
@@ -28,18 +28,15 @@
#define GVARS_VARIANT 0x0001
#define FRSKY_VARIANT 0x0002
#define MAVLINK_VARIANT 0x0008
#define M128_VARIANT 0x8000
#define TARANIS_X9E_VARIANT 0x8000
#define TARANIS_X7_VARIANT 0x4000
#define TARANIS_XLITE_VARIANT 0x2000
#define TARANIS_XLITES_VARIANT 0x1000
#define TARANIS_X9LITE_VARIANT 0x0800
#define TARANIS_X9LITES_VARIANT 0x0801
#define JUMPER_T12_VARIANT 0x4001
#define SIMU_STOCK_VARIANTS (GVARS_VARIANT|FRSKY_VARIANT)
#define SIMU_M128_VARIANTS (M128_VARIANT|SIMU_STOCK_VARIANTS)
class OpenTxGeneralData: public TransformedField {
public:
OpenTxGeneralData(GeneralSettings & generalData, Board::Type board, unsigned int version, unsigned int variant=0);
@@ -107,6 +104,9 @@ 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++);
}
}
};
+156 -182
View File
@@ -58,18 +58,14 @@ OpenTxEepromInterface::~OpenTxEepromInterface()
const char * OpenTxEepromInterface::getName()
{
switch (board) {
case BOARD_9X_M64:
return "OpenTX for 9X board";
case BOARD_9X_M128:
return "OpenTX for M128 / 9X board";
case BOARD_MEGA2560:
return "OpenTX for MEGA2560 board";
case BOARD_GRUVIN9X:
return "OpenTX for Gruvin9x board / 9X";
case BOARD_JUMPER_T12:
return "OpenTX for Jumper T12";
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_TARANIS_X9D:
return "OpenTX for FrSky Taranis X9D";
case BOARD_TARANIS_X9DP:
@@ -80,6 +76,8 @@ const char * OpenTxEepromInterface::getName()
return "OpenTX for FrSky Taranis X9E";
case BOARD_TARANIS_X7:
return "OpenTX for FrSky Taranis X7";
case BOARD_TARANIS_X7_ACCESS:
return "OpenTX for FrSky Taranis X7 Access";
case BOARD_TARANIS_X9LITES:
return "OpenTX for FrSky Taranis X9-Lite S";
case BOARD_TARANIS_X9LITE:
@@ -173,7 +171,7 @@ bool OpenTxEepromInterface::loadFromByteArray(T & dest, const QByteArray & data)
{
uint32_t fourcc = *((uint32_t*)&data.data()[0]);
if (Boards::getFourCC(board) != fourcc) {
if (IS_HORUS(board) && fourcc == 0x3178396F) {
if (IS_FAMILY_HORUS_OR_T16(board) && fourcc == 0x3178396F) {
qDebug() << QString().sprintf("%s: Deprecated fourcc used %x vs %x", getName(), fourcc, Boards::getFourCC(board));
}
else {
@@ -276,16 +274,7 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
uint8_t OpenTxEepromInterface::getLastDataVersion(Board::Type board)
{
switch (board) {
case BOARD_9X_M64:
return 216;
case BOARD_GRUVIN9X:
case BOARD_MEGA2560:
case BOARD_9X_M128:
return 217;
default:
return 219;
}
return 219;
}
void OpenTxEepromInterface::showErrors(const QString & title, const QStringList & errors)
@@ -321,15 +310,18 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, u
efile->EeFsCreate(eeprom, size, board, version);
if (board == BOARD_9X_M128) {
variant |= M128_VARIANT;
}
else if (IS_TARANIS_X9E(board)) {
if (IS_TARANIS_X9E(board)) {
variant |= TARANIS_X9E_VARIANT;
}
else if (IS_TARANIS_X9LITES(board)) {
variant |= TARANIS_X9LITES_VARIANT;
}
else if (IS_TARANIS_X9LITE(board)) {
variant |= TARANIS_X9LITE_VARIANT;
}
else if (IS_TARANIS_X7_ACCESS(board)) {
variant |= TARANIS_X7_VARIANT;
}
else if (IS_TARANIS_X7(board)) {
variant |= TARANIS_X7_VARIANT;
}
@@ -433,45 +425,28 @@ int OpenTxFirmware::getCapability(::Capability capability)
{
switch (capability) {
case Models:
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
return 0;
else if (IS_ARM(board))
else
return 60;
else if (board == BOARD_9X_M128)
return 30;
else if (IS_2560(board))
return 30;
else
return 16;
case Imperial:
if (IS_ARM(board))
return 0;
else
return id.contains("imperial") ? 1 : 0;
return 0;
case ModelImage:
return (board == BOARD_TARANIS_X9D || IS_TARANIS_PLUS(board) || board == BOARD_TARANIS_X9DP_2019 || IS_HORUS(board));
return (board == BOARD_TARANIS_X9D || IS_TARANIS_PLUS(board) || board == BOARD_TARANIS_X9DP_2019 || IS_FAMILY_HORUS_OR_T16(board));
case HasBeeper:
return (!IS_ARM(board));
return false;
case HasPxxCountry:
return 1;
case HasGeneralUnits:
if (IS_ARM(board))
return 1;
else
return 0;
return true;
case HasNegAndSwitches:
return IS_ARM(board);
return true;
case PPMExtCtrl:
return 1;
case PPMFrameLength:
return 40;
case FlightModes:
if (IS_ARM(board))
return 9;
else if (IS_2560(board))
return 6;
else
return 5;
return 9;
case FlightModesHaveFades:
return 1;
case Heli:
@@ -483,85 +458,67 @@ int OpenTxFirmware::getCapability(::Capability capability)
if (IS_HORUS_OR_TARANIS(board))
return id.contains("nogvars") ? 0 : 9;
else if (id.contains("gvars"))
return IS_ARM(board) ? 9 : 5;
return 9;
else
return 0;
case ModelName:
return (IS_HORUS(board) ? 15 : (HAS_LARGE_LCD(board) ? 12 : 10));
return (IS_FAMILY_HORUS_OR_T16(board) ? 15 : (HAS_LARGE_LCD(board) ? 12 : 10));
case FlightModesName:
return (IS_HORUS_OR_TARANIS(board) ? 10 : 6);
case GvarsName:
return (IS_9X(board) ? 0 : 3);
return 3;
case GvarsInCS:
case HasFAIMode:
return 1;
case GvarsAreNamed:
case GvarsFlightModes:
return ((IS_ARM(board) || IS_2560(board)) ? 1 : 0);
return 1;
case Mixes:
return (IS_ARM(board) ? 64 : 32);
return 64;
case OffsetWeight:
return (IS_ARM(board) ? 500 : 245);
return 500;
case Timers:
return (IS_ARM(board) ? 3 : 2);
return 3;
case TimersName:
if (HAS_LARGE_LCD(board))
return 8;
else if (IS_ARM(board))
else
return 3;
else
return 0;
case PermTimers:
return (IS_2560(board) || IS_ARM(board));
return true;
case CustomFunctions:
if (IS_ARM(board))
return 64;
else if (IS_2560(board) || board == BOARD_9X_M128)
return 24;
else
return 16;
return 64;
case SafetyChannelCustomFunction:
return id.contains("nooverridech") ? 0 : 1;
case LogicalSwitches:
if (IS_ARM(board))
return 64;
else
return 12;
return 64;
case CustomAndSwitches:
if (IS_ARM(board))
return getCapability(LogicalSwitches);
else
return 15/*4bits*/- 9/*sw positions*/;
return getCapability(LogicalSwitches);
case LogicalSwitchesExt:
return (IS_ARM(board) ? true : false);
return true;
case RotaryEncoders:
if (board == BOARD_GRUVIN9X)
return 2;
else if (IS_SKY9X(board))
return 1;
else
return 0;
case Outputs:
return (IS_ARM(board) ? 32 : 16);
return 32;
case NumCurvePoints:
return (IS_ARM(board) ? 512 : 104);
return 512;
case VoicesAsNumbers:
return (IS_ARM(board) ? 0 : 1);
return 0;
case VoicesMaxLength:
return (IS_ARM(board) ? (IS_TARANIS_X9(board) ? 8 : 6) : 0);
return (IS_TARANIS_X9(board) ? 8 : 6);
case MultiLangVoice:
return (IS_ARM(board) ? 1 : 0);
return 1;
case SoundPitch:
return 1;
case Haptic:
return (IS_2560(board) || IS_SKY9X(board) || IS_TARANIS_PLUS(board) || IS_TARANIS_SMALL(board) || IS_TARANIS_X9E(board) || IS_HORUS(board) || IS_JUMPER_T12(board) || id.contains("haptic"));
return board != Board::BOARD_TARANIS_X9D || id.contains("haptic");
case ModelTrainerEnable:
if (IS_HORUS_OR_TARANIS(board) && board!=Board::BOARD_TARANIS_XLITE)
return 1;
else
return 0;
case MaxVolume:
return (IS_ARM(board) ? 23 : 7);
return 23;
case MaxContrast:
if (IS_TARANIS_SMALL(board) || IS_JUMPER_T12(board))
return 30;
@@ -573,7 +530,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
else
return 10;
case HasSoundMixer:
return (IS_ARM(board) ? 1 : 0);
return 1;
case ExtraInputs:
return 1;
case TrimsRange:
@@ -583,29 +540,30 @@ int OpenTxFirmware::getCapability(::Capability capability)
case Simulation:
return 1;
case NumCurves:
return (HAS_LARGE_LCD(board) ? 32 : (IS_ARM(board) ? 16 : 8));
return (HAS_LARGE_LCD(board) ? 32 : 16);
case HasMixerNames:
return (IS_ARM(board) ? (IS_TARANIS_X9(board) ? 8 : 6) : false);
return (IS_TARANIS_X9(board) ? 8 : 6);
case HasExpoNames:
return (IS_ARM(board) ? (IS_TARANIS_X9(board) ? 8 : 6) : false);
return (IS_TARANIS_X9(board) ? 8 : 6);
case HasNoExpo:
return (IS_HORUS_OR_TARANIS(board) ? false : true);
case ChannelsName:
return (IS_ARM(board) ? (HAS_LARGE_LCD(board) ? 6 : 4) : 0);
return (HAS_LARGE_LCD(board) ? 6 : 4);
case HasCvNames:
return (IS_ARM(board) ? 1 : 0);
return 1;
case Telemetry:
if (IS_2560(board) || IS_ARM(board) || id.contains("frsky") || id.contains("telemetrez"))
return TM_HASTELEMETRY | TM_HASOFFSET | TM_HASWSHH;
else
return 0;
return 1;
case TelemetryBars:
return 1;
case TelemetryCustomScreens:
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
return 0;
else
return IS_ARM(board) ? 4 : 2;
return 4;
case TelemetryCustomScreensBars:
return (getCapability(TelemetryCustomScreens) ? 4 : 0);
case TelemetryCustomScreensLines:
return (getCapability(TelemetryCustomScreens) ? 4 : 0);
case TelemetryCustomScreensFieldsPerLine:
return HAS_LARGE_LCD(board) ? 3 : 2;
case NoTelemetryProtocol:
@@ -613,7 +571,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
case TelemetryUnits:
return 0;
case TelemetryMaxMultiplier:
return (IS_ARM(board) ? 32 : 8);
return 32;
case PPMCenter:
return (IS_HORUS_OR_TARANIS(board) ? 500 : (id.contains("ppmca") ? 125 : 0));
case PPMUnitMicroseconds:
@@ -625,37 +583,37 @@ int OpenTxFirmware::getCapability(::Capability capability)
case HasVario:
return 1;
case HasVarioSink:
return ((IS_2560(board) || IS_ARM(board)) ? true : false);
return true;
case HasFailsafe:
return (IS_ARM(board) ? 32 : 0);
return 32;
case NumModules:
return (IS_ARM(board) ? 2 : 1);
return 2;
case NumFirstUsableModule:
return (IS_JUMPER_T12(board) ? 1 : 0);
return (IS_JUMPER_T12(board) && !id.contains("internalmulti") ? 1 : 0);
case HasModuleR9MFlex:
return id.contains("flexr9m");
case HasModuleR9MMini:
return IS_TARANIS_XLITE(board) && !id.contains("stdr9m");
case HasPPMStart:
return (IS_ARM(board) ? true : false);
return true;
case HastxCurrentCalibration:
return (IS_SKY9X(board) ? true : false);
case HasVolume:
return (IS_ARM(board) ? true : false);
return true;
case HasBrightness:
return (IS_ARM(board) ? true : false);
return true;
case PerModelTimers:
return 1;
case SlowScale:
return (IS_ARM(board) ? 10 : 2);
return 10;
case SlowRange:
return (IS_ARM(board) ? 250 : 15);
return 250;
case CSFunc:
return 18;
case HasSDLogs:
return ((IS_2560(board) || IS_ARM(board)) ? true : false);
return true;
case LcdWidth:
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
return 480;
else if (IS_TARANIS_SMALL(board) || IS_JUMPER_T12(board))
return 128;
@@ -664,12 +622,12 @@ int OpenTxFirmware::getCapability(::Capability capability)
else
return 128;
case LcdHeight:
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
return 272;
else
return 64;
case LcdDepth:
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
return 16;
else if (IS_TARANIS_SMALL(board) || IS_JUMPER_T12(board))
return 1;
@@ -680,19 +638,19 @@ int OpenTxFirmware::getCapability(::Capability capability)
case GetThrSwitch:
return (IS_HORUS_OR_TARANIS(board) ? SWITCH_SF1 : SWITCH_THR);
case HasDisplayText:
return IS_ARM(board) ? 1 : 0;
return 1;
case HasTopLcd:
return IS_TARANIS_X9E(board) ? 1 : 0;
case GlobalFunctions:
return IS_ARM(board) ? 64 : 0;
return 64;
case VirtualInputs:
return IS_ARM(board) ? 32 : 0;
return 32;
case InputsLength:
return HAS_LARGE_LCD(board) ? 4 : 3;
case TrainerInputs:
return IS_ARM(board) ? 16 : 8;
return 16;
case RtcTime:
return IS_ARM(board) || IS_2560(board) ? 1 : 0;
return 1;
case LuaScripts:
return IS_HORUS_OR_TARANIS(board) && id.contains("lua") ? 7 : 0;
case LuaInputsPerScript:
@@ -701,18 +659,16 @@ int OpenTxFirmware::getCapability(::Capability capability)
return IS_HORUS_OR_TARANIS(board) ? 6 : 0;
case LimitsPer1000:
case EnhancedCurves:
return IS_ARM(board);
return 1;
case HasFasOffset:
return (IS_STOCK(board) ? false : true);
return true;
case HasMahPersistent:
return (IS_ARM(board) ? true : false);
return true;
case SimulatorVariant:
if (board == BOARD_9X_M64)
return SIMU_STOCK_VARIANTS;
else if (board == BOARD_9X_M128)
return SIMU_M128_VARIANTS;
else if (IS_TARANIS_X9E(board))
if (IS_TARANIS_X9E(board))
return TARANIS_X9E_VARIANT;
else if (IS_TARANIS_X9LITES(board))
return TARANIS_X9LITES_VARIANT;
else if (IS_TARANIS_X9LITE(board))
return TARANIS_X9LITE_VARIANT;
else if (IS_TARANIS_X7(board))
@@ -728,7 +684,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
case MavlinkTelemetry:
return id.contains("mavlink") ? 1 : 0;
case SportTelemetry:
return IS_ARM(board) ? 1 : 0;
return 1;
case HasInputDiff:
case HasMixerExpo:
return (IS_HORUS_OR_TARANIS(board) ? true : false);
@@ -737,11 +693,16 @@ int OpenTxFirmware::getCapability(::Capability capability)
case DangerousFunctions:
return id.contains("danger") ? 1 : 0;
case HasModelCategories:
return IS_HORUS(board);
return IS_FAMILY_HORUS_OR_T16(board);
case HasSwitchableJack:
return IS_TARANIS_XLITES(board);
case PwrButtonPress:
return IS_HORUS_OR_TARANIS(board) && (board!=Board::BOARD_TARANIS_X9D) && (board!=Board::BOARD_TARANIS_X9DP);
case Sensors:
if (IS_FAMILY_HORUS_OR_T16(board) || IS_TARANIS_X9(board))
return 60;
else
return 40;
default:
return 0;
}
@@ -756,10 +717,8 @@ QTime OpenTxFirmware::getMaxTimerStart()
{
if (IS_HORUS_OR_TARANIS(board))
return QTime(23, 59, 59);
else if (IS_ARM(board))
return QTime(8, 59, 59);
else
return QTime(0, 59, 59);
return QTime(8, 59, 59);
}
bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
@@ -772,16 +731,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) && board != BOARD_JUMPER_T16;
return !IS_ACCESS_RADIO(board, id) && !IS_FAMILY_T16(board) && !IS_JUMPER_T12(board);
case PULSES_PXX_XJT_D8:
return !(IS_ACCESS_RADIO(board, id) || id.contains("eu")) && board != BOARD_JUMPER_T16;
case PULSES_PPM:
return id.contains("internalppm");
return !(IS_ACCESS_RADIO(board, id) || id.contains("eu")) && !IS_FAMILY_T16(board) && !IS_JUMPER_T12(board);
case PULSES_ACCESS_ISRM:
case PULSES_ACCST_ISRM_D16:
return IS_ACCESS_RADIO(board, id);
case PULSES_MULTIMODULE:
return id.contains("internalmulti");
return id.contains("internalmulti") || IS_RADIOMASTER_TX16S(board) || IS_JUMPER_T18(board);
default:
return false;
}
@@ -802,16 +759,17 @@ bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
case PULSES_SBUS:
case PULSES_MULTIMODULE:
case PULSES_CROSSFIRE:
case PULSES_AFHDS3:
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_HORUS(board) && id.contains("internalaccess"));
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"));
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));
default:
return false;
}
@@ -925,14 +883,9 @@ EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version)
// M128 revert because too much RAM used!
case 216:
// A lot of things (first github release)
if (IS_2560(board) || IS_M128(board)) {
return OLD_VERSION;
}
case 217:
// 3 logical switches removed on M128 / gruvin9x boards
if (IS_ARM(board)) {
return OLD_VERSION;
}
case 218:
// ACCESS
// switches add for X7/X10/X12S
@@ -952,21 +905,7 @@ EepromLoadErrors OpenTxEepromInterface::checkVersion(unsigned int version)
bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int variant)
{
bool variantError = false;
if (board == BOARD_9X_M128 && !(variant & M128_VARIANT)) {
if (version == 212) {
uint8_t tmp[1000];
for (int i = 1; i < 31; i++) {
efile->openRd(i);
int sz = efile->readRlc2(tmp, sizeof(tmp));
if (sz == 849) {
qWarning() << " warning: M128 variant not set (but model size seems ok)";
return true;
}
}
}
variantError = true;
}
else if (IS_TARANIS_X9E(board)) {
if (IS_TARANIS_X9E(board)) {
if (variant != TARANIS_X9E_VARIANT) {
variantError = true;
}
@@ -986,6 +925,11 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
variantError = true;
}
}
else if (IS_TARANIS_X9LITES(board)) {
if (variant != TARANIS_X9LITES_VARIANT) {
variantError = true;
}
}
else if (IS_TARANIS_X9LITE(board)) {
if (variant != TARANIS_X9LITE_VARIANT) {
variantError = true;
@@ -1053,9 +997,6 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
case 0x32:
backupBoard = BOARD_SKY9X;
break;
case 0x31:
backupBoard = BOARD_GRUVIN9X;
break;
default:
dbg << " unknown board";
errors.set(UNKNOWN_BOARD);
@@ -1155,14 +1096,28 @@ void addOpenTxCommonOptions(OpenTxFirmware * firmware)
firmware->addOption("nooverridech", Firmware::tr("No OverrideCH functions available"));
}
void addOpenTxRfOptions(OpenTxFirmware * firmware, bool flex = true)
enum RfOptions {
NONE = 0,
EU = 1 << 0,
FLEX = 1 << 1,
AFHDS3 = 1 << 2
};
void addOpenTxRfOptions(OpenTxFirmware * firmware, uint8_t options)
{
static const Firmware::Option opt_eu("eu", Firmware::tr("Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015"));
static const Firmware::Option opt_fl("flexr9m", Firmware::tr("Enable non certified firmwares"));
if (flex)
static const Firmware::Option opt_afhds3("afhds3", Firmware::tr("Enable AFHDS3 support"));
if ((options & (EU + FLEX)) == EU + FLEX)
firmware->addOptionsGroup({opt_eu, opt_fl});
else
else if ((options & EU) != 0)
firmware->addOption(opt_eu);
else if ((options & FLEX) != 0)
firmware->addOption(opt_fl);
if ((options & AFHDS3) != 0)
firmware->addOption(opt_afhds3);
}
void addOpenTxFontOptions(OpenTxFirmware * firmware)
@@ -1176,7 +1131,6 @@ void addOpenTxFrskyOptions(OpenTxFirmware * 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"));
addOpenTxRfOptions(firmware);
}
void addOpenTxTaranisOptions(OpenTxFirmware * firmware)
@@ -1185,11 +1139,6 @@ void addOpenTxTaranisOptions(OpenTxFirmware * firmware)
addOpenTxFontOptions(firmware);
}
void addPPMInternalModuleHack(OpenTxFirmware * firmware)
{
firmware->addOption("internalppm", Firmware::tr("Support for PPM internal module hack"));
}
void addOpenTxArm9xOptions(OpenTxFirmware * firmware, bool dblkeys = true)
{
addOpenTxCommonOptions(firmware);
@@ -1205,7 +1154,7 @@ void addOpenTxArm9xOptions(OpenTxFirmware * firmware, bool dblkeys = true)
if (dblkeys)
firmware->addOption("dblkeys", Firmware::tr("Enable resetting values by pressing up and down at the same time"));
addOpenTxFontOptions(firmware);
addOpenTxRfOptions(firmware, true);
addOpenTxRfOptions(firmware, FLEX);
}
void registerOpenTxFirmwares()
@@ -1216,65 +1165,80 @@ void registerOpenTxFirmwares()
firmware = new OpenTxFirmware("opentx-x9d+", Firmware::tr("FrSky Taranis X9D+"), BOARD_TARANIS_X9DP);
firmware->addOption("noras", Firmware::tr("Disable RAS (SWR)"));
addOpenTxTaranisOptions(firmware);
addPPMInternalModuleHack(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, EU + FLEX + AFHDS3);
/* FrSky Taranis X9D+ 2019 board */
firmware = new OpenTxFirmware("opentx-x9d+2019", Firmware::tr("FrSky Taranis X9D+ 2019"), BOARD_TARANIS_X9DP_2019);
addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX);
/* FrSky Taranis X9D board */
firmware = new OpenTxFirmware("opentx-x9d", Firmware::tr("FrSky Taranis X9D"), BOARD_TARANIS_X9D);
firmware->addOption("noras", Firmware::tr("Disable RAS (SWR)"));
firmware->addOption("haptic", Firmware::tr("Haptic module installed"));
addOpenTxTaranisOptions(firmware);
addPPMInternalModuleHack(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, EU + FLEX + AFHDS3);
/* FrSky Taranis X9E board */
firmware = new OpenTxFirmware("opentx-x9e", Firmware::tr("FrSky Taranis X9E"), BOARD_TARANIS_X9E);
firmware->addOption("shutdownconfirm", Firmware::tr("Confirmation before radio shutdown"));
firmware->addOption("horussticks", Firmware::tr("Horus gimbals installed (Hall sensors)"));
addOpenTxTaranisOptions(firmware);
addPPMInternalModuleHack(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, EU + FLEX + AFHDS3);
/* 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);
/* 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);
/* FrSky X7 board */
firmware = new OpenTxFirmware("opentx-x7", Firmware::tr("FrSky Taranis X7 / X7S"), BOARD_TARANIS_X7);
addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, EU + FLEX);
/* FrSky X7 Access board */
firmware = new OpenTxFirmware("opentx-x7access", Firmware::tr("FrSky Taranis X7 / X7S Access"), BOARD_TARANIS_X7_ACCESS);
addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX);
/* FrSky X-Lite S/PRO board */
firmware = new OpenTxFirmware("opentx-xlites", Firmware::tr("FrSky Taranis X-Lite S/PRO"), BOARD_TARANIS_XLITES);
addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
/* FrSky X-Lite board */
firmware = new OpenTxFirmware("opentx-xlite", Firmware::tr("FrSky Taranis X-Lite"), BOARD_TARANIS_XLITE);
// firmware->addOption("stdr9m", Firmware::tr("Use JR-sized R9M module"));
addOpenTxTaranisOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, EU + FLEX);
/* FrSky X10 board */
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"));
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, EU + FLEX);
/* FrSky X10 Express board */
firmware = new OpenTxFirmware("opentx-x10express", Firmware::tr("FrSky Horus X10 Express / X10S Express"), BOARD_X10_EXPRESS);
addOpenTxFrskyOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX);
/* FrSky X12 (Horus) board */
firmware = new OpenTxFirmware("opentx-x12s", Firmware::tr("FrSky Horus X12S"), BOARD_HORUS_X12S);
@@ -1282,6 +1246,7 @@ void registerOpenTxFirmwares()
firmware->addOption("internalaccess", Firmware::tr("Support for ACCESS internal module replacement"));
firmware->addOption("pcbdev", Firmware::tr("Use ONLY with first DEV pcb version"));
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, EU + FLEX);
/* Jumper T12 board */
firmware = new OpenTxFirmware("opentx-t12", QCoreApplication::translate("Firmware", "Jumper T12 / T12 Pro"), BOARD_JUMPER_T12);
@@ -1289,18 +1254,35 @@ void registerOpenTxFirmwares()
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"));
firmware->addOption("flexr9m", Firmware::tr("Enable non certified R9M firmwares"));
firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module"));
addOpenTxFontOptions(firmware);
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX + AFHDS3);
/* 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"));
addOpenTxRfOptions(firmware, FLEX);
registerOpenTxFirmware(firmware);
/* Radiomaster TX16S board */
firmware = new OpenTxFirmware("opentx-tx16s", Firmware::tr("Radiomaster TX16s / TX16s Hall / TX16s 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});
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"));
registerOpenTxFirmware(firmware);
addOpenTxRfOptions(firmware, FLEX);
/* 9XR-Pro */
firmware = new OpenTxFirmware("opentx-9xrpro", Firmware::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO);
addOpenTxArm9xOptions(firmware, false);
@@ -1318,14 +1300,6 @@ void registerOpenTxFirmwares()
addOpenTxArm9xOptions(firmware);
registerOpenTxFirmware(firmware);
// These are kept only for import purposes, marked as deprecated to hide from UI.
registerOpenTxFirmware(new OpenTxFirmware("opentx-9xr", Firmware::tr("Turnigy 9XR"), BOARD_9X_M64), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-9xr128", Firmware::tr("Turnigy 9XR with m128 chip"), BOARD_9X_M128), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-9x", Firmware::tr("9X with stock board"), BOARD_9X_M64), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-9x128", Firmware::tr("9X with stock board and m128 chip"), BOARD_9X_M128), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-gruvin9x", Firmware::tr("9X with Gruvin9x board"), BOARD_GRUVIN9X), true);
registerOpenTxFirmware(new OpenTxFirmware("opentx-mega2560", Firmware::tr("DIY MEGA2560 radio"), BOARD_MEGA2560), true);
Firmware::setDefaultVariant(Firmware::getFirmwareForId("opentx-x9d+"));
Firmware::setCurrentVariant(Firmware::getDefaultVariant());
}
+1 -1
View File
@@ -116,7 +116,7 @@ void RadioData::convert(RadioDataConversionState & cstate)
}
}
if (IS_HORUS(cstate.toType)) {
if (IS_FAMILY_HORUS_OR_T16(cstate.toType)) {
fixModelFilenames();
}
+13 -221
View File
@@ -32,10 +32,7 @@
float RawSourceRange::getValue(int value)
{
if (IS_ARM(getCurrentBoard()))
return float(value) * step;
else
return min + float(value) * step;
return float(value) * step;
}
@@ -48,11 +45,10 @@ RawSourceRange RawSource::getRange(const ModelData * model, const GeneralSetting
RawSourceRange result;
Firmware * firmware = Firmware::getCurrentVariant();
Board::Type board = firmware->getBoard();
switch (type) {
case SOURCE_TYPE_TELEMETRY:
if (IS_ARM(board)) {
{
div_t qr = div(index, 3);
const SensorData & sensor = model->sensorData[qr.quot];
if (sensor.prec == 2)
@@ -65,192 +61,8 @@ RawSourceRange RawSource::getRange(const ModelData * model, const GeneralSetting
result.max = +30000 * result.step;
result.decimals = sensor.prec;
result.unit = sensor.unitString();
break;
}
else {
result.offset = -DBL_MAX;
switch (index) {
case TELEMETRY_SOURCE_TX_BATT:
result.step = 0.1;
result.decimals = 1;
result.max = 25.5;
result.unit = tr("V");
break;
case TELEMETRY_SOURCE_TX_TIME:
result.step = 60;
result.max = 24 * 60 * result.step - 60; // 23:59:00 with 1-minute resolution
result.unit = tr("s");
break;
case TELEMETRY_SOURCE_TIMER1:
case TELEMETRY_SOURCE_TIMER2:
case TELEMETRY_SOURCE_TIMER3:
result.step = 5;
result.max = 255 * result.step;
result.unit = tr("s");
break;
case TELEMETRY_SOURCE_RSSI_TX:
case TELEMETRY_SOURCE_RSSI_RX:
result.max = 100;
result.offset = 128;
break;
case TELEMETRY_SOURCE_A1_MIN:
case TELEMETRY_SOURCE_A2_MIN:
case TELEMETRY_SOURCE_A3_MIN:
case TELEMETRY_SOURCE_A4_MIN:
if (model) result = model->frsky.channels[index-TELEMETRY_SOURCE_A1_MIN].getRange();
break;
case TELEMETRY_SOURCE_A1:
case TELEMETRY_SOURCE_A2:
case TELEMETRY_SOURCE_A3:
case TELEMETRY_SOURCE_A4:
if (model) result = model->frsky.channels[index-TELEMETRY_SOURCE_A1].getRange();
break;
case TELEMETRY_SOURCE_ALT:
case TELEMETRY_SOURCE_ALT_MIN:
case TELEMETRY_SOURCE_ALT_MAX:
case TELEMETRY_SOURCE_GPS_ALT:
result.step = 8;
result.min = -500;
result.max = 1540;
if (firmware->getCapability(Imperial) || settings.imperial) {
result.step = (result.step * 105) / 32;
result.min = (result.min * 105) / 32;
result.max = (result.max * 105) / 32;
result.unit = tr("ft");
}
else {
result.unit = tr("m");
}
break;
case TELEMETRY_SOURCE_T1:
case TELEMETRY_SOURCE_T1_MAX:
case TELEMETRY_SOURCE_T2:
case TELEMETRY_SOURCE_T2_MAX:
result.min = -30;
result.max = 225;
result.unit = tr("°C");
break;
case TELEMETRY_SOURCE_HDG:
result.step = 2;
result.max = 360;
result.offset = 256;
result.unit = tr("°");
break;
case TELEMETRY_SOURCE_RPM:
case TELEMETRY_SOURCE_RPM_MAX:
result.step = 50;
result.max = 12750;
break;
case TELEMETRY_SOURCE_FUEL:
result.max = 100;
result.unit = tr("%");
break;
case TELEMETRY_SOURCE_ASPEED:
case TELEMETRY_SOURCE_ASPEED_MAX:
result.decimals = 1;
result.step = 2.0;
result.max = (2*255);
if (firmware->getCapability(Imperial) || settings.imperial) {
result.step *= 1.150779;
result.max *= 1.150779;
result.unit = tr("mph");
}
else {
result.step *= 1.852;
result.max *= 1.852;
result.unit = tr("km/h");
}
break;
case TELEMETRY_SOURCE_SPEED:
case TELEMETRY_SOURCE_SPEED_MAX:
result.step = 2;
result.max = (2*255);
if (firmware->getCapability(Imperial) || settings.imperial) {
result.step *= 1.150779;
result.max *= 1.150779;
result.unit = tr("mph");
}
else {
result.step *= 1.852;
result.max *= 1.852;
result.unit = tr("km/h");
}
break;
case TELEMETRY_SOURCE_VERTICAL_SPEED:
result.step = 0.1;
result.min = -12.5;
result.max = 13.0;
result.decimals = 1;
result.unit = tr("m/s");
break;
case TELEMETRY_SOURCE_DTE:
result.max = 30000;
break;
case TELEMETRY_SOURCE_DIST:
case TELEMETRY_SOURCE_DIST_MAX:
result.step = 8;
result.max = 2040;
result.unit = tr("m");
break;
case TELEMETRY_SOURCE_CELL:
case TELEMETRY_SOURCE_CELL_MIN:
result.step = 0.02;
result.max = 5.1;
result.decimals = 2;
result.unit = tr("V");
break;
case TELEMETRY_SOURCE_CELLS_SUM:
case TELEMETRY_SOURCE_CELLS_MIN:
case TELEMETRY_SOURCE_VFAS:
case TELEMETRY_SOURCE_VFAS_MIN:
result.step = 0.1;
result.max = 25.5;
result.decimals = 1;
result.unit = tr("V");
break;
case TELEMETRY_SOURCE_CURRENT:
case TELEMETRY_SOURCE_CURRENT_MAX:
result.step = 0.5;
result.max = 127.5;
result.decimals = 1;
result.unit = tr("A");
break;
case TELEMETRY_SOURCE_CONSUMPTION:
result.step = 100;
result.max = 25500;
result.unit = tr("mAh");
break;
case TELEMETRY_SOURCE_POWER:
case TELEMETRY_SOURCE_POWER_MAX:
result.step = 5;
result.max = 1275;
result.unit = tr("W");
break;
case TELEMETRY_SOURCE_ACCX:
case TELEMETRY_SOURCE_ACCY:
case TELEMETRY_SOURCE_ACCZ:
result.step = 0.01;
result.decimals = 2;
result.max = 2.55;
result.min = 0;
result.unit = tr("g");
break;
default:
result.max = 125;
break;
}
if (result.offset == -DBL_MAX) {
result.offset = result.max - (127*result.step);
}
if (flags & (RANGE_DELTA_FUNCTION | RANGE_ABS_FUNCTION)) {
result.offset = 0;
result.min = result.step * -127;
result.max = result.step * 127;
}
}
break;
case SOURCE_TYPE_LUA_OUTPUT:
result.max = 30000;
@@ -414,7 +226,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
return CHECK_IN_ARRAY(special, index);
case SOURCE_TYPE_TELEMETRY:
if (IS_ARM(board)) {
{
div_t qr = div(index, 3);
if (model)
result = model->sensorData[qr.quot].nameToString(qr.quot);
@@ -424,9 +236,6 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
result += (qr.rem == 1 ? "-" : "+");
return result;
}
else {
return CHECK_IN_ARRAY(telemetry, index);
}
case SOURCE_TYPE_GVAR:
if (model)
@@ -486,13 +295,7 @@ bool RawSource::isSlider(int * sliderIndex, Board::Type board) const
bool RawSource::isTimeBased(Board::Type board) const
{
if (board == Board::BOARD_UNKNOWN)
board = getCurrentBoard();
if (IS_ARM(board))
return (type == SOURCE_TYPE_SPECIAL && index > 0);
else
return (type==SOURCE_TYPE_TELEMETRY && (index==TELEMETRY_SOURCE_TX_TIME || index==TELEMETRY_SOURCE_TIMER1 || index==TELEMETRY_SOURCE_TIMER2 || index==TELEMETRY_SOURCE_TIMER3));
return (type == SOURCE_TYPE_SPECIAL && index > 0);
}
bool RawSource::isAvailable(const ModelData * const model, const GeneralSettings * const gs, Board::Type board) const
@@ -516,20 +319,9 @@ bool RawSource::isAvailable(const ModelData * const model, const GeneralSettings
return false;
if (type == SOURCE_TYPE_TELEMETRY) {
if (IS_ARM(board) && !model->sensorData[div(index, 3).quot].isAvailable()) {
if (!model->sensorData[div(index, 3).quot].isAvailable()) {
return false;
}
else if (!IS_ARM(board)) {
Firmware * fw = getCurrentFirmware();
if (type == (int)TELEMETRY_SOURCE_TX_TIME && !fw->getCapability(RtcTime))
return false;
if (type == (int)TELEMETRY_SOURCE_RAS && !fw->getCapability(SportTelemetry))
return false;
if (type == (int)TELEMETRY_SOURCE_TIMER3 && fw->getCapability(Timers) < 3)
return false;
}
}
}
@@ -580,13 +372,13 @@ RawSource RawSource::convert(RadioDataConversionState & cstate)
}
}
if (IS_TARANIS(cstate.toType) && IS_HORUS(cstate.fromType)) {
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_HORUS(cstate.toType) && IS_TARANIS(cstate.fromType) && index == 5)
else if (IS_FAMILY_HORUS_OR_T16(cstate.toType) && IS_TARANIS(cstate.fromType) && index == 5)
{
index = 6; // pot S2 to S2
}
@@ -602,7 +394,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate)
}
}
if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType))) {
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
@@ -615,7 +407,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate)
index = 5; // SH to SH
}
}
else if (IS_JUMPER_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType))) {
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
@@ -629,7 +421,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate)
}
}
// Compensate for SE and SG on X9/Horus board if converting from X7
else if ((IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) && IS_TARANIS_X7(cstate.fromType)) {
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
}
@@ -637,7 +429,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate)
index = 7; // SH to SH
}
}
else if ((IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) {
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
}
@@ -645,7 +437,7 @@ RawSource RawSource::convert(RadioDataConversionState & cstate)
index = 7; // SH to SH
}
}
else if ((IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) {
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
}
+3 -9
View File
@@ -159,10 +159,6 @@ enum TelemetrySource {
TELEMETRY_SOURCE_RESERVE = -1
};
#define TM_HASTELEMETRY 0x01
#define TM_HASOFFSET 0x02
#define TM_HASWSHH 0x04
enum RawSourceType {
SOURCE_TYPE_NONE,
SOURCE_TYPE_VIRTUAL_INPUT,
@@ -227,11 +223,7 @@ class RawSource {
AllSourceGroups = InputSourceGroups | GVarsGroup | TelemGroup | ScriptsGroup
};
RawSource():
type(SOURCE_TYPE_NONE),
index(0)
{
}
RawSource() { clear(); }
explicit RawSource(int value):
type(RawSourceType(abs(value)/65536)),
@@ -258,6 +250,8 @@ class RawSource {
bool isSlider(int * sliderIndex = NULL, Board::Type board = Board::BOARD_UNKNOWN) const;
bool isTimeBased(Board::Type board = Board::BOARD_UNKNOWN) const;
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; }
bool operator == ( const RawSource & other) const {
return (this->type == other.type) && (this->index == other.index);
+4 -4
View File
@@ -197,7 +197,7 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate)
}
// No SE and SG on X7 board
if (IS_TARANIS_X7(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType))) {
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)
@@ -211,7 +211,7 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate)
delta = 6; // SH to SH
}
}
else if (IS_JUMPER_T12(cstate.toType) && (IS_TARANIS_X9(cstate.fromType) || IS_HORUS(cstate.fromType))) {
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)
@@ -226,7 +226,7 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate)
}
}
// Compensate for SE and SG on X9/Horus board if converting from X7
else if ((IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) && IS_TARANIS_X7(cstate.fromType)) {
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
}
@@ -234,7 +234,7 @@ RawSwitch RawSwitch::convert(RadioDataConversionState & cstate)
delta = -6; // SH to SH
}
}
else if ((IS_TARANIS_X9(cstate.toType) || IS_HORUS(cstate.toType)) && IS_JUMPER_T12(cstate.fromType)) {
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
}
+3 -6
View File
@@ -65,11 +65,7 @@ class RawSwitch {
AllSwitchContexts = AllModelContexts | GlobalFunctionsContext
};
RawSwitch():
type(SWITCH_TYPE_NONE),
index(0)
{
}
RawSwitch() { clear(); }
explicit RawSwitch(int value):
type(RawSwitchType(abs(value)/256)),
@@ -91,6 +87,8 @@ class RawSwitch {
RawSwitch convert(RadioDataConversionState & cstate);
QString toString(Board::Type board = Board::BOARD_UNKNOWN, const GeneralSettings * const generalSettings = NULL, const ModelData * const modelData = NULL) const;
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; }
bool operator== ( const RawSwitch& other) const {
return (this->type == other.type) && (this->index == other.index);
@@ -100,7 +98,6 @@ class RawSwitch {
return (this->type != other.type) || (this->index != other.index);
}
RawSwitchType type;
int index;
};
+2
View File
@@ -82,6 +82,8 @@ QString SensorData::unitString() const
return tr("seconds");
case UNIT_CELLS:
return tr("V");
case UNIT_MILLILITERS_PER_MINUTE:
return tr("ml/minute");
default:
return "";
}
+19 -3
View File
@@ -74,10 +74,13 @@ class SensorData {
UNIT_METERS_PER_SECOND,
UNIT_FEET_PER_SECOND,
UNIT_KMH,
UNIT_SPEED = UNIT_KMH,
UNIT_MPH,
UNIT_METERS,
UNIT_DIST = UNIT_METERS,
UNIT_FEET,
UNIT_CELSIUS,
UNIT_TEMPERATURE = UNIT_CELSIUS,
UNIT_FAHRENHEIT,
UNIT_PERCENT,
UNIT_MAH,
@@ -90,18 +93,31 @@ class SensorData {
UNIT_RADIANS,
UNIT_MILLILITERS,
UNIT_FLOZ,
UNIT_MILLILITERS_PER_MINUTE,
UNIT_MAX = UNIT_MILLILITERS_PER_MINUTE,
UNIT_SPARE1,
UNIT_SPARE2,
UNIT_SPARE3,
UNIT_SPARE4,
UNIT_SPARE5,
UNIT_SPARE6,
UNIT_SPARE7,
UNIT_SPARE8,
UNIT_SPARE9,
UNIT_SPARE10,
UNIT_HOURS,
UNIT_MINUTES,
UNIT_SECONDS,
// FrSky format used for these fields, could be another format in the future
UNIT_FIRST_VIRTUAL,
UNIT_FIRST_VIRTUAL,
UNIT_CELLS = UNIT_FIRST_VIRTUAL,
UNIT_DATETIME,
UNIT_GPS,
UNIT_BITFIELD,
UNIT_TEXT,
// Internal units (not stored in sensor unit)
UNIT_GPS_LONGITUDE,
UNIT_GPS_LATITUDE,
UNIT_GPS_LONGITUDE_EW,
UNIT_GPS_LATITUDE_NS,
UNIT_DATETIME_YEAR,
UNIT_DATETIME_DAY_MONTH,
UNIT_DATETIME_HOUR_MIN,
-3
View File
@@ -48,9 +48,6 @@ RawSourceRange FrSkyChannelData::getRange() const
void FrSkyScreenData::clear()
{
memset(reinterpret_cast<void *>(this), 0, sizeof(FrSkyScreenData));
if (!IS_ARM(getCurrentBoard())) {
type = TELEMETRY_SCREEN_NUMBERS;
}
}
void FrSkyData::clear()
+2 -3
View File
@@ -21,7 +21,6 @@
#include "flashfirmwaredialog.h"
#include "ui_flashfirmwaredialog.h"
#include "appdata.h"
#include "process_flash.h"
#include "helpers.h"
#include "progressdialog.h"
#include "radiointerface.h"
@@ -112,7 +111,7 @@ void FlashFirmwareDialog::updateUI()
}
QImage image;
switch(imageSource) {
switch (imageSource) {
case FIRMWARE:
ui->useFirmwareSplash->setChecked(true);
image = firmware.getSplash();
@@ -202,7 +201,7 @@ void FlashFirmwareDialog::on_useExternalSplash_clicked()
void FlashFirmwareDialog::on_useLibrarySplash_clicked()
{
QString fileName;
SplashLibraryDialog *ld = new SplashLibraryDialog(this, &fileName);
auto ld = new SplashLibraryDialog(this, &fileName);
ld->exec();
if (!fileName.isEmpty()) {
QImage image(fileName);
+1 -3
View File
@@ -56,9 +56,7 @@ GeneralEdit::GeneralEdit(QWidget * parent, RadioData & radioData, Firmware * fir
}
addTab(new GeneralSetupPanel(this, generalSettings, firmware), tr("Setup"));
if (IS_ARM(firmware->getBoard())) {
addTab(new CustomFunctionsPanel(this, NULL, generalSettings, firmware), tr("Global Functions"));
}
addTab(new CustomFunctionsPanel(this, NULL, generalSettings, firmware), 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"));
+12 -17
View File
@@ -191,12 +191,18 @@ ui(new Ui::GeneralSetup)
ui->label_BLBright->hide();
}
if (!IS_HORUS(firmware->getBoard())) {
if (!IS_FAMILY_HORUS_OR_T16(firmware->getBoard())) {
ui->OFFBright_SB->hide();
ui->OFFBright_SB->setDisabled(true);
ui->label_OFFBright->hide();
}
if (!IS_JUMPER_T18(firmware->getBoard())) {
ui->keysBl_ChkB->hide();
ui->keysBl_ChkB->setDisabled(true);
ui->label_KeysBl->hide();
}
if (!firmware->getCapability(SoundMod)) {
ui->soundModeCB->setDisabled(true);
ui->label_soundMode->hide();
@@ -234,14 +240,9 @@ ui(new Ui::GeneralSetup)
ui->memwarnChkB->setChecked(!generalSettings.disableMemoryWarning); // Default is zero=checked
ui->alarmwarnChkB->setChecked(!generalSettings.disableAlarmWarning); // Default is zero=checked
if (IS_ARM(firmware->getBoard())) {
ui->rssiPowerOffWarnChkB->setChecked(!generalSettings.disableRssiPoweroffAlarm); // Default is zero=checked
}
else {
ui->rssiPowerOffWarnChkB->hide();
}
ui->rssiPowerOffWarnChkB->setChecked(!generalSettings.disableRssiPoweroffAlarm); // Default is zero=checked
if (IS_HORUS(firmware->getBoard())) {
if (IS_FAMILY_HORUS_OR_T16(firmware->getBoard())) {
ui->splashScreenChkB->hide();
ui->splashScreenDuration->hide();
ui->splashScreenLabel->hide();
@@ -302,13 +303,7 @@ ui(new Ui::GeneralSetup)
ui->backlightColor2_label->hide();
}
if (IS_ARM(firmware->getBoard())) {
ui->switchesDelay->setValue(10*(generalSettings.switchesDelay+15));
}
else {
ui->switchesDelay->hide();
ui->switchesDelayLabel->hide();
}
ui->switchesDelay->setValue(10*(generalSettings.switchesDelay+15));
ui->blAlarm_ChkB->setChecked(generalSettings.flashBeep);
if (!firmware->getCapability(HasBatMeterRange)) {
@@ -750,11 +745,11 @@ void GeneralSetupPanel::on_blAlarm_ChkB_stateChanged()
emit modified();
}
void GeneralSetupPanel::on_ownerID_editingFinished()
void GeneralSetupPanel::on_registrationId_editingFinished()
{
//copy ownerID back to generalSettings.registrationId
QByteArray array = ui->registrationId->text().toLocal8Bit();
strncpy(generalSettings.registrationId, "pafleraf", 9);
strncpy(generalSettings.registrationId, array, 8);
generalSettings.registrationId[8] = '\0';
emit modified();
}
+1 -1
View File
@@ -87,7 +87,7 @@ class GeneralSetupPanel : public GeneralPanel
void on_vBatMinDSB_editingFinished();
void on_vBatMaxDSB_editingFinished();
void on_contrastSB_editingFinished();
void on_ownerID_editingFinished();
void on_registrationId_editingFinished();
void on_pwrOnDelay_valueChanged();
void on_pwrOffDelay_valueChanged();
+402 -388
View File
@@ -554,348 +554,13 @@
</item>
<item row="0" column="3">
<layout class="QGridLayout" name="gridLayout_3" columnstretch="0,0">
<item row="2" column="1">
<widget class="QSpinBox" name="volume_SB">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>23</number>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="re_label">
<property name="text">
<string>RotEnc Navigation</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="blAlarm_ChkB">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="stickReverseLB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Stick reverse</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="backlightswCB">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>This is the switch selectrion for turning on the backlight (if installed).
</string>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="blAlarm_LB">
<property name="text">
<string>Backlight flash on alarm</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Backlight Auto OFF after</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Backlight Switch</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="varioR0_SB">
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>200</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>500</number>
</property>
</widget>
</item>
<item row="18" column="0">
<widget class="QLabel" name="VoiceLang_label">
<property name="text">
<string>Voice Language</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="varioP0_SB">
<property name="suffix">
<string> Hz</string>
</property>
<property name="minimum">
<number>300</number>
</property>
<property name="maximum">
<number>1100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>700</number>
</property>
</widget>
</item>
<item row="14" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="stickReverse1">
<property name="text">
<string notr="true">1</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="stickReverse2">
<property name="text">
<string notr="true">2</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="stickReverse3">
<property name="text">
<string notr="true">3</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="stickReverse4">
<property name="text">
<string notr="true">4</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0">
<widget class="QLabel" name="varioR0_label">
<property name="text">
<string>Vario repeat at zero</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="varioP0_label">
<property name="text">
<string>Vario pitch at zero</string>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="label_faimode">
<property name="text">
<string>FAI Mode</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_OFFBright">
<property name="text">
<string>Backlight OFF Brightness</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QSpinBox" name="BLBright_SB">
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QSpinBox" name="backlightautoSB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>If this value is not 0, any keypress will turn on the backlight and turn it off after the specified number of seconds.</string>
</property>
<property name="suffix">
<string> sec</string>
</property>
<property name="maximum">
<number>600</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="speakerPitchSB">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;LCD Screen Contrast&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Values can be 20-45&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="varioPMax_SB">
<property name="suffix">
<string> Hz</string>
</property>
<property name="minimum">
<number>1300</number>
</property>
<property name="maximum">
<number>2900</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>1700</number>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="label_timezone">
<property name="text">
<string>Timeshift from UTC</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QSpinBox" name="OFFBright_SB">
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="QComboBox" name="countrycode_CB">
<item>
<property name="text">
<string>America</string>
</property>
</item>
<item>
<property name="text">
<string>Japan</string>
</property>
</item>
<item>
<property name="text">
<string>Europe</string>
</property>
</item>
</widget>
</item>
<item row="15" column="1">
<widget class="QCheckBox" name="faimode_CB">
<property name="toolTip">
<string>If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="soundModeCB">
<item>
<property name="text">
<string>Beeper</string>
</property>
</item>
<item>
<property name="text">
<string>Speaker</string>
</property>
</item>
<item>
<property name="text">
<string>BeeperVoice</string>
</property>
</item>
<item>
<property name="text">
<string>SpeakerVoice</string>
</property>
</item>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_BLBright">
<property name="text">
<string>Backlight Brightness</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<layout class="QGridLayout" name="gridLayout_9" columnstretch="1,0,1,0">
<item row="0" column="0">
@@ -992,24 +657,288 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</item>
<item row="12" column="0">
<widget class="QLabel" name="backlightColor_label">
<item row="19" column="1">
<widget class="QComboBox" name="voiceLang_CB"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_soundMode">
<property name="text">
<string>Backlight color</string>
<string>Sound Mode</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="varioPMax_label">
<item row="9" column="1">
<widget class="QCheckBox" name="blAlarm_ChkB">
<property name="text">
<string>Vario pitch at max</string>
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_speakerPitch">
<item row="15" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="stickReverse1">
<property name="text">
<string notr="true">1</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="stickReverse2">
<property name="text">
<string notr="true">2</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="stickReverse3">
<property name="text">
<string notr="true">3</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="stickReverse4">
<property name="text">
<string notr="true">4</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="backlightswCB">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>This is the switch selectrion for turning on the backlight (if installed).
</string>
</property>
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="varioP0_SB">
<property name="suffix">
<string> Hz</string>
</property>
<property name="minimum">
<number>300</number>
</property>
<property name="maximum">
<number>1100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>700</number>
</property>
</widget>
</item>
<item row="21" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="varioR0_SB">
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>200</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>500</number>
</property>
</widget>
</item>
<item row="15" column="0">
<widget class="QLabel" name="stickReverseLB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Speaker Pitch (spkr only)</string>
<string>Stick reverse</string>
</property>
</widget>
</item>
<item row="20" column="1">
<widget class="QLineEdit" name="registrationId">
<property name="inputMask">
<string>nnnnnnNN</string>
</property>
<property name="maxLength">
<number>8</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="soundModeCB">
<item>
<property name="text">
<string>Beeper</string>
</property>
</item>
<item>
<property name="text">
<string>Speaker</string>
</property>
</item>
<item>
<property name="text">
<string>BeeperVoice</string>
</property>
</item>
<item>
<property name="text">
<string>SpeakerVoice</string>
</property>
</item>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_OFFBright">
<property name="text">
<string>Backlight OFF Brightness</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="volume_SB">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>23</number>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="re_label">
<property name="text">
<string>RotEnc Navigation</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QSpinBox" name="OFFBright_SB">
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Backlight Switch</string>
</property>
</widget>
</item>
<item row="17" column="1">
<widget class="QComboBox" name="countrycode_CB">
<item>
<property name="text">
<string>America</string>
</property>
</item>
<item>
<property name="text">
<string>Japan</string>
</property>
</item>
<item>
<property name="text">
<string>Europe</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="varioP0_label">
<property name="text">
<string>Vario pitch at zero</string>
</property>
</widget>
</item>
<item row="16" column="1">
<widget class="QCheckBox" name="faimode_CB">
<property name="toolTip">
<string>If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio.</string>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Backlight Auto OFF after</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="varioPMax_SB">
<property name="suffix">
<string> Hz</string>
</property>
<property name="minimum">
<number>1300</number>
</property>
<property name="maximum">
<number>2900</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>1700</number>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QSpinBox" name="BLBright_SB">
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="16" column="0">
<widget class="QLabel" name="label_faimode">
<property name="text">
<string>FAI Mode</string>
</property>
</widget>
</item>
@@ -1044,31 +973,56 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</item>
<item row="16" column="0">
<item row="12" column="0">
<widget class="QLabel" name="backlightColor_label">
<property name="text">
<string>Backlight color</string>
</property>
</widget>
</item>
<item row="20" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Owner Registration ID</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QSpinBox" name="backlightautoSB">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>If this value is not 0, any keypress will turn on the backlight and turn it off after the specified number of seconds.</string>
</property>
<property name="suffix">
<string> sec</string>
</property>
<property name="maximum">
<number>600</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
</widget>
</item>
<item row="17" column="0">
<widget class="QLabel" name="countrycode_label">
<property name="text">
<string>Country Code</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QComboBox" name="re_CB"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_soundMode">
<property name="text">
<string>Sound Mode</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_volume">
<property name="text">
<string>Speaker Volume</string>
</property>
</widget>
</item>
<item row="17" column="1">
<item row="18" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="timezoneSB">
@@ -1098,36 +1052,96 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</item>
<item row="18" column="1">
<widget class="QComboBox" name="voiceLang_CB"/>
</item>
<item row="20" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="19" column="0">
<widget class="QLabel" name="label">
<item row="10" column="0">
<widget class="QLabel" name="label_BLBright">
<property name="text">
<string>Owner Registration ID</string>
<string>Backlight Brightness</string>
</property>
</widget>
</item>
<item row="19" column="1">
<widget class="QLineEdit" name="registrationId">
<property name="inputMask">
<string>aaaaaaAA</string>
<item row="6" column="0">
<widget class="QLabel" name="varioR0_label">
<property name="text">
<string>Vario repeat at zero</string>
</property>
<property name="maxLength">
<number>8</number>
</widget>
</item>
<item row="19" column="0">
<widget class="QLabel" name="VoiceLang_label">
<property name="text">
<string>Voice Language</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="blAlarm_LB">
<property name="text">
<string>Backlight flash on alarm</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="varioPMax_label">
<property name="text">
<string>Vario pitch at max</string>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QComboBox" name="re_CB"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_speakerPitch">
<property name="text">
<string>Speaker Pitch (spkr only)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_volume">
<property name="text">
<string>Speaker Volume</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="speakerPitchSB">
<property name="toolTip">
<string/>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;LCD Screen Contrast&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Values can be 20-45&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_KeysBl">
<property name="text">
<string>Keys Backlight</string>
</property>
</widget>
</item>
<item row="13" column="1">
<widget class="QCheckBox" name="keysBl_ChkB">
<property name="text">
<string/>
</property>
</widget>
</item>
+2 -2
View File
@@ -172,7 +172,7 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
ui->txCurrentCalibrationLabel->hide();
}
if (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board)|| IS_TARANIS_X9E(board) || IS_HORUS(board)) {
if (IS_TARANIS_X7(board) || IS_TARANIS_XLITE(board)|| IS_TARANIS_X9E(board) || IS_TARANIS_X9DP_2019(board) || IS_FAMILY_HORUS_OR_T16(board)) {
ui->bluetoothMode->addItem(tr("OFF"), 0);
if (IS_TARANIS_X9E(board)) {
ui->bluetoothMode->addItem(tr("Enabled"), 1);
@@ -189,7 +189,7 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
ui->bluetoothWidget->hide();
}
if ((IS_HORUS(board) && board != Board::BOARD_X10_EXPRESS) || (IS_TARANIS_XLITE(board) && !IS_TARANIS_XLITES(board))) {
if ((IS_FAMILY_HORUS_OR_T16(board) && board != Board::BOARD_X10_EXPRESS) || (IS_TARANIS_XLITE(board) && !IS_TARANIS_XLITES(board))) {
ui->antennaMode->addItem(tr("Internal"), -2);
ui->antennaMode->addItem(tr("Ask"), -1);
ui->antennaMode->addItem(tr("Per model"), 0);
+4 -1
View File
@@ -565,7 +565,6 @@ QPixmap makePixMap(const QImage & image)
return QPixmap::fromImage(result);
}
int version2index(const QString & version)
{
int result = 999;
@@ -581,6 +580,10 @@ int version2index(const QString & version)
result = parts[1].toInt(); // nightly build up to 899
mainVersion = parts[0];
}
else if (version.contains("-")) {
parts = version.split("-");
mainVersion = parts[0];
}
parts = mainVersion.split('.');
if (parts.size() > 2)
result += 1000 * parts[2].toInt();
Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

-500
View File
@@ -1,500 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>preferencesDialog</class>
<widget class="QDialog" name="preferencesDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>685</width>
<height>432</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>685</width>
<height>0</height>
</size>
</property>
<property name="windowTitle">
<string>Preferences</string>
</property>
<layout class="QGridLayout" name="gridLayout_4" columnstretch="1">
<property name="sizeConstraint">
<enum>QLayout::SetMinimumSize</enum>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="margin">
<number>4</number>
</property>
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>8</number>
</property>
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1">
<widget class="QLineEdit" name="snapshotPath">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Simu BackLight</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>Simulator capture folder</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Joystick</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Remember simulator switches</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="simuSW">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QComboBox" name="joystickCB">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="joystickChkB">
<property name="text">
<string>Enable</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="snapshotClipboardCKB">
<property name="text">
<string>Use clipboard only</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="joystickcalButton">
<property name="text">
<string>Calibrate</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="backLightColor">
<item>
<property name="text">
<string>Blue</string>
</property>
</item>
<item>
<property name="text">
<string>Green</string>
</property>
</item>
<item>
<property name="text">
<string>Red</string>
</property>
</item>
<item>
<property name="text">
<string>Orange</string>
</property>
</item>
<item>
<property name="text">
<string>Yellow</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="2">
<widget class="QPushButton" name="snapshotPathButton">
<property name="text">
<string>Open Folder</string>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_7">
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Personal splash library</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLineEdit" name="libraryPath">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="libraryPathButton">
<property name="text">
<string>Open Folder</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QComboBox" name="splashincludeCB">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Include companion splashes</string>
</property>
</item>
<item>
<property name="text">
<string>Only user defined splashes</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Splash library behaviour</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Custom TX splash screen</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLineEdit" name="SplashFileName">
<property name="enabled">
<bool>true</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="SplashSelect">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Open Image</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QToolButton" name="SplashLibraryDialogButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="clearImageButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="InvertPixels">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Invert Pixels</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="imageLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>64</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>64</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>backLightColor</tabstop>
<tabstop>joystickCB</tabstop>
<tabstop>joystickChkB</tabstop>
<tabstop>joystickcalButton</tabstop>
<tabstop>simuSW</tabstop>
<tabstop>snapshotPath</tabstop>
<tabstop>snapshotPathButton</tabstop>
<tabstop>snapshotClipboardCKB</tabstop>
<tabstop>libraryPath</tabstop>
<tabstop>libraryPathButton</tabstop>
<tabstop>splashincludeCB</tabstop>
<tabstop>SplashFileName</tabstop>
<tabstop>SplashSelect</tabstop>
<tabstop>SplashLibraryDialogButton</tabstop>
<tabstop>clearImageButton</tabstop>
<tabstop>InvertPixels</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources>
<include location="companion.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>preferencesDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>370</x>
<y>49</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>preferencesDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>390</x>
<y>55</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+1 -1
View File
@@ -761,7 +761,7 @@ void LogsDialog::setFlightSessions()
int noSesions = sessions.size()-1;
QString label = QString("%1 ").arg(noSesions);
label += tr(noSesions > 1 ? "sessions" : "session");
label += " <" + tr("total duration ") + generateDuration(getRecordTimeStamp(1), getRecordTimeStamp(n-1)) + ">";
label += " <" + tr("time span") + generateDuration(getRecordTimeStamp(1), getRecordTimeStamp(n-1)) + ">";
ui->sessions_CB->addItem(label);
// add individual sessions
+51 -38
View File
@@ -26,7 +26,6 @@
#include "apppreferencesdialog.h"
#include "fwpreferencesdialog.h"
#include "firmwareinterface.h"
#include "fusesdialog.h"
#include "downloaddialog.h"
#include "printdialog.h"
#include "version.h"
@@ -49,6 +48,7 @@
#include "translations.h"
#include "dialogs/filesyncdialog.h"
#include "profilechooser.h"
#include <QtGui>
#include <QFileInfo>
@@ -130,10 +130,16 @@ MainWindow::MainWindow():
else {
if (!g.previousVersion().isEmpty())
g.warningId(g.warningId() | AppMessages::MSG_UPGRADED);
if (checkProfileRadioExists(g.sessionId()))
QTimer::singleShot(updateDelay, this, SLOT(doAutoUpdates()));
else
g.warningId(g.warningId() | AppMessages::MSG_NO_RADIO_TYPE);
if (g.promptProfile()) {
QTimer::singleShot(updateDelay, this, SLOT(chooseProfile())); // add an extra second to give mainwindow time to load
updateDelay += 5000; // give user time to select profile before warnings
}
else {
if (checkProfileRadioExists(g.sessionId()))
QTimer::singleShot(updateDelay, this, SLOT(doAutoUpdates()));
else
g.warningId(g.warningId() | AppMessages::MSG_NO_RADIO_TYPE);
}
}
QTimer::singleShot(updateDelay, this, SLOT(displayWarnings()));
@@ -353,7 +359,6 @@ void MainWindow::checkForCompanionUpdateFinished(QNetworkReply * reply)
return onUpdatesError(tr("Companion update check failed, new version information not found."));
int webVersion = version2index(version);
int ownVersion = version2index(VERSION);
if (ownVersion < webVersion) {
@@ -468,7 +473,7 @@ void MainWindow::checkForFirmwareUpdateFinished(QNetworkReply * reply)
const QString errorString = seekCodeString(qba, "ERROR");
const QString blockedRadios = seekCodeString(qba, "BLOCK");
long version;
if (errorString == "NO_RC")
return onUpdatesError(tr("No firmware release candidates are currently being served for this version, please switch release channel"));
else if (errorString == "NO_NIGHTLY")
@@ -481,7 +486,7 @@ void MainWindow::checkForFirmwareUpdateFinished(QNetworkReply * reply)
msgbox.setText(tr("Release candidate builds are now available for this version, would you like to switch to using them?"));
msgbox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgbox.setDefaultButton(QMessageBox::Yes);
if(msgbox.exec() == QMessageBox::Yes) {
g.OpenTxBranch(AppData::DownloadBranchType(AppData::BRANCH_RC_TESTING));
return onUpdatesError(tr("Channel changed to RC, please restart the download process"));
@@ -493,7 +498,7 @@ void MainWindow::checkForFirmwareUpdateFinished(QNetworkReply * reply)
msgbox.setText(tr("Official release builds are now available for this version, would you like to switch to using them?"));
msgbox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgbox.setDefaultButton(QMessageBox::Yes);
if(msgbox.exec() == QMessageBox::Yes) {
g.OpenTxBranch(AppData::DownloadBranchType(AppData::BRANCH_RELEASE_STABLE));
return onUpdatesError(tr("Channel changed to Release, please restart the download process"));
@@ -916,26 +921,25 @@ void MainWindow::changelog()
void MainWindow::customizeSplash()
{
CustomizeSplashDialog * dialog = new CustomizeSplashDialog(this);
auto * dialog = new CustomizeSplashDialog(this);
dialog->exec();
dialog->deleteLater();
}
void MainWindow::writeEeprom()
{
if (activeMdiChild()) activeMdiChild()->writeEeprom();
if (activeMdiChild())
activeMdiChild()->writeEeprom();
}
void MainWindow::readEeprom()
{
Board::Type board = getCurrentBoard();
QString tempFile;
if (IS_HORUS(board))
if (IS_FAMILY_HORUS_OR_T16(board))
tempFile = generateProcessUniqueTempFileName("temp.otx");
else if (IS_ARM(board))
tempFile = generateProcessUniqueTempFileName("temp.bin");
else
tempFile = generateProcessUniqueTempFileName("temp.hex");
tempFile = generateProcessUniqueTempFileName("temp.bin");
qDebug() << "MainWindow::readEeprom(): using temp file: " << tempFile;
@@ -975,7 +979,7 @@ bool MainWindow::readEepromFromRadio(const QString & filename)
void MainWindow::writeBackup()
{
if (IS_HORUS(getCurrentBoard())) {
if (IS_FAMILY_HORUS_OR_T16(getCurrentBoard())) {
QMessageBox::information(this, CPN_STR_APP_NAME, tr("This function is not yet implemented"));
return;
// TODO implementation
@@ -992,7 +996,7 @@ void MainWindow::writeFlash(QString fileToFlash)
void MainWindow::readBackup()
{
if (IS_HORUS(getCurrentBoard())) {
if (IS_FAMILY_HORUS_OR_T16(getCurrentBoard())) {
QMessageBox::information(this, CPN_STR_APP_NAME, tr("This function is not yet implemented"));
return;
// TODO implementation
@@ -1022,14 +1026,6 @@ void MainWindow::burnConfig()
void MainWindow::burnList()
{
burnConfigDialog bcd(this);
bcd.listAvrdudeProgrammers();
}
void MainWindow::burnFuses()
{
FusesDialog *fd = new FusesDialog(this);
fd->exec();
delete fd;
}
void MainWindow::compare()
@@ -1058,7 +1054,7 @@ void MainWindow::about()
aboutStr.append("<br/><br/>");
aboutStr.append(QString("Version %1, %2").arg(VERSION).arg(__DATE__));
aboutStr.append("<br/><br/>");
aboutStr.append(tr("Copyright OpenTX Team") + "<br/>&copy; 2011-2019<br/>");
aboutStr.append(tr("Copyright OpenTX Team") + QString("<br/>&copy; 2011-%1<br/>").arg(QString(__DATE__).right(4)));
QMessageBox msgBox(this);
msgBox.setWindowIcon(CompanionIcon("information.png"));
msgBox.setWindowTitle(tr("About Companion"));
@@ -1078,9 +1074,15 @@ void MainWindow::updateMenus()
compareAct->setEnabled(activeChild);
writeEepromAct->setEnabled(activeChild);
readEepromAct->setEnabled(true);
writeBUToRadioAct->setEnabled(true);
readBUToFileAct->setEnabled(true);
editSplashAct->setDisabled(IS_HORUS(getCurrentBoard()));
if (IS_FAMILY_HORUS_OR_T16(getCurrentBoard())) {
writeBUToRadioAct->setEnabled(false);
readBUToFileAct->setEnabled(false);
}
else {
writeBUToRadioAct->setEnabled(true);
readBUToFileAct->setEnabled(true);
}
editSplashAct->setDisabled(IS_FAMILY_HORUS_OR_T16(getCurrentBoard()));
foreach (QAction * act, fileWindowActions) {
if (!act)
@@ -1219,8 +1221,6 @@ void MainWindow::retranslateUi(bool showMsg)
trAct(changelogAct, tr("Release notes..."), tr("Show release notes"));
trAct(compareAct, tr("Compare Models..."), tr("Compare models"));
trAct(editSplashAct, tr("Edit Radio Splash Image..."), tr("Edit the splash image of your Radio"));
trAct(burnListAct, tr("List programmers..."), tr("List available programmers"));
trAct(burnFusesAct, tr("Fuses..."), tr("Show fuses dialog"));
trAct(readFlashAct, tr("Read Firmware from Radio"), tr("Read firmware from Radio"));
trAct(writeFlashAct, tr("Write Firmware to Radio"), tr("Write firmware to Radio"));
trAct(sdsyncAct, tr("Synchronize SD"), tr("SD card synchronization"));
@@ -1282,14 +1282,14 @@ void MainWindow::createActions()
editSplashAct = addAct("paintbrush.png", SLOT(customizeSplash()));
burnListAct = addAct("list.png", SLOT(burnList()));
burnFusesAct = addAct("fuses.png", SLOT(burnFuses()));
readFlashAct = addAct("read_flash.png", SLOT(readFlash()));
writeFlashAct = addAct("write_flash.png", SLOT(writeFlash()));
writeEepromAct = addAct("write_eeprom.png", SLOT(writeEeprom()));
readEepromAct = addAct("read_eeprom.png", SLOT(readEeprom()));
burnConfigAct = addAct("configure.png", SLOT(burnConfig()));
writeBUToRadioAct = addAct("write_eeprom_file.png", SLOT(writeBackup()));
readBUToFileAct = addAct("read_eeprom_file.png", SLOT(readBackup()));
writeBUToRadioAct = addAct("write_eeprom_file.png", SLOT(writeBackup()));
readBUToFileAct = addAct("read_eeprom_file.png", SLOT(readBackup()));
createProfileAct = addAct("new.png", SLOT(createProfile()));
copyProfileAct = addAct("copy.png", SLOT(copyProfile()));
@@ -1386,10 +1386,6 @@ void MainWindow::createMenus()
burnMenu->addAction(readFlashAct);
burnMenu->addSeparator();
burnMenu->addSeparator();
if (!IS_ARM(getCurrentBoard())) {
burnMenu->addAction(burnFusesAct);
burnMenu->addAction(burnListAct);
}
windowMenu = menuBar()->addMenu("");
windowMenu->addAction(actTabbedWindows);
@@ -1799,3 +1795,20 @@ void MainWindow::autoClose()
{
this->close();
}
void MainWindow::chooseProfile()
{
QMap<int, QString> active;
active = g.getActiveProfiles();
if (active.size() > 1) {
ProfileChooserDialog *pcd = new ProfileChooserDialog(this);
connect(pcd, &ProfileChooserDialog::profileChanged, this, &MainWindow::loadProfileId);
pcd->exec();
delete pcd;
// doi here as need to wait until dialog dismissed and current radio type is set
if (checkProfileRadioExists(g.sessionId()))
doAutoUpdates();
else
g.warningId(g.warningId() | AppMessages::MSG_NO_RADIO_TYPE);
}
}
+1 -2
View File
@@ -111,7 +111,6 @@ class MainWindow : public QMainWindow
void readBackup();
void burnConfig();
void burnList();
void burnFuses();
void contributors();
void sdsync();
void changelog();
@@ -128,6 +127,7 @@ class MainWindow : public QMainWindow
void exportSettings();
void importSettings();
void autoClose();
void chooseProfile();
void openUpdatesWaitDialog();
void closeUpdatesWaitDialog();
@@ -209,7 +209,6 @@ class MainWindow : public QMainWindow
QAction *readEepromAct;
QAction *burnConfigAct;
QAction *burnListAct;
QAction *burnFusesAct;
QAction *writeFlashAct;
QAction *readFlashAct;
QAction *writeBUToRadioAct;
+7 -7
View File
@@ -534,7 +534,7 @@ void MdiChild::initModelsList()
connect(modelsListModel, &QAbstractItemModel::dataChanged, this, &MdiChild::onDataChanged);
ui->modelsList->setModel(modelsListModel);
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
ui->modelsList->setIndentation(20);
// ui->modelsList->resetIndentation(); // introduced in next Qt versions ...
}
@@ -1490,18 +1490,18 @@ bool MdiChild::convertStorage(Board::Type from, Board::Type to, bool newFile)
isUntitled = true;
if (cstate.hasLogEntries(RadioDataConversionState::EVT_INF)) {
QDialog * msgBox = new QDialog(Q_NULLPTR, Qt::Dialog | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
auto * msgBox = new QDialog(Q_NULLPTR, Qt::Dialog | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
ExportableTableView * tv = new ExportableTableView(msgBox);
auto * tv = new ExportableTableView(msgBox);
tv->setSortingEnabled(true);
tv->verticalHeader()->hide();
tv->setModel(cstate.getLogModel(RadioDataConversionState::EVT_INF, tv));
tv->resizeColumnsToContents();
tv->resizeRowsToContents();
QDialogButtonBox * btnBox = new QDialogButtonBox(QDialogButtonBox::Ok, this);
auto * btnBox = new QDialogButtonBox(QDialogButtonBox::Ok, this);
QVBoxLayout * lo = new QVBoxLayout(msgBox);
auto * lo = new QVBoxLayout(msgBox);
lo->addWidget(new QLabel(tr("<b>The conversion generated some important messages, please review them below.</b>")));
lo->addWidget(tv);
lo->addWidget(btnBox);
@@ -1531,12 +1531,12 @@ int MdiChild::askQuestion(const QString & msg, QMessageBox::StandardButtons butt
void MdiChild::writeEeprom() // write to Tx
{
Board::Type board = getCurrentBoard();
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
QString radioPath = findMassstoragePath("RADIO", true);
qDebug() << "Searching for SD card, found" << radioPath;
if (radioPath.isEmpty()) {
qDebug() << "MdiChild::writeEeprom(): Horus radio not found";
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Unable to find Horus radio SD card!"));
QMessageBox::critical(this, CPN_STR_TTL_ERROR, tr("Unable to find radio SD card!"));
return;
}
if (saveFile(radioPath, false)) {
-1
View File
@@ -42,7 +42,6 @@ set(modeledit_UIS
setup_timer.ui
setup_module.ui
flightmode.ui
telemetry_analog.ui
telemetry_customscreen.ui
telemetry_sensor.ui
)
+93 -70
View File
@@ -45,7 +45,7 @@ LimitsGroup::LimitsGroup(Firmware * firmware, TableLayout * tableLayout, int row
spinbox->setSuffix("%");
}
if (IS_ARM(board) || deflt == 0 /*it's the offset*/) {
if (deflt == 0 /*it's the offset*/) {
spinbox->setDecimals(1);
}
else {
@@ -120,7 +120,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
s1.report("header");
for (int i=0; i<chnCapability; i++) {
for (int i = 0; i < chnCapability; i++) {
int col = 0;
// Channel label
@@ -131,7 +131,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
label->setContextMenuPolicy(Qt::CustomContextMenu);
label->setToolTip(tr("Popup menu available"));
label->setMouseTracking(true);
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(chn_customContextMenuRequested(QPoint)));
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint)));
tableLayout->addWidget(i, col++, label);
// Channel name
@@ -204,7 +204,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
Channels::~Channels()
{
// compiler warning if delete[]
for (int i=0; i<CPN_MAX_CHNOUT;i++) {
for (int i = 0; i < CPN_MAX_CHNOUT; i++) {
delete name[i];
delete chnOffset[i];
delete chnMin[i];
@@ -240,7 +240,7 @@ void Channels::refreshExtendedLimits()
{
int channelMax = model->getChannelsMax();
for (int i=0 ; i<CPN_MAX_CHNOUT; i++) {
for (int i = 0 ; i < CPN_MAX_CHNOUT; i++) {
chnOffset[i]->updateMinMax(10 * channelMax);
chnMin[i]->updateMinMax(10 * channelMax);
chnMax[i]->updateMinMax(10 * channelMax);
@@ -280,7 +280,7 @@ void Channels::ppmcenterEdited()
void Channels::update()
{
for (int i=0; i<chnCapability; i++) {
for (int i = 0; i < chnCapability; i++) {
updateLine(i);
}
}
@@ -298,7 +298,7 @@ void Channels::updateLine(int i)
if (IS_HORUS_OR_TARANIS(firmware->getBoard())) {
int numcurves = firmware->getCapability(NumCurves);
curveCB[i]->clear();
for (int j=-numcurves; j<=numcurves; j++) {
for (int j = -numcurves; j <= numcurves; j++) {
curveCB[i]->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(model, false), j);
}
curveCB[i]->setCurrentIndex(model->limitData[i].curve.value + numcurves);
@@ -312,118 +312,140 @@ void Channels::updateLine(int i)
lock = false;
}
void Channels::chnPaste()
void Channels::cmPaste()
{
const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
if (mimeData->hasFormat(MIMETYPE_CHN)) {
QByteArray chnData = mimeData->data(MIMETYPE_CHN);
LimitData *chn = &model->limitData[selectedChannel];
memcpy(chn, chnData.constData(), sizeof(LimitData));
updateLine(selectedChannel);
QByteArray data;
if (hasClipboardData(&data)) {
memcpy(&model->limitData[selectedIndex], data.constData(), sizeof(LimitData));
updateLine(selectedIndex);
emit modified();
}
}
void Channels::chnDelete()
void Channels::cmDelete()
{
int maxidx = chnCapability - 1;
for (int i=selectedChannel; i<maxidx; i++) {
if (!model->limitData[i].isEmpty() || !model->limitData[i+1].isEmpty()) {
LimitData *chn1 = &model->limitData[i];
LimitData *chn2 = &model->limitData[i+1];
memcpy(chn1, chn2, sizeof(LimitData));
updateLine(i);
}
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
memmove(&model->limitData[selectedIndex], &model->limitData[selectedIndex + 1], (CPN_MAX_CHNOUT - (selectedIndex + 1)) * sizeof(LimitData));
model->limitData[chnCapability - 1].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1);
for (int i = selectedIndex; i < chnCapability; i++) {
updateLine(i);
}
model->limitData[maxidx].clear();
updateLine(maxidx);
emit modified();
}
void Channels::chnCopy()
void Channels::cmCopy()
{
QByteArray chnData;
chnData.append((char*)&model->limitData[selectedChannel],sizeof(LimitData));
QByteArray data;
data.append((char*)&model->limitData[selectedIndex], sizeof(LimitData));
QMimeData *mimeData = new QMimeData;
mimeData->setData(MIMETYPE_CHN, chnData);
mimeData->setData(MIMETYPE_CHANNEL, data);
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
}
void Channels::chnCut()
void Channels::cmCut()
{
chnCopy();
chnClear();
cmCopy();
cmClear();
}
void Channels::chn_customContextMenuRequested(QPoint pos)
void Channels::onCustomContextMenuRequested(QPoint pos)
{
QLabel *label = (QLabel *)sender();
selectedChannel = label->property("index").toInt();
selectedIndex = label->property("index").toInt();
QPoint globalPos = label->mapToGlobal(pos);
const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
bool hasData = mimeData->hasFormat(MIMETYPE_CHN);
bool moveUpAllowed = (selectedChannel > 0);
bool moveDownAllowed = (selectedChannel < (chnCapability - 1));
bool insertAllowed = (selectedChannel < (chnCapability - 1)) && (model->limitData[chnCapability - 1].isEmpty());
QMenu contextMenu;
contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"),this,SLOT(chnCopy()));
contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"),this,SLOT(chnCut()));
contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"),this,SLOT(chnPaste()))->setEnabled(hasData);
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"),this,SLOT(chnClear()));
contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"),this,SLOT(cmCopy()));
contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"),this,SLOT(cmCut()));
contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"),this,SLOT(cmPaste()))->setEnabled(hasClipboardData());
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"),this,SLOT(cmClear()));
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"),this,SLOT(chnInsert()))->setEnabled(insertAllowed);
contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"),this,SLOT(chnDelete()));
contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(chnMoveUp()))->setEnabled(moveUpAllowed);
contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(chnMoveDown()))->setEnabled(moveDownAllowed);
contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"),this,SLOT(cmInsert()))->setEnabled(insertAllowed());
contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"),this,SLOT(cmDelete()));
contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(cmMoveUp()))->setEnabled(moveUpAllowed());
contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(cmMoveDown()))->setEnabled(moveDownAllowed());
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"),this,SLOT(chnClearAll()));
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"),this,SLOT(cmClearAll()));
contextMenu.exec(globalPos);
}
void Channels::chnMoveUp()
bool Channels::hasClipboardData(QByteArray * data) const
{
swapChnData(selectedChannel, selectedChannel - 1);
const QClipboard * clipboard = QApplication::clipboard();
const QMimeData * mimeData = clipboard->mimeData();
if (mimeData->hasFormat(MIMETYPE_CHANNEL)) {
if (data)
data->append(mimeData->data(MIMETYPE_CHANNEL));
return true;
}
return false;
}
void Channels::chnMoveDown()
bool Channels::insertAllowed() const
{
swapChnData(selectedChannel, selectedChannel + 1);
return ((selectedIndex < chnCapability - 1) && (model->limitData[chnCapability - 1].isEmpty()));
}
void Channels::chnClear()
bool Channels::moveDownAllowed() const
{
model->limitData[selectedChannel].clear();
updateLine(selectedChannel);
return selectedIndex < chnCapability - 1;
}
bool Channels::moveUpAllowed() const
{
return selectedIndex > 0;
}
void Channels::cmMoveUp()
{
swapData(selectedIndex, selectedIndex - 1);
}
void Channels::cmMoveDown()
{
swapData(selectedIndex, selectedIndex + 1);
}
void Channels::cmClear()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Channel. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
model->limitData[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, selectedIndex);
updateLine(selectedIndex);
emit modified();
}
void Channels::chnClearAll()
void Channels::cmClearAll()
{
for (int i=0; i<chnCapability; i++) {
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Channels. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
for (int i = 0; i < chnCapability; i++) {
model->limitData[i].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_CLEAR, i);
updateLine(i);
}
emit modified();
}
void Channels::chnInsert()
void Channels::cmInsert()
{
for (int i=(chnCapability - 1); i>selectedChannel; i--) {
if (!model->limitData[i].isEmpty() || !model->limitData[i-1].isEmpty()) {
memcpy(&model->limitData[i], &model->limitData[i-1], sizeof(LimitData));
updateLine(i);
}
}
chnClear();
memmove(&model->limitData[selectedIndex + 1], &model->limitData[selectedIndex], (CPN_MAX_CHNOUT - (selectedIndex + 1)) * sizeof(LimitData));
model->limitData[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
update();
emit modified();
}
void Channels::swapChnData(int idx1, int idx2)
void Channels::swapData(int idx1, int idx2)
{
if ((idx1 != idx2) && (!model->limitData[idx1].isEmpty() || !model->limitData[idx2].isEmpty())) {
LimitData chntmp = model->limitData[idx2];
@@ -431,6 +453,7 @@ void Channels::swapChnData(int idx1, int idx2)
LimitData *chn2 = &model->limitData[idx2];
memcpy(chn2, chn1, sizeof(LimitData));
memcpy(chn1, &chntmp, sizeof(LimitData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_CHANNEL, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
updateLine(idx1);
updateLine(idx2);
emit modified();
+17 -13
View File
@@ -26,7 +26,7 @@
#include <QtCore>
constexpr char MIMETYPE_CHN[] = "application/x-companion-chn";
constexpr char MIMETYPE_CHANNEL[] = "application/x-companion-channel";
class GVarGroup;
@@ -68,19 +68,23 @@ class Channels : public ModelPanel
void ppmcenterEdited();
void update();
void updateLine(int index);
void chnDelete();
void chnCopy();
void chnPaste();
void chnCut();
void chnMoveUp();
void chnMoveDown();
void chnInsert();
void chnClear();
void chnClearAll();
void chn_customContextMenuRequested(QPoint pos);
void cmDelete();
void cmCopy();
void cmPaste();
void cmCut();
void cmMoveUp();
void cmMoveDown();
void cmInsert();
void cmClear();
void cmClearAll();
void onCustomContextMenuRequested(QPoint pos);
private:
void swapChnData(int idx1, int idx2);
bool hasClipboardData(QByteArray * data = nullptr) const;
bool insertAllowed() const;
bool moveDownAllowed() const;
bool moveUpAllowed() const;
void swapData(int idx1, int idx2);
QLineEdit *name[CPN_MAX_CHNOUT];
LimitsGroup *chnOffset[CPN_MAX_CHNOUT];
LimitsGroup *chnMin[CPN_MAX_CHNOUT];
@@ -89,7 +93,7 @@ class Channels : public ModelPanel
QComboBox *curveCB[CPN_MAX_CHNOUT];
QSpinBox *centerSB[CPN_MAX_CHNOUT];
QCheckBox *symlimitsChk[CPN_MAX_CHNOUT];
int selectedChannel;
int selectedIndex;
int chnCapability;
};
+213 -128
View File
@@ -117,7 +117,12 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
lock = true;
if (!firmware->getCapability(HasCvNames)) {
maxCurves = firmware->getCapability(NumCurves);
hasNames = firmware->getCapability(HasCvNames);
hasEnhanced = firmware->getCapability(EnhancedCurves);
maxPoints = firmware->getCapability(NumCurvePoints);
if (!hasNames) {
ui->curveName->hide();
ui->curveNameLabel->hide();
}
@@ -127,14 +132,14 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
connect(scene, SIGNAL(newPoint(int, int)), this, SLOT(onSceneNewPoint(int, int)));
ui->curvePreview->setScene(scene);
int numcurves=firmware->getCapability(NumCurves);
int limit;
if (numcurves>16) {
limit=numcurves/2;
if (maxCurves > 16) {
limit = maxCurves / 2;
} else {
limit=numcurves;
limit = maxCurves;
}
for (int i=0; i<numcurves; i++) {
for (int i = 0; i < maxCurves; i++) {
visibleCurves[i] = false;
// The edit curve button
@@ -151,15 +156,15 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
edit->setStyleSheet(QString("background-color: %1; color: white; padding: 2px 3px; border-style: outset; border-width: 1px; border-radius: 2px; border-color: inherit;").arg(colors[i].name()));
#endif
edit->setPalette(palette);
edit->setText(tr("Curve %1").arg(i+1));
edit->setText(tr("Curve %1").arg(i + 1));
edit->setContextMenuPolicy(Qt::CustomContextMenu);
edit->setToolTip(tr("Popup menu available"));
connect(edit, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(ShowContextMenu(const QPoint&)));
connect(edit, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onCustomContextMenuRequested(const QPoint&)));
connect(edit, SIGNAL(clicked()), this, SLOT(editCurve()));
if (i<limit) {
if (i < limit) {
ui->curvesLayout->addWidget(edit, i, 1, 1, 1);
} else {
ui->curvesLayout2->addWidget(edit, i-limit, 2, 1, 1);
ui->curvesLayout2->addWidget(edit, i - limit, 2, 1, 1);
}
// The curve plot checkbox
@@ -167,7 +172,7 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
plot->setProperty("index", i);
plot->setPalette(palette);
connect(plot, SIGNAL(toggled(bool)), this, SLOT(plotCurve(bool)));
if (i<limit) {
if (i < limit) {
ui->curvesLayout->addWidget(plot, i, 2, 1, 1);
} else {
ui->curvesLayout2->addWidget(plot, i-limit, 1, 1, 1);
@@ -175,13 +180,13 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
}
QSpacerItem * item = new QSpacerItem(1,1, QSizePolicy::Fixed, QSizePolicy::Expanding);
ui->curvesLayout->addItem(item,limit+1,1,1,1,0);
if (limit!=numcurves) {
ui->curvesLayout->addItem(item,limit + 1, 1, 1, 1, 0);
if (limit != maxCurves) {
QSpacerItem * item2 = new QSpacerItem(1,1, QSizePolicy::Fixed, QSizePolicy::Expanding);
ui->curvesLayout2->addItem(item2,limit+1,1,1,1,0);
ui->curvesLayout2->addItem(item2,limit + 1, 1, 1, 1, 0);
}
for (int i=0; i<CPN_MAX_POINTS; i++) {
for (int i = 0; i < CPN_MAX_POINTS; i++) {
spnx[i] = new QSpinBox(this);
spnx[i]->setProperty("index", i);
spnx[i]->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
@@ -199,14 +204,14 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
ui->pointsLayout->addWidget(spny[i], i, 1, 1, 1);
bool insert;
if (firmware->getCapability(EnhancedCurves)) {
if (hasEnhanced) {
insert = (i >= 1);
}
else {
insert = (i==2 || i==4 || i==8 || i==16);
insert = (i == 2 || i == 4 || i ==8 || i == 16);
}
if (insert) {
ui->curvePoints->addItem(tr("%1 points").arg(i+1), i+1);
ui->curvePoints->addItem(tr("%1 points").arg(i + 1), i + 1);
}
}
@@ -250,7 +255,7 @@ void Curves::update()
{
lock = true;
if (firmware->getCapability(HasCvNames)) {
if (hasNames) {
ui->curveName->setText(model->curves[currentCurve].name);
}
@@ -272,7 +277,7 @@ void Curves::updateCurveType()
int index = 0;
if (firmware->getCapability(EnhancedCurves)) {
if (hasEnhanced) {
index = model->curves[currentCurve].count - 2;
}
else {
@@ -305,35 +310,34 @@ void Curves::updateCurve()
qreal width = scene->sceneRect().width();
qreal height = scene->sceneRect().height();
qreal centerX = scene->sceneRect().left() + width/2;
qreal centerY = scene->sceneRect().top() + height/2;
qreal centerX = scene->sceneRect().left() + width / 2;
qreal centerY = scene->sceneRect().top() + height / 2;
QGraphicsSimpleTextItem *ti = scene->addSimpleText(tr("Editing curve %1").arg(currentCurve+1));
QGraphicsSimpleTextItem *ti = scene->addSimpleText(tr("Editing curve %1").arg(currentCurve + 1));
ti->setPos(3, 3);
scene->addLine(centerX, GFX_MARGIN, centerX, height+GFX_MARGIN);
scene->addLine(GFX_MARGIN, centerY, width+GFX_MARGIN, centerY);
scene->addLine(centerX, GFX_MARGIN, centerX, height + GFX_MARGIN);
scene->addLine(GFX_MARGIN, centerY, width + GFX_MARGIN, centerY);
QPen pen;
pen.setWidth(1);
pen.setStyle(Qt::SolidLine);
int numcurves = firmware->getCapability(NumCurves);
for (int k=0; k<numcurves; k++) {
for (int k = 0; k < maxCurves; k++) {
pen.setColor(colors[k]);
if (currentCurve!=k && visibleCurves[k]) {
if (currentCurve != k && visibleCurves[k]) {
int numpoints = model->curves[k].count;
for (int i=0; i<numpoints-1; i++) {
for (int i = 0; i < numpoints - 1; i++) {
if (model->curves[k].type == CurveData::CURVE_TYPE_CUSTOM)
scene->addLine(centerX + (qreal)model->curves[k].points[i].x*width/200,centerY - (qreal)model->curves[k].points[i].y*height/200,centerX + (qreal)model->curves[k].points[i+1].x*width/200,centerY - (qreal)model->curves[k].points[i+1].y*height/200, pen);
scene->addLine(centerX + (qreal)model->curves[k].points[i].x*width/200, centerY - (qreal)model->curves[k].points[i].y*height/200,centerX + (qreal)model->curves[k].points[i+1].x*width/200,centerY - (qreal)model->curves[k].points[i+1].y*height/200, pen);
else
scene->addLine(GFX_MARGIN + i*width/(numpoints-1),centerY - (qreal)model->curves[k].points[i].y*height/200,GFX_MARGIN + (i+1)*width/(numpoints-1),centerY - (qreal)model->curves[k].points[i+1].y*height/200, pen);
scene->addLine(GFX_MARGIN + i*width/(numpoints-1), centerY - (qreal)model->curves[k].points[i].y*height/200,GFX_MARGIN + (i+1)*width/(numpoints-1),centerY - (qreal)model->curves[k].points[i+1].y*height/200, pen);
}
}
}
int numpoints = model->curves[currentCurve].count;
for (int i=0; i<numpoints; i++) {
for (int i = 0; i < numpoints; i++) {
nodel = nodex;
nodex = new Node();
nodex->setProperty("index", i);
@@ -341,26 +345,27 @@ void Curves::updateCurve()
nodex->setBallSize(ui->pointSize->value());
nodex->setBallHeight(0);
if (model->curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) {
if (i>0 && i<numpoints-1) {
if (i > 0 && i < numpoints - 1) {
nodex->setFixedX(false);
nodex->setMinX(model->curves[currentCurve].points[i-1].x);
nodex->setMaxX(model->curves[currentCurve].points[i+1].x);
nodex->setMinX(model->curves[currentCurve].points[i - 1].x);
nodex->setMaxX(model->curves[currentCurve].points[i + 1].x);
}
else {
nodex->setFixedX(true);
}
nodex->setPos(centerX + (qreal)model->curves[currentCurve].points[i].x*width/200,centerY - (qreal)model->curves[currentCurve].points[i].y*height/200);
nodex->setPos(centerX + (qreal)model->curves[currentCurve].points[i].x * width / 200, centerY - (qreal)model->curves[currentCurve].points[i].y * height / 200);
}
else {
nodex->setFixedX(true);
nodex->setPos(GFX_MARGIN + i*width/(numpoints-1), centerY - (qreal)model->curves[currentCurve].points[i].y*height/200);
nodex->setPos(GFX_MARGIN + i * width / (numpoints - 1), centerY - (qreal)model->curves[currentCurve].points[i].y * height / 200);
}
connect(nodex, SIGNAL(moved(int, int)), this, SLOT(onNodeMoved(int, int)));
connect(nodex, SIGNAL(focus()), this, SLOT(onNodeFocus()));
connect(nodex, SIGNAL(unfocus()), this, SLOT(onNodeUnfocus()));
connect(nodex, SIGNAL(deleteMe()), this, SLOT(onNodeDelete()));
scene->addItem(nodex);
if (i>0) scene->addItem(new Edge(nodel, nodex));
if (i > 0)
scene->addItem(new Edge(nodel, nodex));
}
lock = false;
@@ -371,20 +376,20 @@ void Curves::updateCurvePoints()
lock = true;
int count = model->curves[currentCurve].count;
for (int i=0; i<count; i++) {
for (int i = 0; i < count; i++) {
spny[i]->show();
spny[i]->setValue(model->curves[currentCurve].points[i].y);
if (model->curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) {
spnx[i]->show();
if (i==0 || i==model->curves[currentCurve].count-1) {
if (i == 0 || i == model->curves[currentCurve].count - 1) {
spnx[i]->setDisabled(true);
spnx[i]->setMaximum(+100);
spnx[i]->setMinimum(-100);
}
else {
spnx[i]->setDisabled(false);
spnx[i]->setMaximum(model->curves[currentCurve].points[i+1].x);
spnx[i]->setMinimum(model->curves[currentCurve].points[i-1].x);
spnx[i]->setMaximum(model->curves[currentCurve].points[i + 1].x);
spnx[i]->setMinimum(model->curves[currentCurve].points[i - 1].x);
}
spnx[i]->setValue(model->curves[currentCurve].points[i].x);
}
@@ -392,7 +397,7 @@ void Curves::updateCurvePoints()
spnx[i]->hide();
}
}
for (int i=count; i<CPN_MAX_POINTS; i++) {
for (int i = count; i < CPN_MAX_POINTS; i++) {
spny[i]->hide();
spnx[i]->hide();
}
@@ -421,9 +426,9 @@ void Curves::onNodeMoved(int x, int y)
spnx[index]->setValue(x);
spny[index]->setValue(y);
if (index > 0)
spnx[index-1]->setMaximum(x);
if (index < model->curves[currentCurve].count-1)
spnx[index+1]->setMinimum(x);
spnx[index - 1]->setMaximum(x);
if (index < model->curves[currentCurve].count - 1)
spnx[index + 1]->setMinimum(x);
emit modified();
lock = false;
}
@@ -444,17 +449,14 @@ void Curves::onNodeUnfocus()
bool Curves::allowCurveType(int points, CurveData::CurveType type)
{
int numcurves = firmware->getCapability(NumCurves);
int totalpoints = 0;
for (int i=0; i<numcurves; i++) {
int cvPoints = (i==currentCurve ? points : model->curves[i].count);
CurveData::CurveType cvType = (i==currentCurve ? type : model->curves[i].type);
totalpoints += cvPoints + (cvType==CurveData::CURVE_TYPE_CUSTOM ? cvPoints-2 : 0);
for (int i = 0; i < maxCurves; i++) {
int cvPoints = (i == currentCurve ? points : model->curves[i].count);
CurveData::CurveType cvType = (i == currentCurve ? type : model->curves[i].type);
totalpoints += cvPoints + (cvType == CurveData::CURVE_TYPE_CUSTOM ? cvPoints - 2 : 0);
}
int fwpoints = firmware->getCapability(NumCurvePoints);
if (totalpoints > fwpoints) {
if (totalpoints > maxPoints) {
QMessageBox::warning(this, "companion", tr("Not enough free points in EEPROM to store the curve."));
return false;
}
@@ -472,8 +474,8 @@ void Curves::on_curvePoints_currentIndexChanged(int index)
model->curves[currentCurve].count = numpoints;
// TODO something better + reuse!
for (int i=0; i<CPN_MAX_POINTS; i++) {
model->curves[currentCurve].points[i].x = (i >= numpoints-1 ? +100 : -100 + (200*i)/(numpoints-1));
for (int i = 0; i < CPN_MAX_POINTS; i++) {
model->curves[currentCurve].points[i].x = (i >= numpoints - 1 ? +100 : -100 + (200 * i) / (numpoints - 1));
model->curves[currentCurve].points[i].y = 0;
}
@@ -491,12 +493,13 @@ void Curves::on_curveCustom_currentIndexChanged(int index)
if (!lock) {
CurveData::CurveType type = (CurveData::CurveType)index;
int numpoints = ui->curvePoints->itemData(ui->curvePoints->currentIndex()).toInt();
if (allowCurveType(model->curves[currentCurve].count, type)) {
model->curves[currentCurve].type = type;
// TODO something better + reuse!
for (int i=0; i<CPN_MAX_POINTS; i++) {
model->curves[currentCurve].points[i].x = (i >= numpoints-1 ? +100 : -100 + (200*i)/(numpoints-1));
for (int i = 0; i < CPN_MAX_POINTS; i++) {
model->curves[currentCurve].points[i].x = (i >= numpoints - 1 ? +100 : -100 + (200 * i) / (numpoints - 1));
model->curves[currentCurve].points[i].y = 0;
}
@@ -525,7 +528,7 @@ void Curves::on_curveName_editingFinished()
void Curves::resizeEvent(QResizeEvent *event)
{
QRect qr = ui->curvePreview->contentsRect();
ui->curvePreview->scene()->setSceneRect(GFX_MARGIN, GFX_MARGIN, qr.width()-GFX_MARGIN*2, qr.height()-GFX_MARGIN*2);
ui->curvePreview->scene()->setSceneRect(GFX_MARGIN, GFX_MARGIN, qr.width() - GFX_MARGIN * 2, qr.height() - GFX_MARGIN * 2);
updateCurve();
ModelPanel::resizeEvent(event);
}
@@ -559,12 +562,12 @@ void Curves::on_curveApply_clicked()
int index = ui->curveType->currentIndex();
int numpoints = model->curves[currentCurve].count;
for (int i=0; i<numpoints; i++) {
for (int i = 0; i < numpoints; i++) {
float x;
if (model->curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM)
x = model->curves[currentCurve].points[i].x;
else
x = -100.0 + (200.0/(numpoints-1))*i;
x = -100.0 + (200.0 / (numpoints - 1)) * i;
bool apply = false;
switch (ui->curveSide->currentIndex()) {
@@ -572,11 +575,11 @@ void Curves::on_curveApply_clicked()
apply = true;
break;
case 1:
if (x>=0)
if (x >= 0)
apply = true;
break;
case 2:
if (x<0)
if (x < 0)
apply = true;
break;
}
@@ -591,68 +594,6 @@ void Curves::on_curveApply_clicked()
emit modified();
}
void Curves::ShowContextMenu(const QPoint& pos) // this is a slot
{
QPushButton *button = (QPushButton *)sender();
int index = button->property("index").toInt();
const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
QPoint globalPos = button->mapToGlobal(pos);
QMenu myMenu;
QAction *action;
action = myMenu.addAction(CompanionIcon("copy.png"),tr("Copy"));
action->setProperty("index", CURVE_COPY);
action = myMenu.addAction(CompanionIcon("paste.png"),tr("Paste"));
if (!mimeData->hasFormat("application/x-companion-curve-item")) {
action->setEnabled(false);
}
action->setProperty("index", CURVE_PASTE);
action = myMenu.addAction(CompanionIcon("clear.png"),tr("Clear"));
action->setProperty("index", CURVE_RESET);
action = myMenu.addAction(CompanionIcon("clear.png"),tr("Clear all curves"));
action->setProperty("index", CURVE_RESETALL);
QAction* selectedItem = myMenu.exec(globalPos);
if (selectedItem) {
int action=selectedItem->property("index").toInt();
if (action==CURVE_COPY) {
QByteArray curveData;
QMimeData *mimeData2 = new QMimeData;
curveData.append((char*)&model->curves[index], sizeof(CurveData));
mimeData2->setData("application/x-companion-curve-item", curveData);
QApplication::clipboard()->setMimeData(mimeData2, QClipboard::Clipboard);
}
else if (action==CURVE_PASTE) {
QByteArray curveData = mimeData->data("application/x-companion-curve-item");
CurveData *curve = &model->curves[index];
memcpy(curve, curveData.constData(), sizeof(CurveData));
update();
emit modified();
}
else if (action==CURVE_RESET) {
int res = QMessageBox::question(this, "companion", tr("Are you sure you want to reset curve %1?").arg(index+1), QMessageBox::Yes | QMessageBox::No);
if (res == QMessageBox::Yes) {
model->curves[index].clear(5);
update();
emit modified();
}
}
else if (action==CURVE_RESETALL) {
int res = QMessageBox::question(this, "companion", tr("Are you sure you want to reset all curves?"), QMessageBox::Yes | QMessageBox::No);
if (res == QMessageBox::Yes) {
int numcurves = firmware->getCapability(NumCurves);
for (int i=0; i<numcurves; i++) {
model->curves[i].clear(5);
}
update();
emit modified();
}
}
}
}
void Curves::onPointSizeEdited()
{
if (!lock) {
@@ -690,7 +631,7 @@ void Curves::onSceneNewPoint(int x, int y)
newidx = numpoints;
}
else {
for (int i=0; i<numpoints; i++) {
for (int i = 0; i < numpoints; i++) {
if (x < model->curves[currentCurve].points[i].x) {
newidx = i;
break;
@@ -699,8 +640,8 @@ void Curves::onSceneNewPoint(int x, int y)
}
numpoints++;
model->curves[currentCurve].count = numpoints;
for (int idx=(numpoints-1); idx>(newidx); idx--) {
model->curves[currentCurve].points[idx] = model->curves[currentCurve].points[idx-1];
for (int idx = (numpoints - 1); idx > newidx; idx--) {
model->curves[currentCurve].points[idx] = model->curves[currentCurve].points[idx - 1];
}
model->curves[currentCurve].points[newidx].x = x;
model->curves[currentCurve].points[newidx].y = y;
@@ -709,6 +650,150 @@ void Curves::onSceneNewPoint(int x, int y)
}
}
void Curves::onCustomContextMenuRequested(QPoint pos)
{
QPushButton *button = (QPushButton *)sender();
selectedIndex = button->property("index").toInt();
QPoint globalPos = button->mapToGlobal(pos);
QMenu contextMenu;
contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"), this, SLOT(cmCopy()));
contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"), this, SLOT(cmCut()));
contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"), this, SLOT(cmPaste()))->setEnabled(hasClipboardData());
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"), this, SLOT(cmClear()));
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"), this, SLOT(cmInsert()))->setEnabled(insertAllowed());
contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"), this, SLOT(cmDelete()));
contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"), this, SLOT(cmMoveUp()))->setEnabled(moveUpAllowed());
contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"), this, SLOT(cmMoveDown()))->setEnabled(moveDownAllowed());
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"), this, SLOT(cmClearAll()));
contextMenu.exec(globalPos);
}
bool Curves::hasClipboardData(QByteArray * data) const
{
const QClipboard * clipboard = QApplication::clipboard();
const QMimeData * mimeData = clipboard->mimeData();
if (mimeData->hasFormat(MIMETYPE_CURVE)) {
if (data)
data->append(mimeData->data(MIMETYPE_CURVE));
return true;
}
return false;
}
bool Curves::insertAllowed() const
{
return ((selectedIndex < maxCurves - 1) && (model->curves[maxCurves - 1].isEmpty()));
}
bool Curves::moveDownAllowed() const
{
return selectedIndex < maxCurves - 1;
}
bool Curves::moveUpAllowed() const
{
return selectedIndex > 0;
}
void Curves::cmClear()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
model->curves[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_CLEAR, selectedIndex);
update();
emit modified();
}
void Curves::cmClearAll()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Curves. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
for (int i = 0; i < maxCurves; i++) {
model->curves[i].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_CLEAR, i);
}
update();
emit modified();
}
void Curves::cmCopy()
{
QByteArray data;
data.append((char*)&model->curves[selectedIndex], sizeof(CurveData));
QMimeData *mimeData = new QMimeData;
mimeData->setData(MIMETYPE_CURVE, data);
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
}
void Curves::cmCut()
{
cmCopy();
cmClear();
}
void Curves::cmDelete()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Curve. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
memmove(&model->curves[selectedIndex], &model->curves[selectedIndex + 1], (CPN_MAX_CURVES - (selectedIndex + 1)) * sizeof(CurveData));
model->curves[maxCurves - 1].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1);
update();
emit modified();
}
void Curves::cmInsert()
{
memmove(&model->curves[selectedIndex + 1], &model->curves[selectedIndex], (CPN_MAX_CURVES - (selectedIndex + 1)) * sizeof(CurveData));
model->curves[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
update();
emit modified();
}
void Curves::cmMoveDown()
{
swapData(selectedIndex, selectedIndex + 1);
}
void Curves::cmMoveUp()
{
swapData(selectedIndex, selectedIndex - 1);
}
void Curves::cmPaste()
{
QByteArray data;
if (hasClipboardData(&data)) {
CurveData *cd = &model->curves[selectedIndex];
memcpy(cd, data.constData(), sizeof(CurveData));
update();
emit modified();
}
}
void Curves::swapData(int idx1, int idx2)
{
if ((idx1 != idx2) && (!model->curves[idx1].isEmpty() || !model->curves[idx2].isEmpty())) {
CurveData cdtmp = model->curves[idx2];
CurveData *cd1 = &model->curves[idx1];
CurveData *cd2 = &model->curves[idx2];
memcpy(cd2, cd1, sizeof(CurveData));
memcpy(cd1, &cdtmp, sizeof(CurveData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_CURVE, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
update();
emit modified();
}
}
CustomScene::CustomScene(QGraphicsView * view) :
QGraphicsScene(view)
{
+21 -7
View File
@@ -26,12 +26,7 @@
#include <QGraphicsScene>
#include <QGraphicsView>
enum CopyAction {
CURVE_COPY,
CURVE_PASTE,
CURVE_RESET,
CURVE_RESETALL
};
constexpr char MIMETYPE_CURVE[] = "application/x-companion-curve";
namespace Ui {
class Curves;
@@ -71,7 +66,6 @@ class Curves : public ModelPanel
private slots:
void editCurve();
void ShowContextMenu(const QPoint& pos);
void plotCurve(bool checked);
void on_curveName_editingFinished();
void on_curvePoints_currentIndexChanged(int index);
@@ -86,6 +80,16 @@ class Curves : public ModelPanel
void onSceneNewPoint(int x, int y);
void onPointSizeEdited();
void onNodeDelete();
void onCustomContextMenuRequested(QPoint pos);
void cmClear();
void cmClearAll();
void cmCopy();
void cmCut();
void cmDelete();
void cmInsert();
void cmPaste();
void cmMoveDown();
void cmMoveUp();
protected:
virtual void resizeEvent(QResizeEvent *event);
@@ -105,6 +109,16 @@ class Curves : public ModelPanel
bool allowCurveType(int points, CurveData::CurveType type);
void setPointY(int i, int x, int y);
CustomScene * scene;
int maxCurves;
int hasNames;
int hasEnhanced;
int maxPoints;
int selectedIndex;
bool hasClipboardData(QByteArray * data = nullptr) const;
bool insertAllowed() const;
bool moveDownAllowed() const;
bool moveUpAllowed() const;
void swapData(int idx1, int idx2);
};
#endif // _CURVES_H_
+115 -106
View File
@@ -29,7 +29,7 @@ RepeatComboBox::RepeatComboBox(QWidget *parent, int & repeatParam):
QComboBox(parent),
repeatParam(repeatParam)
{
unsigned int step = IS_ARM(getCurrentBoard()) ? 1 : 10;
unsigned int step = 1;
int value = repeatParam/step;
setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
@@ -58,7 +58,7 @@ void RepeatComboBox::onIndexChanged(int index)
void RepeatComboBox::update()
{
unsigned int step = IS_ARM(getCurrentBoard()) ? 1 : 10;
unsigned int step = 1;
int value = repeatParam/step;
if (step == 1) {
value++;
@@ -70,7 +70,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
GenericPanel(parent, model, generalSettings, firmware),
functions(model ? model->customFn : generalSettings.customFn),
mediaPlayerCurrent(-1),
mediaPlayer(NULL)
mediaPlayer(nullptr)
{
Stopwatch s1("CustomFunctionsPanel - populate");
lock = true;
@@ -84,7 +84,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
if (!firmware->getCapability(VoicesAsNumbers)) {
tracksSet = getFilesSet(getSoundsPath(generalSettings), QStringList() << "*.wav" << "*.WAV", firmware->getCapability(VoicesMaxLength));
for (int i=0; i<fswCapability; i++) {
if (functions[i].func==FuncPlayPrompt || functions[i].func==FuncBackgroundMusic) {
if (functions[i].func == FuncPlayPrompt || functions[i].func == FuncBackgroundMusic) {
QString temp = functions[i].paramarm;
if (!temp.isEmpty()) {
tracksSet.insert(temp);
@@ -98,7 +98,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
if (IS_STM32(firmware->getBoard())) {
scriptsSet = getFilesSet(g.profile[g.id()].sdPath() + "/SCRIPTS/FUNCTIONS", QStringList() << "*.lua", firmware->getCapability(VoicesMaxLength));
for (int i=0; i<fswCapability; i++) {
if (functions[i].func==FuncPlayScript) {
if (functions[i].func == FuncPlayScript) {
QString temp = functions[i].paramarm;
if (!temp.isEmpty()) {
scriptsSet.insert(temp);
@@ -127,7 +127,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
else
label->setText(tr("GF%1").arg(i+1));
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(fsw_customContextMenuRequested(QPoint)));
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint)));
tableLayout->addWidget(i, 0, label);
// s1.report("label");
@@ -389,7 +389,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
if (!cfn.isEmpty()) {
widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC;
if (func>=FuncOverrideCH1 && func<=FuncOverrideCH32) {
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32) {
if (model) {
int channelsMax = model->getChannelsMax(true);
fswtchParam[i]->setDecimals(0);
@@ -403,7 +403,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_ENABLE;
}
}
else if (func==FuncLogs) {
else if (func == FuncLogs) {
fswtchParam[i]->setDecimals(1);
fswtchParam[i]->setMinimum(0);
fswtchParam[i]->setMaximum(25.5);
@@ -413,38 +413,29 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
fswtchParam[i]->setValue(cfn.param/10.0);
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
}
else if (func>=FuncAdjustGV1 && func<=FuncAdjustGVLast) {
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) {
int gvidx = func - FuncAdjustGV1;
if (modified)
cfn.adjustMode = fswtchGVmode[i]->currentIndex();
fswtchGVmode[i]->setCurrentIndex(cfn.adjustMode);
widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE;
if (cfn.adjustMode==FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode==FUNC_ADJUST_GVAR_INCDEC) {
if (cfn.adjustMode == FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) {
if (modified)
cfn.param = fswtchParam[i]->value() * model->gvarData[gvidx].multiplierSet();
if (IS_ARM(getCurrentBoard())) {
fswtchParam[i]->setDecimals(model->gvarData[gvidx].prec);
fswtchParam[i]->setSingleStep(model->gvarData[gvidx].multiplierGet());
fswtchParam[i]->setSuffix(model->gvarData[gvidx].unitToString());
if (cfn.adjustMode==FUNC_ADJUST_GVAR_INCDEC) {
double rng = abs(model->gvarData[gvidx].getMax() - model->gvarData[gvidx].getMin());
rng *= model->gvarData[gvidx].multiplierGet();
fswtchParam[i]->setMinimum(-rng);
fswtchParam[i]->setMaximum(rng);
}
else {
fswtchParam[i]->setMinimum(model->gvarData[gvidx].getMinPrec());
fswtchParam[i]->setMaximum(model->gvarData[gvidx].getMaxPrec());
}
fswtchParam[i]->setValue(cfn.param * model->gvarData[gvidx].multiplierGet());
fswtchParam[i]->setDecimals(model->gvarData[gvidx].prec);
fswtchParam[i]->setSingleStep(model->gvarData[gvidx].multiplierGet());
fswtchParam[i]->setSuffix(model->gvarData[gvidx].unitToString());
if (cfn.adjustMode==FUNC_ADJUST_GVAR_INCDEC) {
double rng = abs(model->gvarData[gvidx].getMax() - model->gvarData[gvidx].getMin());
rng *= model->gvarData[gvidx].multiplierGet();
fswtchParam[i]->setMinimum(-rng);
fswtchParam[i]->setMaximum(rng);
}
else {
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
fswtchParam[i]->setMinimum(-125);
fswtchParam[i]->setMaximum(125);
fswtchParam[i]->setValue(cfn.param);
fswtchParam[i]->setMinimum(model->gvarData[gvidx].getMinPrec());
fswtchParam[i]->setMaximum(model->gvarData[gvidx].getMaxPrec());
}
fswtchParam[i]->setValue(cfn.param * model->gvarData[gvidx].multiplierGet());
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
}
else {
@@ -454,13 +445,13 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
}
else if (func==FuncReset) {
else if (func == FuncReset) {
if (modified)
cfn.param = fswtchParamT[i]->currentData().toInt();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE;
}
else if (func>=FuncSetTimer1 && func<=FuncSetTimer3) {
else if (func >= FuncSetTimer1 && func <= FuncSetTimer3) {
if (modified)
cfn.param = fswtchParamTime[i]->timeInSeconds();
RawSourceRange range = RawSource(SOURCE_TYPE_SPECIAL, func - FuncSetTimer1 + 2).getRange(model, generalSettings);
@@ -468,39 +459,39 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
fswtchParamTime[i]->setTime(cfn.param);
widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM | CUSTOM_FUNCTION_ENABLE;
}
else if (func>=FuncSetFailsafeInternalModule && func<=FuncBindExternalModule) {
else if (func >= FuncSetFailsafeInternalModule && func <= FuncBindExternalModule) {
widgetsMask |= CUSTOM_FUNCTION_ENABLE;
}
else if (func==FuncVolume) {
else if (func == FuncVolume) {
if (modified)
cfn.param = fswtchParamT[i]->currentData().toInt();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE;
}
else if (func==FuncPlaySound || func==FuncPlayHaptic || func==FuncPlayValue || func==FuncPlayPrompt || func==FuncPlayBoth || func==FuncBackgroundMusic) {
else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic) {
if (func != FuncBackgroundMusic) {
widgetsMask |= CUSTOM_FUNCTION_REPEAT;
fswtchRepeat[i]->update();
}
if (func==FuncPlayValue) {
if (func == FuncPlayValue) {
if (modified)
cfn.param = fswtchParamT[i]->currentData().toInt();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_REPEAT;
}
else if (func==FuncPlayPrompt || func==FuncPlayBoth) {
else if (func == FuncPlayPrompt || func == FuncPlayBoth) {
if (firmware->getCapability(VoicesAsNumbers)) {
fswtchParam[i]->setDecimals(0);
fswtchParam[i]->setSingleStep(1);
fswtchParam[i]->setMinimum(0);
if (func==FuncPlayPrompt) {
if (func == FuncPlayPrompt) {
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT | CUSTOM_FUNCTION_GV_TOOGLE;
}
else {
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT;
fswtchParamGV[i]->setChecked(false);
}
fswtchParam[i]->setMaximum(func==FuncPlayBoth ? 254 : 255);
fswtchParam[i]->setMaximum(func == FuncPlayBoth ? 254 : 255);
if (modified) {
if (fswtchParamGV[i]->isChecked()) {
fswtchParam[i]->setMinimum(1);
@@ -533,7 +524,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
}
}
}
else if (func==FuncBackgroundMusic) {
else if (func == FuncBackgroundMusic) {
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
if (modified) {
Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, firmware->getCapability(VoicesMaxLength));
@@ -543,27 +534,27 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
widgetsMask |= CUSTOM_FUNCTION_PLAY;
}
}
else if (func==FuncPlaySound) {
else if (func == FuncPlaySound) {
if (modified)
cfn.param = (uint8_t)fswtchParamT[i]->currentIndex();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
else if (func==FuncPlayHaptic) {
else if (func == FuncPlayHaptic) {
if (modified)
cfn.param = (uint8_t)fswtchParamT[i]->currentIndex();
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM;
}
}
else if (func==FuncPlayScript) {
else if (func == FuncPlayScript) {
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
if (modified) {
Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, 8);
}
Helpers::populateFileComboBox(fswtchParamArmT[i], scriptsSet, cfn.paramarm);
}
else if (func==FuncBacklight && IS_TARANIS_PLUS(getCurrentBoard())) {
else if (func == FuncBacklight && IS_TARANIS_PLUS(getCurrentBoard())) {
if (modified)
cfn.param = (uint8_t)fswtchBLcolor[i]->value();
fswtchBLcolor[i]->setValue(cfn.param);
@@ -608,76 +599,63 @@ void CustomFunctionsPanel::update()
lock = false;
}
void CustomFunctionsPanel::fswPaste()
void CustomFunctionsPanel::cmPaste()
{
const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
if (mimeData->hasFormat(MIMETYPE_FSW)) {
QByteArray fswData = mimeData->data(MIMETYPE_FSW);
CustomFunctionData *fsw = &functions[selectedFunction];
memcpy(fsw, fswData.constData(), sizeof(CustomFunctionData));
resetCBsAndRefresh(selectedFunction);
QByteArray data;
if (hasClipboardData(&data)) {
memcpy(&functions[selectedIndex], data.constData(), sizeof(CustomFunctionData));
resetCBsAndRefresh(selectedIndex);
emit modified();
}
}
void CustomFunctionsPanel::fswDelete()
void CustomFunctionsPanel::cmDelete()
{
int maxidx = fswCapability - 1;
for (int i=selectedFunction; i<maxidx; i++) {
if (!functions[i].isEmpty() || !functions[i+1].isEmpty()) {
CustomFunctionData *fsw1 = &functions[i];
CustomFunctionData *fsw2 = &functions[i+1];
memcpy(fsw1, fsw2, sizeof(CustomFunctionData));
resetCBsAndRefresh(i);
}
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Special Function. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
memmove(&functions[selectedIndex], &functions[selectedIndex + 1], (CPN_MAX_SPECIAL_FUNCTIONS - (selectedIndex + 1)) * sizeof(CustomFunctionData));
functions[fswCapability - 1].clear();
for (int i = selectedIndex; i < (fswCapability - 1); i++) {
resetCBsAndRefresh(i);
}
functions[maxidx].clear();
resetCBsAndRefresh(maxidx);
emit modified();
}
void CustomFunctionsPanel::fswCopy()
void CustomFunctionsPanel::cmCopy()
{
QByteArray fswData;
fswData.append((char*)&functions[selectedFunction], sizeof(CustomFunctionData));
QByteArray data;
data.append((char*)&functions[selectedIndex], sizeof(CustomFunctionData));
QMimeData *mimeData = new QMimeData;
mimeData->setData(MIMETYPE_FSW, fswData);
mimeData->setData(MIMETYPE_CUSTOM_FUNCTION, data);
QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
}
void CustomFunctionsPanel::fswCut()
void CustomFunctionsPanel::cmCut()
{
fswCopy();
fswClear();
cmCopy();
cmClear();
}
void CustomFunctionsPanel::fsw_customContextMenuRequested(QPoint pos)
void CustomFunctionsPanel::onCustomContextMenuRequested(QPoint pos)
{
QLabel *label = (QLabel *)sender();
selectedFunction = label->property("index").toInt();
selectedIndex = label->property("index").toInt();
QPoint globalPos = label->mapToGlobal(pos);
const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
bool hasData = mimeData->hasFormat(MIMETYPE_FSW);
bool moveUpAllowed = (selectedFunction > 0);
bool moveDownAllowed = (selectedFunction < (fswCapability - 1));
bool insertAllowed = (selectedFunction < (fswCapability - 1)) && (functions[fswCapability - 1].isEmpty());
QMenu contextMenu;
contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"),this,SLOT(fswCopy()));
contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"),this,SLOT(fswCut()));
contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"),this,SLOT(fswPaste()))->setEnabled(hasData);
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"),this,SLOT(fswClear()));
contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"),this,SLOT(cmCopy()));
contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"),this,SLOT(cmCut()));
contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"),this,SLOT(cmPaste()))->setEnabled(hasClipboardData());
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"),this,SLOT(cmClear()));
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"),this,SLOT(fswInsert()))->setEnabled(insertAllowed);
contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"),this,SLOT(fswDelete()));
contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(fswMoveUp()))->setEnabled(moveUpAllowed);
contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(fswMoveDown()))->setEnabled(moveDownAllowed);
contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"),this,SLOT(cmInsert()))->setEnabled(insertAllowed());
contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"),this,SLOT(cmDelete()));
contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(cmMoveUp()))->setEnabled(moveUpAllowed());
contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(cmMoveDown()))->setEnabled(moveDownAllowed());
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"),this,SLOT(fswClearAll()));
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"),this,SLOT(cmClearAll()));
contextMenu.exec(globalPos);
}
@@ -692,7 +670,6 @@ void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value)
((i==FuncPlayHaptic) && !firmware->getCapability(Haptic)) ||
((i==FuncPlayBoth) && !firmware->getCapability(HasBeeper)) ||
((i==FuncLogs) && !firmware->getCapability(HasSDLogs)) ||
((i==FuncSetTimer1 || i==FuncSetTimer2) && !IS_ARM(firmware->getBoard())) ||
((i==FuncSetTimer3) && firmware->getCapability(Timers) < 3) ||
((i==FuncScreenshot) && !IS_HORUS_OR_TARANIS(firmware->getBoard())) ||
((i>=FuncRangeCheckInternalModule && i<=FuncBindExternalModule) && (!model || !firmware->getCapability(DangerousFunctions))) ||
@@ -762,25 +739,31 @@ void CustomFunctionsPanel::populateFuncParamCB(QComboBox *b, uint function, unsi
}
}
void CustomFunctionsPanel::fswMoveUp()
void CustomFunctionsPanel::cmMoveUp()
{
swapFuncData(selectedFunction, selectedFunction - 1);
swapData(selectedIndex, selectedIndex - 1);
}
void CustomFunctionsPanel::fswMoveDown()
void CustomFunctionsPanel::cmMoveDown()
{
swapFuncData(selectedFunction, selectedFunction + 1);
swapData(selectedIndex, selectedIndex + 1);
}
void CustomFunctionsPanel::fswClear()
void CustomFunctionsPanel::cmClear()
{
functions[selectedFunction].clear();
resetCBsAndRefresh(selectedFunction);
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Special Function. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
functions[selectedIndex].clear();
resetCBsAndRefresh(selectedIndex);
emit modified();
}
void CustomFunctionsPanel::fswClearAll()
void CustomFunctionsPanel::cmClearAll()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Special Functions. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
for (int i=0; i<fswCapability; i++) {
functions[i].clear();
resetCBsAndRefresh(i);
@@ -788,18 +771,17 @@ void CustomFunctionsPanel::fswClearAll()
emit modified();
}
void CustomFunctionsPanel::fswInsert()
void CustomFunctionsPanel::cmInsert()
{
for (int i=(fswCapability - 1); i>selectedFunction; i--) {
if (!functions[i].isEmpty() || !functions[i-1].isEmpty()) {
memcpy(&functions[i], &functions[i-1], sizeof(CustomFunctionData));
resetCBsAndRefresh(i);
}
memmove(&functions[selectedIndex + 1], &functions[selectedIndex], (CPN_MAX_SPECIAL_FUNCTIONS - (selectedIndex + 1)) * sizeof(CustomFunctionData));
functions[selectedIndex].clear();
for (int i = selectedIndex; i < (fswCapability - 1); i++) {
resetCBsAndRefresh(i);
}
fswClear();
}
void CustomFunctionsPanel::swapFuncData(int idx1, int idx2)
void CustomFunctionsPanel::swapData(int idx1, int idx2)
{
if ((idx1 != idx2) && (!functions[idx1].isEmpty() || !functions[idx2].isEmpty())) {
CustomFunctionData fswtmp = functions[idx2];
@@ -823,3 +805,30 @@ void CustomFunctionsPanel::resetCBsAndRefresh(int idx)
refreshCustomFunction(idx);
lock = false;
}
bool CustomFunctionsPanel::hasClipboardData(QByteArray * data) const
{
const QClipboard * clipboard = QApplication::clipboard();
const QMimeData * mimeData = clipboard->mimeData();
if (mimeData->hasFormat(MIMETYPE_CUSTOM_FUNCTION)) {
if (data)
data->append(mimeData->data(MIMETYPE_CUSTOM_FUNCTION));
return true;
}
return false;
}
bool CustomFunctionsPanel::insertAllowed() const
{
return ((selectedIndex < fswCapability - 1) && (model->curves[fswCapability - 1].isEmpty()));
}
bool CustomFunctionsPanel::moveDownAllowed() const
{
return selectedIndex < fswCapability - 1;
}
bool CustomFunctionsPanel::moveUpAllowed() const
{
return selectedIndex > 0;
}
+17 -13
View File
@@ -30,7 +30,7 @@ class RawSourceFilterItemModel;
class RawSwitchFilterItemModel;
class TimerEdit;
constexpr char MIMETYPE_FSW[] = "application/x-companion-fsw";
constexpr char MIMETYPE_CUSTOM_FUNCTION[] = "application/x-companion-custom-function";
class RepeatComboBox: public QComboBox
{
@@ -67,7 +67,7 @@ class CustomFunctionsPanel : public GenericPanel
void updateDataModels();
void customFunctionEdited();
void functionEdited();
void fsw_customContextMenuRequested(QPoint pos);
void onCustomContextMenuRequested(QPoint pos);
void refreshCustomFunction(int index, bool modified=false);
void onChildModified();
bool playSound(int index);
@@ -75,21 +75,25 @@ class CustomFunctionsPanel : public GenericPanel
void toggleSound(bool play);
void onMediaPlayerStateChanged(QMediaPlayer::State state);
void onMediaPlayerError(QMediaPlayer::Error error);
void fswDelete();
void fswCopy();
void fswPaste();
void fswCut();
void fswMoveUp();
void fswMoveDown();
void fswInsert();
void fswClear();
void fswClearAll();
void cmDelete();
void cmCopy();
void cmPaste();
void cmCut();
void cmMoveUp();
void cmMoveDown();
void cmInsert();
void cmClear();
void cmClearAll();
private:
void populateFuncCB(QComboBox *b, unsigned int value);
void populateGVmodeCB(QComboBox *b, unsigned int value);
void populateFuncParamCB(QComboBox *b, uint function, unsigned int value, unsigned int adjustmode=0);
void swapFuncData(int idx1, int idx2);
bool hasClipboardData(QByteArray * data = nullptr) const;
bool insertAllowed() const;
bool moveDownAllowed() const;
bool moveUpAllowed() const;
void swapData(int idx1, int idx2);
void resetCBsAndRefresh(int idx);
RawSwitchFilterItemModel * rawSwitchItemModel;
RawSourceFilterItemModel * rawSrcAllItemModel;
@@ -113,7 +117,7 @@ class CustomFunctionsPanel : public GenericPanel
QSlider * fswtchBLcolor[CPN_MAX_SPECIAL_FUNCTIONS];
QMediaPlayer * mediaPlayer;
int selectedFunction;
int selectedIndex;
int fswCapability;
};
+2 -12
View File
@@ -46,18 +46,8 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
setWindowTitle(tr("Edit %1").arg(RawSource(srcType, ed->chn).toString(&model, &generalSettings)));
QRegExp rx(CHAR_FOR_NAMES_REGEX);
if (IS_ARM(getCurrentBoard())) {
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, ed->weight, model, 100, -100, 100);
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, ed->offset, model, 0, -100, 100);
}
else {
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, ed->weight, model, 100, 0, 100);
gvOffsetGroup = NULL;
ui->offsetLabel->hide();
ui->offsetGV->hide();
ui->offsetSB->hide();
ui->offsetCB->hide();
}
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, ed->weight, model, 100, -100, 100);
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, ed->offset, model, 0, -100, 100);
curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve, model,
firmware->getCapability(HasInputDiff) ? 0 : (HIDE_DIFF | HIDE_NEGATIVE_CURVES));
+244 -112
View File
@@ -58,7 +58,7 @@
</property>
</widget>
</item>
<item row="0" column="4" rowspan="2">
<item row="0" column="6" rowspan="2">
<spacer name="spacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -85,24 +85,18 @@
</item>
<item>
<layout class="QGridLayout" name="trimsLayout">
<item row="2" column="1">
<widget class="QSlider" name="trim1Slider">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item row="0" column="4">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
<property name="tickInterval">
<number>25</number>
</property>
</widget>
</spacer>
</item>
<item row="0" column="0">
<widget class="QSlider" name="trim2Slider">
@@ -136,25 +130,6 @@
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QSlider" name="trim4Slider">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
<property name="tickInterval">
<number>25</number>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QFrame" name="frame">
<property name="frameShape">
@@ -166,16 +141,6 @@
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="leftTrims_3" columnstretch="0,1">
<item row="1" column="0">
<widget class="QLabel" name="trim1Label">
<property name="text">
<string notr="true">trim1</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_5c_3">
<item>
@@ -284,11 +249,59 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="trim1Label">
<property name="text">
<string notr="true">trim1</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="2" column="2">
<widget class="QSlider" name="trim4Slider">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
<property name="tickInterval">
<number>25</number>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSlider" name="trim1Slider">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
<property name="tickInterval">
<number>25</number>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QFrame" name="frame_2">
<property name="frameShape">
@@ -299,7 +312,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QGridLayout" name="righTrims_2" columnstretch="0,1">
<layout class="QGridLayout" name="rightTrims_2" columnstretch="0,1">
<item row="1" column="0">
<widget class="QLabel" name="trim4Label">
<property name="text">
@@ -310,65 +323,6 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="trim3Label">
<property name="text">
<string notr="true">trim3</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_7b_2">
<item>
<spacer name="verticalSpacer_7b_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QComboBox" name="trim3Use"/>
</item>
<item>
<widget class="QSpinBox" name="trim3Value">
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="minimum">
<number>-896</number>
</property>
<property name="maximum">
<number>896</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_8d_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout_8d_2">
<item>
@@ -418,23 +372,201 @@
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_7b_2">
<item>
<spacer name="verticalSpacer_7b_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QComboBox" name="trim3Use"/>
</item>
<item>
<widget class="QSpinBox" name="trim3Value">
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="minimum">
<number>-896</number>
</property>
<property name="maximum">
<number>896</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_8d_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="trim3Label">
<property name="text">
<string notr="true">trim3</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="0" column="4">
<spacer name="horizontalSpacer">
<item row="3" column="2">
<layout class="QGridLayout" name="t6Layout" columnstretch="0,1">
<item row="2" column="0">
<widget class="QLabel" name="trim6Label">
<property name="text">
<string>trim6</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QComboBox" name="trim6Use"/>
</item>
<item>
<widget class="QSpinBox" name="trim6Value">
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="minimum">
<number>-896</number>
</property>
<property name="maximum">
<number>896</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="4" column="2">
<widget class="QSlider" name="trim6Slider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
</spacer>
<property name="tickInterval">
<number>25</number>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSlider" name="trim5Slider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TicksBothSides</enum>
</property>
<property name="tickInterval">
<number>25</number>
</property>
</widget>
</item>
<item row="3" column="1">
<layout class="QGridLayout" name="t5Layout" columnstretch="0,1">
<item row="1" column="0">
<widget class="QLabel" name="trim5Label">
<property name="text">
<string>trim5</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QComboBox" name="trim5Use"/>
</item>
<item>
<widget class="QSpinBox" name="trim5Value">
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
<property name="accelerated">
<bool>true</bool>
</property>
<property name="minimum">
<number>-896</number>
</property>
<property name="maximum">
<number>896</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
File diff suppressed because it is too large Load Diff
+42 -4
View File
@@ -26,6 +26,10 @@
class RawSwitchFilterItemModel;
constexpr char MIMETYPE_FLIGHTMODE[] = "application/x-companion-flightmode";
constexpr char MIMETYPE_GVAR_PARAMS[] = "application/x-companion-gvar-params";
constexpr char MIMETYPE_GVAR_VALUE[] = "application/x-companion-gvar-value";
namespace Ui {
class FlightMode;
}
@@ -42,6 +46,7 @@ class FlightModePanel : public ModelPanel
signals:
void nameModified();
void datachanged();
private slots:
void phaseName_editingFinished();
@@ -61,18 +66,36 @@ class FlightModePanel : public ModelPanel
void phaseGVMax_editingFinished();
void phaseREValue_editingFinished();
void phaseREUse_currentIndexChanged(int index);
void name_customContextMenuRequested(const QPoint & pos);
void fmClear();
void gvLabel_customContextMenuRequested(const QPoint & pos);
void gvClear();
void onCustomContextMenuRequested(QPoint pos);
void cmClear();
void cmClearAll();
void cmCopy();
void cmCut();
void cmDelete();
void cmInsert();
void cmPaste();
void cmMoveDown();
void cmMoveUp();
void gvOnCustomContextMenuRequested(QPoint pos);
void gvCmClear();
void gvCmClearAll();
void gvCmCopy();
void gvCmCut();
void gvCmDelete();
void gvCmInsert();
void gvCmPaste();
void gvCmMoveDown();
void gvCmMoveUp();
private:
Ui::FlightMode *ui;
int phaseIdx;
FlightModeData & phase;
int fmCount;
int reCount;
int gvCount;
int gvIdx;
int trimCount;
QVector<QLabel *> trimsLabel;
QLineEdit * gvNames[CPN_MAX_GVARS];
QDoubleSpinBox * gvValues[CPN_MAX_GVARS];
@@ -88,12 +111,27 @@ class FlightModePanel : public ModelPanel
QVector<QSpinBox *> trimsValue;
QVector<QSlider *> trimsSlider;
RawSwitchFilterItemModel * rawSwitchItemModel;
Board::Type board;
void trimUpdate(unsigned int trim);
void updateGVar(int index);
void updateRotaryEncoder(int index);
void setGVSB(QDoubleSpinBox * spinBox, int min, int max, int val);
void populateGvarUnitCB(QComboBox * cb);
void populateGvarPrecCB(QComboBox * cb);
bool hasClipboardData(QByteArray * data = nullptr) const;
bool insertAllowed() const;
bool moveDownAllowed() const;
bool moveUpAllowed() const;
void swapData(int idx1, int idx2);
bool gvHasClipboardData() const;
bool gvHasDefnClipboardData(QByteArray * data = nullptr) const;
bool gvHasValueClipboardData(QByteArray * data = nullptr) const;
bool gvDeleteAllowed() const;
bool gvInsertAllowed() const;
bool gvMoveDownAllowed() const;
bool gvMoveUpAllowed() const;
void gvSwapData(int idx1, int idx2);
};
class FlightModesPanel : public ModelPanel
+346 -158
View File
@@ -47,18 +47,18 @@ InputsPanel::InputsPanel(QWidget *parent, ModelData & model, GeneralSettings & g
qbClear->setText(tr("Clear All Inputs"));
qbClear->setIcon(CompanionIcon("clear.png"));
exposLayout->addWidget(ExposlistWidget,1,1,1,3);
exposLayout->addWidget(qbUp,2,1);
exposLayout->addWidget(qbClear,2,2);
exposLayout->addWidget(qbDown,2,3);
exposLayout->addWidget(ExposlistWidget, 1, 1, 1, 3);
exposLayout->addWidget(qbUp, 2, 1);
exposLayout->addWidget(qbClear, 2, 2);
exposLayout->addWidget(qbDown, 2, 3);
connect(ExposlistWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(expolistWidget_customContextMenuRequested(QPoint)));
connect(ExposlistWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(expolistWidget_doubleClicked(QModelIndex)));
connect(ExposlistWidget, SIGNAL(mimeDropped(int,const QMimeData*,Qt::DropAction)), this, SLOT(mimeExpoDropped(int, const QMimeData*, Qt::DropAction)));
connect(ExposlistWidget, SIGNAL(mimeDropped(int, const QMimeData*,Qt::DropAction)), this, SLOT(mimeExpoDropped(int, const QMimeData*, Qt::DropAction)));
connect(qbUp, SIGNAL(pressed()),SLOT(moveExpoUp()));
connect(qbDown, SIGNAL(pressed()),SLOT(moveExpoDown()));
connect(qbClear, SIGNAL(pressed()),SLOT(clearExpos()));
connect(qbUp, SIGNAL(pressed()), SLOT(moveExpoUp()));
connect(qbDown, SIGNAL(pressed()), SLOT(moveExpoDown()));
connect(qbClear, SIGNAL(pressed()), SLOT(clearExpos()));
connect(ExposlistWidget, SIGNAL(keyWasPressed(QKeyEvent*)), this, SLOT(expolistWidget_KeyPress(QKeyEvent*)));
}
@@ -71,9 +71,9 @@ void InputsPanel::update()
{
lock = true;
ExposlistWidget->clear();
for (int i=0; i < inputsCount; ++i) {
for (int i = 0; i < inputsCount; ++i) {
bool filled = false;
for (uint j=0; j < CPN_MAX_EXPOS; ++j) {
for (uint j = 0; j < CPN_MAX_EXPOS; ++j) {
const ExpoData & ed = model->expoData[j];
if ((int)ed.chn == i && ed.mode) {
AddInputLine(j);
@@ -81,7 +81,7 @@ void InputsPanel::update()
}
}
if (!filled) {
AddInputLine(-i-1);
AddInputLine(-i - 1);
}
}
lock = false;
@@ -108,9 +108,8 @@ void InputsPanel::AddInputLine(int dest)
const ExpoData &md = model->expoData[dest];
qba.append((const char*)&md, sizeof(ExpoData));
destId = md.chn + 1;
const QVector<const ExpoData *> expos = model->expos(md.chn);
newChan = (expos.constFirst() == &md);
hasSibs = (expos.constLast() != &md);
newChan = model->isExpoParent(dest);
hasSibs = (model->hasExpoChildren(dest) || model->hasExpoSiblings(dest));
}
QListWidgetItem *itm = new QListWidgetItem(getInputText(dest, newChan));
itm->setData(Qt::UserRole, qba);
@@ -133,10 +132,10 @@ QString InputsPanel::getInputText(int dest, bool newChan)
{
QString str;
if (dest < 0) {
str = modelPrinter.printInputName(-dest-1);
str = modelPrinter.printInputName(-dest - 1);
}
else {
const ExpoData & input = model->expoData[dest];
const ExpoData &input = model->expoData[dest];
const int nameChars = (firmware->getCapability(VirtualInputs) ? 10 : 4);
if (newChan)
str = QString("%1").arg(modelPrinter.printInputName(input.chn), -nameChars, QChar(' '));
@@ -150,14 +149,14 @@ QString InputsPanel::getInputText(int dest, bool newChan)
bool InputsPanel::gm_insertExpo(int idx)
{
if (idx<0 || idx>=CPN_MAX_EXPOS || model->expoData[CPN_MAX_EXPOS-1].mode > 0) {
QMessageBox::information(this, CPN_STR_APP_NAME, tr("Not enough available inputs!"));
if (idx < 0 || idx >= CPN_MAX_EXPOS || model->expoData[CPN_MAX_EXPOS-1].mode > 0) {
QMessageBox::information(this, CPN_STR_APP_NAME, tr("Not enough available Inputs!"));
return false;
}
int chn = model->expoData[idx].chn;
ExpoData * newExpo = model->insertInput(idx);
ExpoData *newExpo = model->insertInput(idx);
newExpo->chn = chn;
newExpo->weight = 100;
newExpo->mode = INPUT_MODE_BOTH;
@@ -172,107 +171,107 @@ void InputsPanel::gm_deleteExpo(int index, bool clearName)
void InputsPanel::gm_openExpo(int index)
{
if(index<0 || index>=CPN_MAX_EXPOS) return;
if (index < 0 || index >= CPN_MAX_EXPOS)
return;
ExpoData mixd(model->expoData[index]);
ExpoData ed(model->expoData[index]);
QString inputName;
QString inputName;
if (firmware->getCapability(VirtualInputs))
inputName = model->inputNames[ed.chn];
ExpoDialog *g = new ExpoDialog(this, *model, &ed, generalSettings, firmware, inputName);
if (g->exec()) {
model->expoData[index] = ed;
if (firmware->getCapability(VirtualInputs))
inputName = model->inputNames[mixd.chn];
ExpoDialog *g = new ExpoDialog(this, *model, &mixd, generalSettings, firmware, inputName);
if (g->exec()) {
model->expoData[index] = mixd;
if (firmware->getCapability(VirtualInputs))
strncpy(model->inputNames[mixd.chn], inputName.toLatin1().data(), 4);
emit modified();
update();
}
else {
if (expoInserted) {
gm_deleteExpo(index);
}
expoInserted=false;
update();
strncpy(model->inputNames[ed.chn], inputName.toLatin1().data(), INPUT_NAME_LEN);
emit modified();
update();
}
else {
if (expoInserted) {
gm_deleteExpo(index);
}
expoInserted=false;
update();
}
}
int InputsPanel::getExpoIndex(unsigned int dch)
{
unsigned int i = 0;
while (model->expoData[i].chn<=dch && model->expoData[i].mode && i<CPN_MAX_EXPOS) i++;
if(i==CPN_MAX_EXPOS) return -1;
return i;
unsigned int i = 0;
while (model->expoData[i].chn <= dch && model->expoData[i].mode && i < CPN_MAX_EXPOS)
i++;
if (i == CPN_MAX_EXPOS)
return -1;
return i;
}
QList<int> InputsPanel::createExpoListFromSelected()
{
QList<int> list;
foreach(QListWidgetItem *item, ExposlistWidget->selectedItems()) {
int idx= item->data(Qt::UserRole).toByteArray().at(0);
if(idx>=0 && idx<CPN_MAX_EXPOS) list << idx;
}
return list;
QList<int> list;
foreach (QListWidgetItem *item, ExposlistWidget->selectedItems()) {
int idx = item->data(Qt::UserRole).toByteArray().at(0);
if (idx >= 0 && idx < CPN_MAX_EXPOS)
list << idx;
}
return list;
}
void InputsPanel::setSelectedByExpoList(QList<int> list)
{
for(int i=0; i<ExposlistWidget->count(); i++) {
int t = ExposlistWidget->item(i)->data(Qt::UserRole).toByteArray().at(0);
if(list.contains(t))
ExposlistWidget->item(i)->setSelected(true);
}
for (int i = 0; i < ExposlistWidget->count(); i++) {
int t = ExposlistWidget->item(i)->data(Qt::UserRole).toByteArray().at(0);
if (list.contains(t))
ExposlistWidget->item(i)->setSelected(true);
}
}
void InputsPanel::exposDelete(bool ask)
{
QList<int> list = createExpoListFromSelected();
if(list.isEmpty()) return;
QList<int> list = createExpoListFromSelected();
if (list.isEmpty())
return;
QMessageBox::StandardButton ret = QMessageBox::No;
QMessageBox::StandardButton ret = QMessageBox::No;
if(ask)
ret = QMessageBox::warning(this, "companion",
tr("Delete Selected Inputs?"),
QMessageBox::Yes | QMessageBox::No);
if (ask)
ret = QMessageBox::warning(this, CPN_STR_APP_NAME, tr("Delete selected Inputs. Are you sure?"), QMessageBox::Yes | QMessageBox::No);
if ((ret == QMessageBox::Yes) || (!ask)) {
exposDeleteList(list, ask);
emit modified();
update();
}
if ((ret == QMessageBox::Yes) || (!ask)) {
exposDeleteList(list, ask);
emit modified();
update();
}
}
void InputsPanel::exposCut()
{
exposCopy();
exposDelete(false);
exposCopy();
exposDelete(false);
}
void InputsPanel::exposCopy()
{
QList<int> list = createExpoListFromSelected();
QList<int> list = createExpoListFromSelected();
QByteArray mxData;
foreach(int idx, list) {
mxData.append((char*)&model->expoData[idx], sizeof(ExpoData));
}
QByteArray exData;
foreach (int idx, list) {
exData.append((char*)&model->expoData[idx], sizeof(ExpoData));
}
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-companion-expo", mxData);
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
QMimeData *mimeData = new QMimeData;
mimeData->setData(MIMETYPE_EXPO, exData);
QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
}
void InputsPanel::mimeExpoDropped(int index, const QMimeData *data, Qt::DropAction action)
{
int idx = ExposlistWidget->item(index)->data(Qt::UserRole).toByteArray().at(0);
if (action==Qt::CopyAction) {
if (action == Qt::CopyAction) {
pasteExpoMimeData(data, idx);
}
else if (action==Qt::MoveAction) {
else if (action == Qt::MoveAction) {
QList<int> list = createExpoListFromSelected();
exposDeleteList(list, false);
foreach (const int del, list) {
@@ -285,30 +284,31 @@ void InputsPanel::mimeExpoDropped(int index, const QMimeData *data, Qt::DropActi
void InputsPanel::pasteExpoMimeData(const QMimeData * mimeData, int destIdx)
{
if (mimeData->hasFormat("application/x-companion-expo")) {
int idx; // mixer index
if (mimeData->hasFormat(MIMETYPE_EXPO)) {
int idx; // expo index
int dch;
if (destIdx < 0) {
dch = -destIdx - 1;
idx = getExpoIndex(dch) - 1; //get expo index to insert
} else {
}
else {
idx = destIdx;
dch = model->expoData[idx].chn;
}
QByteArray mxData = mimeData->data("application/x-companion-expo");
QByteArray exData = mimeData->data(MIMETYPE_EXPO);
int i = 0;
while (i < mxData.size()) {
while (i < exData.size()) {
idx++;
if (!gm_insertExpo(idx))
break;
ExpoData *md = &model->expoData[idx];
memcpy(md, mxData.mid(i, sizeof(ExpoData)).constData(), sizeof(ExpoData));
const int oldChan = md->chn;
md->chn = dch;
maybeCopyInputName(oldChan, md->chn);
ExpoData *ed = &model->expoData[idx];
memcpy(ed, exData.mid(i, sizeof(ExpoData)).constData(), sizeof(ExpoData));
const int oldChan = ed->chn;
ed->chn = dch;
maybeCopyInputName(oldChan, ed->chn);
i += sizeof(ExpoData);
}
@@ -334,83 +334,104 @@ void InputsPanel::exposDuplicate()
exposPaste();
}
void InputsPanel::expoOpen(QListWidgetItem *item)
{
if (!item)
item = ExposlistWidget->currentItem();
if (!item)
item = ExposlistWidget->currentItem();
int idx = item->data(Qt::UserRole).toByteArray().at(0);
if (idx<0) {
int ch = -idx-1;
idx = getExpoIndex(ch); // get expo index to insert
if (!gm_insertExpo(idx))
return;
model->expoData[idx].chn = ch;
expoInserted=true;
} else {
expoInserted=false;
}
gm_openExpo(idx);
int idx = item->data(Qt::UserRole).toByteArray().at(0);
if (idx < 0) {
int ch = -idx - 1;
idx = getExpoIndex(ch); // get expo index to insert
if (!gm_insertExpo(idx))
return;
model->expoData[idx].chn = ch;
expoInserted = true;
}
else {
expoInserted = false;
}
gm_openExpo(idx);
}
void InputsPanel::expoAdd()
{
int index = ExposlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
int index = ExposlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
if(index<0) { // if empty then return relevant index
expoOpen();
} else {
index++;
if (!gm_insertExpo(index))
return;
model->expoData[index].chn = model->expoData[index-1].chn;
expoInserted=true;
}
gm_openExpo(index);
if (index < 0) { // if empty then return relevant index
expoOpen();
}
else {
index++;
if (!gm_insertExpo(index))
return;
model->expoData[index].chn = model->expoData[index-1].chn;
expoInserted = true;
}
gm_openExpo(index);
}
void InputsPanel::expolistWidget_customContextMenuRequested(QPoint pos)
{
QPoint globalPos = ExposlistWidget->mapToGlobal(pos);
QPoint globalPos = ExposlistWidget->mapToGlobal(pos);
const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
bool hasData = mimeData->hasFormat("application/x-companion-expo");
const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
bool hasData = mimeData->hasFormat(MIMETYPE_EXPO);
QMenu contextMenu;
contextMenu.addAction(CompanionIcon("add.png"), tr("&Add"),this,SLOT(expoAdd()),tr("Ctrl+A"));
contextMenu.addAction(CompanionIcon("edit.png"), tr("&Edit"),this,SLOT(expoOpen()),tr("Enter"));
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(exposDelete()),tr("Delete"));
contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(exposCopy()),tr("Ctrl+C"));
contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(exposCut()),tr("Ctrl+X"));
contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(exposPaste()),tr("Ctrl+V"))->setEnabled(hasData);
contextMenu.addAction(CompanionIcon("duplicate.png"), tr("Du&plicate"),this,SLOT(exposDuplicate()),tr("Ctrl+U"));
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(moveExpoUp()),tr("Ctrl+Up"));
contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(moveExpoDown()),tr("Ctrl+Down"));
contextMenu.addSeparator();
contextMenu.addActions(ExposlistWidget->actions());
selectedIdx = getIndexFromSelected();
inputIdx = getInputIndexFromSelected();
contextMenu.exec(globalPos);
QMenu contextMenu;
QMenu *contextMenuLines = contextMenu.addMenu(tr("Lines"));
contextMenuLines->addAction(CompanionIcon("add.png"), tr("&Add"), this, SLOT(expoAdd()), tr("Ctrl+A"));
contextMenuLines->addAction(CompanionIcon("edit.png"), tr("&Edit"), this, SLOT(expoOpen()), tr("Enter"));
contextMenuLines->addSeparator();
contextMenuLines->addAction(CompanionIcon("clear.png"), tr("&Delete"), this, SLOT(exposDelete()), tr("Delete"));
contextMenuLines->addAction(CompanionIcon("copy.png"), tr("&Copy"), this, SLOT(exposCopy()), tr("Ctrl+C"));
contextMenuLines->addAction(CompanionIcon("cut.png"), tr("&Cut"), this, SLOT(exposCut()), tr("Ctrl+X"));
contextMenuLines->addAction(CompanionIcon("paste.png"), tr("&Paste"), this, SLOT(exposPaste()), tr("Ctrl+V"))->setEnabled(hasData);
contextMenuLines->addAction(CompanionIcon("duplicate.png"), tr("Du&plicate"), this, SLOT(exposDuplicate()), tr("Ctrl+U"));
contextMenuLines->addSeparator();
contextMenuLines->addAction(CompanionIcon("moveup.png"), tr("Move Up"), this, SLOT(moveExpoUp()), tr("Ctrl+Up"));
contextMenuLines->addAction(CompanionIcon("movedown.png"), tr("Move Down"), this, SLOT(moveExpoDown()), tr("Ctrl+Down"));
QMenu *contextMenuInputs = contextMenu.addMenu(tr("Input"));
contextMenuInputs->addAction(CompanionIcon("arrow-right.png"), tr("Insert"), this, SLOT(cmInputInsert()))->setEnabled(cmInputInsertAllowed());
contextMenuInputs->addAction(CompanionIcon("arrow-left.png"), tr("Delete"), this, SLOT(cmInputDelete()));
contextMenuInputs->addAction(CompanionIcon("moveup.png"), tr("Move Up"), this, SLOT(cmInputMoveUp()))->setEnabled(cmInputMoveUpAllowed());
contextMenuInputs->addAction(CompanionIcon("movedown.png"), tr("Move Down"), this, SLOT(cmInputMoveDown()))->setEnabled(cmInputMoveDownAllowed());
contextMenuInputs->addSeparator();
contextMenuInputs->addAction(CompanionIcon("clear.png"), tr("Clear"), this, SLOT(cmInputClear()))->setEnabled(isExpoIndex(selectedIdx));
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"), this, SLOT(clearExpos()));
contextMenu.addSeparator();
contextMenu.addActions(ExposlistWidget->actions());
contextMenu.exec(globalPos);
}
void InputsPanel::expolistWidget_KeyPress(QKeyEvent *event)
{
if(event->matches(QKeySequence::SelectAll)) expoAdd(); //Ctrl A
if(event->matches(QKeySequence::Delete)) exposDelete();
if(event->matches(QKeySequence::Copy)) exposCopy();
if(event->matches(QKeySequence::Cut)) exposCut();
if(event->matches(QKeySequence::Paste)) exposPaste();
if(event->matches(QKeySequence::Underline)) exposDuplicate();
if (event->matches(QKeySequence::SelectAll))
expoAdd(); //Ctrl A
if (event->matches(QKeySequence::Delete))
exposDelete();
if (event->matches(QKeySequence::Copy))
exposCopy();
if (event->matches(QKeySequence::Cut))
exposCut();
if (event->matches(QKeySequence::Paste))
exposPaste();
if (event->matches(QKeySequence::Underline))
exposDuplicate();
if(event->key()==Qt::Key_Return || event->key()==Qt::Key_Enter) expoOpen();
if(event->matches(QKeySequence::MoveToNextLine))
ExposlistWidget->setCurrentRow(ExposlistWidget->currentRow()+1);
if(event->matches(QKeySequence::MoveToPreviousLine))
ExposlistWidget->setCurrentRow(ExposlistWidget->currentRow()-1);
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
expoOpen();
if (event->matches(QKeySequence::MoveToNextLine))
ExposlistWidget->setCurrentRow(ExposlistWidget->currentRow() + 1);
if (event->matches(QKeySequence::MoveToPreviousLine))
ExposlistWidget->setCurrentRow(ExposlistWidget->currentRow() - 1);
}
int InputsPanel::gm_moveExpo(int idx, bool dir) //true=inc=down false=dec=up
@@ -418,7 +439,7 @@ int InputsPanel::gm_moveExpo(int idx, bool dir) //true=inc=down false=dec=up
if (idx >= CPN_MAX_EXPOS || idx < 0 || (dir && idx >= CPN_MAX_EXPOS - 1) || (!dir && !idx))
return -1;
const int tdx = dir ? idx+1 : idx-1;
const int tdx = dir ? idx + 1 : idx-1;
ExpoData temp;
ExpoData &src = model->expoData[idx];
ExpoData &tgt = model->expoData[tdx];
@@ -432,7 +453,7 @@ int InputsPanel::gm_moveExpo(int idx, bool dir) //true=inc=down false=dec=up
if (tgt.chn != src.chn || tgtempty) {
const int oldChan = src.chn;
if (dir && src.chn < unsigned(inputsCount-1))
if (dir && src.chn < unsigned(inputsCount - 1))
src.chn++;
else if (!dir && src.chn > 0)
src.chn--;
@@ -452,7 +473,7 @@ void InputsPanel::moveExpoList(bool down)
QList<int> list = createExpoListFromSelected();
QList<int> highlightList;
bool mod = false;
foreach(int idx, list) {
foreach (int idx, list) {
const int newIdx = gm_moveExpo(idx, down);
if (newIdx > -1) {
highlightList << newIdx;
@@ -483,19 +504,22 @@ void InputsPanel::expolistWidget_doubleClicked(QModelIndex index)
void InputsPanel::exposDeleteList(QList<int> list, bool clearName)
{
std::sort(list.begin(), list.end());
std::sort(list.begin(), list.end());
int iDec = 0;
foreach(int idx, list) {
gm_deleteExpo(idx-iDec, clearName);
iDec++;
}
int iDec = 0;
foreach (int idx, list) {
gm_deleteExpo(idx-iDec, clearName);
iDec++;
}
}
void InputsPanel::clearExpos()
{
if (QMessageBox::question(this, tr("Clear Inputs?"), tr("Really clear all the inputs?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Inputs. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
model->clearInputs();
for (int i = 0; i < inputsCount; i++) {
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, i);
}
emit modified();
update();
}
@@ -512,8 +536,172 @@ void InputsPanel::maybeCopyInputName(int srcChan, int destChan)
if (srcEmpty) {
// if destination input name is empty, copy it from source expo input
if (!strlen(model->inputNames[destChan]))
strncpy(model->inputNames[destChan], model->inputNames[srcChan], 5);
strncpy(model->inputNames[destChan], model->inputNames[srcChan], INPUT_NAME_LEN);
// clear the emptry source channel name
model->inputNames[srcChan][0] = 0;
}
}
bool InputsPanel::cmInputInsertAllowed() const
{
return ((!model->hasExpos(inputsCount - 1)) && (inputIdx < inputsCount - 1));
}
bool InputsPanel::cmInputMoveDownAllowed() const
{
return (inputIdx >= 0 && (inputIdx < inputsCount - 1));
}
bool InputsPanel::cmInputMoveUpAllowed() const
{
return inputIdx > 0;
}
void InputsPanel::cmInputClear()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Input. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
for (int i = CPN_MAX_EXPOS - 1; i >= 0; i--) {
ExpoData *ed = &model->expoData[i];
if ((int)ed->chn == inputIdx)
model->removeInput(i);
}
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_CLEAR, inputIdx);
update();
emit modified();
}
void InputsPanel::cmInputDelete()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Input. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
for (int i = 0; i < CPN_MAX_EXPOS; i++) {
ExpoData *ed = &model->expoData[i];
if ((int)ed->chn == inputIdx)
model->removeInput(i);
else if ((int)ed->chn > inputIdx)
ed->chn--;
}
for (int i = inputIdx; i < inputsCount; i++) {
strncpy(model->inputNames[i], model->inputNames[i + 1], sizeof(model->inputNames[i]) - 1);
}
model->inputNames[inputsCount - 1][0] = 0;
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, -1);
update();
emit modified();
}
void InputsPanel::cmInputInsert()
{
for (int i = 0; i < CPN_MAX_EXPOS; i++) {
ExpoData *ed = &model->expoData[i];
if ((int)ed->chn >= inputIdx)
ed->chn++;
}
for (int i = inputsCount - 1; i > inputIdx; i--) {
strncpy(model->inputNames[i], model->inputNames[i - 1], sizeof(model->inputNames[i]) - 1);
}
model->inputNames[inputIdx][0] = 0;
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SHIFT, inputIdx, 0, 1);
update();
emit modified();
}
void InputsPanel::cmInputMoveDown()
{
cmInputSwapData(inputIdx, inputIdx + 1);
}
void InputsPanel::cmInputMoveUp()
{
cmInputSwapData(inputIdx - 1, inputIdx);
}
void InputsPanel::cmInputSwapData(int idx1, int idx2)
{
if (idx1 >= idx2 || (!model->hasExpos(idx1) && !model->hasExpos(idx2)))
return;
// save expos
int expoidx = -1;
QVector<ExpoData> edtmp;
int i;
for (i = 0; i < CPN_MAX_EXPOS; i++) {
ExpoData *ed = &model->expoData[i];
if ((int)ed->chn == idx1) {
edtmp << model->expoData[i];
if (expoidx < 0)
expoidx = i;
}
else if ((int)ed->chn > idx1)
break;
}
// move expos up
const int offset = i - expoidx;
int expocnt = 0;
for (int j = i; j < CPN_MAX_EXPOS; j++) {
ExpoData *ed = &model->expoData[j];
if ((int)ed->chn == idx2) {
ExpoData *dest = &model->expoData[j - offset];
memcpy(dest, &model->expoData[j], sizeof(ExpoData));
dest->chn = idx1;
expocnt++;
}
else if ((int)ed->chn > idx2)
break;
}
// copy back saved expos
int cnt = 0;
foreach (ExpoData ed, edtmp) {
ExpoData *dest = &model->expoData[expoidx + expocnt + cnt];
memcpy(dest, &ed, sizeof(ExpoData));
dest->chn = idx2;
cnt++;
}
// swap names
QByteArray *tname = new QByteArray(model->inputNames[idx2]);
strncpy(model->inputNames[idx2], model->inputNames[idx1], sizeof(model->inputNames[idx2]) - 1);
strncpy(model->inputNames[idx1], tname->data(), sizeof(model->inputNames[idx1]) - 1);
model->updateAllReferences(ModelData::REF_UPD_TYPE_INPUT, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
update();
emit modified();
}
bool InputsPanel::isInputIndex(const int index)
{
if (index < 0)
return true;
else
return false;
}
bool InputsPanel::isExpoIndex(const int index)
{
return !isInputIndex(index);
}
int InputsPanel::getIndexFromSelected()
{
return ExposlistWidget->currentItem()->data(Qt::UserRole).toByteArray().at(0);
}
int InputsPanel::getInputIndexFromSelected()
{
const int selidx = getIndexFromSelected();
int idx;
if (isInputIndex(selidx))
idx = -selidx - 1;
else {
const ExpoData *ed = &model->expoData[selidx];
idx = ed->chn;
}
return idx;
}
+17 -1
View File
@@ -25,6 +25,8 @@
#include "mixerslistwidget.h"
#include "modelprinter.h"
constexpr char MIMETYPE_EXPO[] = "application/x-companion-expo";
class InputsPanel : public ModelPanel
{
Q_OBJECT
@@ -52,12 +54,19 @@ class InputsPanel : public ModelPanel
void expoOpen(QListWidgetItem *item = NULL);
void expoAdd();
void maybeCopyInputName(int srcChan, int destChan);
void cmInputClear();
void cmInputDelete();
void cmInputInsert();
void cmInputMoveDown();
void cmInputMoveUp();
private:
bool expoInserted;
MixersListWidget *ExposlistWidget;
int inputsCount;
ModelPrinter modelPrinter;
int selectedIdx;
int inputIdx;
int getExpoIndex(unsigned int dch);
bool gm_insertExpo(int idx);
@@ -70,7 +79,14 @@ class InputsPanel : public ModelPanel
void pasteExpoMimeData(const QMimeData * mimeData, int destIdx);
void AddInputLine(int dest);
QString getInputText(int dest, bool newChan);
bool cmInputInsertAllowed() const;
bool cmInputMoveDownAllowed() const;
bool cmInputMoveUpAllowed() const;
void cmInputSwapData(int idx1, int idx2);
bool isInputIndex(const int index);
bool isExpoIndex(const int index);
int getIndexFromSelected();
int getInputIndexFromSelected();
};
#endif // _INPUTS_H_
+265 -199
View File
@@ -26,7 +26,7 @@
LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
ModelPanel(parent, model, generalSettings, firmware),
selectedSwitch(0)
selectedIndex(0)
{
Stopwatch s1("LogicalSwitchesPanel");
@@ -35,19 +35,22 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
const int srcGroups = firmware->getCapability(GvarsInCS) ? 0 : (RawSource::AllSourceGroups & ~RawSource::GVarsGroup);
rawSourceItemModel = new RawSourceFilterItemModel(&generalSettings, &model, srcGroups, this);
lsCapability = firmware->getCapability(LogicalSwitches);
lsCapabilityExt = firmware->getCapability(LogicalSwitchesExt);
QStringList headerLabels;
headerLabels << "#" << tr("Function") << tr("V1") << tr("V2") << tr("AND Switch");
if (firmware->getCapability(LogicalSwitchesExt)) {
if (lsCapabilityExt) {
headerLabels << tr("Duration") << tr("Delay");
}
TableLayout * tableLayout = new TableLayout(this, firmware->getCapability(LogicalSwitches), headerLabels);
TableLayout * tableLayout = new TableLayout(this, lsCapability, headerLabels);
s1.report("header");
const int channelsMax = model.getChannelsMax(true);
lock = true;
for (int i=0; i<firmware->getCapability(LogicalSwitches); i++) {
for (int i=0; i<lsCapability; i++) {
// The label
QLabel * label = new QLabel(this);
label->setProperty("index", i);
@@ -56,96 +59,96 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
label->setToolTip(tr("Popup menu available"));
label->setMouseTracking(true);
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(csw_customContextMenuRequested(QPoint)));
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint)));
tableLayout->addWidget(i, 0, label);
// The function
csw[i] = new QComboBox(this);
csw[i]->setProperty("index", i);
populateCSWCB(csw[i]);
connect(csw[i], SIGNAL(currentIndexChanged(int)), this, SLOT(functionChanged()));
tableLayout->addWidget(i, 1, csw[i]);
cbFunction[i] = new QComboBox(this);
cbFunction[i]->setProperty("index", i);
populateFunctionCB(cbFunction[i]);
connect(cbFunction[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onFunctionChanged()));
tableLayout->addWidget(i, 1, cbFunction[i]);
// V1
QHBoxLayout *v1Layout = new QHBoxLayout();
cswitchSource1[i] = new QComboBox(this);
cswitchSource1[i]->setProperty("index",i);
connect(cswitchSource1[i], SIGNAL(currentIndexChanged(int)), this, SLOT(v1Edited(int)));
v1Layout->addWidget(cswitchSource1[i]);
cswitchSource1[i]->setVisible(false);
cswitchValue[i] = new QDoubleSpinBox(this);
cswitchValue[i]->setMaximum(channelsMax);
cswitchValue[i]->setMinimum(-channelsMax);
cswitchValue[i]->setAccelerated(true);
cswitchValue[i]->setDecimals(0);
cswitchValue[i]->setProperty("index", i);
connect(cswitchValue[i], SIGNAL(editingFinished()), this, SLOT(offsetEdited()));
v1Layout->addWidget(cswitchValue[i]);
cswitchValue[i]->setVisible(false);
cbSource1[i] = new QComboBox(this);
cbSource1[i]->setProperty("index",i);
connect(cbSource1[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onV1Changed(int)));
v1Layout->addWidget(cbSource1[i]);
cbSource1[i]->setVisible(false);
dsbValue[i] = new QDoubleSpinBox(this);
dsbValue[i]->setMaximum(channelsMax);
dsbValue[i]->setMinimum(-channelsMax);
dsbValue[i]->setAccelerated(true);
dsbValue[i]->setDecimals(0);
dsbValue[i]->setProperty("index", i);
connect(dsbValue[i], SIGNAL(editingFinished()), this, SLOT(onOffsetChanged()));
v1Layout->addWidget(dsbValue[i]);
dsbValue[i]->setVisible(false);
tableLayout->addLayout(i, 2, v1Layout);
// V2
QHBoxLayout *v2Layout = new QHBoxLayout();
cswitchSource2[i] = new QComboBox(this);
cswitchSource2[i]->setProperty("index", i);
connect(cswitchSource2[i], SIGNAL(currentIndexChanged(int)), this, SLOT(v2Edited(int)));
v2Layout->addWidget(cswitchSource2[i]);
cswitchSource2[i]->setVisible(false);
cswitchOffset[i] = new QDoubleSpinBox(this);
cswitchOffset[i]->setProperty("index",i);
cswitchOffset[i]->setMaximum(channelsMax);
cswitchOffset[i]->setMinimum(-channelsMax);
cswitchOffset[i]->setAccelerated(true);
cswitchOffset[i]->setDecimals(0);
connect(cswitchOffset[i], SIGNAL(editingFinished()), this, SLOT(offsetEdited()));
cswitchOffset[i]->setVisible(false);
v2Layout->addWidget(cswitchOffset[i]);
cswitchOffset2[i] = new QDoubleSpinBox(this);
cswitchOffset2[i]->setProperty("index",i);
cswitchOffset2[i]->setMaximum(channelsMax);
cswitchOffset2[i]->setMinimum(-channelsMax);
cswitchOffset2[i]->setAccelerated(true);
cswitchOffset2[i]->setDecimals(0);
cswitchOffset2[i]->setSpecialValueText(" " + tr("(instant)"));
connect(cswitchOffset2[i], SIGNAL(editingFinished()), this, SLOT(offsetEdited()));
cswitchOffset2[i]->setVisible(false);
v2Layout->addWidget(cswitchOffset2[i]);
cswitchTOffset[i] = new TimerEdit(this);
cswitchTOffset[i]->setProperty("index",i);
connect(cswitchTOffset[i],SIGNAL(editingFinished()),this,SLOT(offsetEdited()));
v2Layout->addWidget(cswitchTOffset[i]);
cswitchTOffset[i]->setVisible(false);
cbSource2[i] = new QComboBox(this);
cbSource2[i]->setProperty("index", i);
connect(cbSource2[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onV2Changed(int)));
v2Layout->addWidget(cbSource2[i]);
cbSource2[i]->setVisible(false);
dsbOffset[i] = new QDoubleSpinBox(this);
dsbOffset[i]->setProperty("index",i);
dsbOffset[i]->setMaximum(channelsMax);
dsbOffset[i]->setMinimum(-channelsMax);
dsbOffset[i]->setAccelerated(true);
dsbOffset[i]->setDecimals(0);
connect(dsbOffset[i], SIGNAL(editingFinished()), this, SLOT(onOffsetChanged()));
dsbOffset[i]->setVisible(false);
v2Layout->addWidget(dsbOffset[i]);
dsbOffset2[i] = new QDoubleSpinBox(this);
dsbOffset2[i]->setProperty("index",i);
dsbOffset2[i]->setMaximum(channelsMax);
dsbOffset2[i]->setMinimum(-channelsMax);
dsbOffset2[i]->setAccelerated(true);
dsbOffset2[i]->setDecimals(0);
dsbOffset2[i]->setSpecialValueText(" " + tr("(instant)"));
connect(dsbOffset2[i], SIGNAL(editingFinished()), this, SLOT(onOffsetChanged()));
dsbOffset2[i]->setVisible(false);
v2Layout->addWidget(dsbOffset2[i]);
teOffset[i] = new TimerEdit(this);
teOffset[i]->setProperty("index",i);
connect(teOffset[i],SIGNAL(editingFinished()),this,SLOT(onOffsetChanged()));
v2Layout->addWidget(teOffset[i]);
teOffset[i]->setVisible(false);
tableLayout->addLayout(i, 3, v2Layout);
// AND
cswitchAnd[i] = new QComboBox(this);
cswitchAnd[i]->setProperty("index", i);
populateAndSwitchCB(cswitchAnd[i]);
connect(cswitchAnd[i], SIGNAL(currentIndexChanged(int)), this, SLOT(andEdited(int)));
tableLayout->addWidget(i, 4, cswitchAnd[i]);
cbAndSwitch[i] = new QComboBox(this);
cbAndSwitch[i]->setProperty("index", i);
populateAndSwitchCB(cbAndSwitch[i]);
connect(cbAndSwitch[i], SIGNAL(currentIndexChanged(int)), this, SLOT(onAndSwitchChanged(int)));
tableLayout->addWidget(i, 4, cbAndSwitch[i]);
if (firmware->getCapability(LogicalSwitchesExt)) {
if (lsCapabilityExt) {
// Duration
cswitchDuration[i] = new QDoubleSpinBox(this);
cswitchDuration[i]->setProperty("index", i);
cswitchDuration[i]->setSingleStep(0.1);
cswitchDuration[i]->setMaximum(25);
cswitchDuration[i]->setMinimum(0);
cswitchDuration[i]->setAccelerated(true);
cswitchDuration[i]->setDecimals(1);
connect(cswitchDuration[i], SIGNAL(valueChanged(double)), this, SLOT(durationEdited(double)));
tableLayout->addWidget(i, 5, cswitchDuration[i]);
dsbDuration[i] = new QDoubleSpinBox(this);
dsbDuration[i]->setProperty("index", i);
dsbDuration[i]->setSingleStep(0.1);
dsbDuration[i]->setMaximum(25);
dsbDuration[i]->setMinimum(0);
dsbDuration[i]->setAccelerated(true);
dsbDuration[i]->setDecimals(1);
connect(dsbDuration[i], SIGNAL(valueChanged(double)), this, SLOT(onDurationChanged(double)));
tableLayout->addWidget(i, 5, dsbDuration[i]);
// Delay
cswitchDelay[i] = new QDoubleSpinBox(this);
cswitchDelay[i]->setProperty("index", i);
cswitchDelay[i]->setSingleStep(0.1);
cswitchDelay[i]->setMaximum(25);
cswitchDelay[i]->setMinimum(0);
cswitchDelay[i]->setAccelerated(true);
cswitchDelay[i]->setDecimals(1);
connect(cswitchDelay[i], SIGNAL(valueChanged(double)), this, SLOT(delayEdited(double)));
tableLayout->addWidget(i, 6, cswitchDelay[i]);
dsbDelay[i] = new QDoubleSpinBox(this);
dsbDelay[i]->setProperty("index", i);
dsbDelay[i]->setSingleStep(0.1);
dsbDelay[i]->setMaximum(25);
dsbDelay[i]->setMinimum(0);
dsbDelay[i]->setAccelerated(true);
dsbDelay[i]->setDecimals(1);
connect(dsbDelay[i], SIGNAL(valueChanged(double)), this, SLOT(onDelayChanged(double)));
tableLayout->addWidget(i, 6, dsbDelay[i]);
}
}
@@ -155,7 +158,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
lock = false;
update();
tableLayout->resizeColumnsToContents();
tableLayout->pushRowsUp(firmware->getCapability(LogicalSwitches)+1);
tableLayout->pushRowsUp(lsCapability+1);
s1.report("end");
}
@@ -172,10 +175,10 @@ void LogicalSwitchesPanel::updateDataModels()
lock = oldLock;
}
void LogicalSwitchesPanel::functionChanged()
void LogicalSwitchesPanel::onFunctionChanged()
{
int i = sender()->property("index").toInt();
unsigned newFunc = csw[i]->currentData().toUInt();
unsigned newFunc = cbFunction[i]->currentData().toUInt();
if (model->logicalSw[i].func == newFunc)
return;
@@ -204,13 +207,13 @@ void LogicalSwitchesPanel::functionChanged()
emit modified();
}
void LogicalSwitchesPanel::v1Edited(int value)
void LogicalSwitchesPanel::onV1Changed(int value)
{
if (!lock) {
int i = sender()->property("index").toInt();
model->logicalSw[i].val1 = cswitchSource1[i]->itemData(value).toInt();
model->logicalSw[i].val1 = cbSource1[i]->itemData(value).toInt();
if (model->logicalSw[i].getFunctionFamily() == LS_FAMILY_VOFS) {
if (!offsetEditedAt(i))
if (!offsetChangedAt(i))
updateLine(i);
}
else {
@@ -219,25 +222,25 @@ void LogicalSwitchesPanel::v1Edited(int value)
}
}
void LogicalSwitchesPanel::v2Edited(int value)
void LogicalSwitchesPanel::onV2Changed(int value)
{
if (!lock) {
int i = sender()->property("index").toInt();
model->logicalSw[i].val2 = cswitchSource2[i]->itemData(value).toInt();
model->logicalSw[i].val2 = cbSource2[i]->itemData(value).toInt();
emit modified();
}
}
void LogicalSwitchesPanel::andEdited(int value)
void LogicalSwitchesPanel::onAndSwitchChanged(int value)
{
if (!lock) {
int index = sender()->property("index").toInt();
model->logicalSw[index].andsw = cswitchAnd[index]->itemData(value).toInt();
model->logicalSw[index].andsw = cbAndSwitch[index]->itemData(value).toInt();
emit modified();
}
}
void LogicalSwitchesPanel::durationEdited(double duration)
void LogicalSwitchesPanel::onDurationChanged(double duration)
{
if (!lock) {
int index = sender()->property("index").toInt();
@@ -246,7 +249,7 @@ void LogicalSwitchesPanel::durationEdited(double duration)
}
}
void LogicalSwitchesPanel::delayEdited(double delay)
void LogicalSwitchesPanel::onDelayChanged(double delay)
{
if (!lock) {
int index = sender()->property("index").toInt();
@@ -255,12 +258,12 @@ void LogicalSwitchesPanel::delayEdited(double delay)
}
}
void LogicalSwitchesPanel::offsetEdited()
void LogicalSwitchesPanel::onOffsetChanged()
{
offsetEditedAt(sender()->property("index").toInt());
offsetChangedAt(sender()->property("index").toInt());
}
bool LogicalSwitchesPanel::offsetEditedAt(int index)
bool LogicalSwitchesPanel::offsetChangedAt(int index)
{
if (lock)
return false;
@@ -275,7 +278,7 @@ bool LogicalSwitchesPanel::offsetEditedAt(int index)
{
RawSource source = RawSource(model->logicalSw[index].val1);
RawSourceRange range = source.getRange(model, generalSettings, model->logicalSw[index].getRangeFlags());
double currVal = source.isTimeBased() ? cswitchTOffset[index]->timeInSeconds() : cswitchOffset[index]->value();
double currVal = source.isTimeBased() ? teOffset[index]->timeInSeconds() : dsbOffset[index]->value();
value = round((currVal - range.offset) / range.step);
mod = (mod || value != model->logicalSw[index].val2);
model->logicalSw[index].val2 = value;
@@ -283,22 +286,22 @@ bool LogicalSwitchesPanel::offsetEditedAt(int index)
}
case LS_FAMILY_TIMER:
value = TimToVal(cswitchValue[index]->value());
value = TimToVal(dsbValue[index]->value());
mod = (mod || value != model->logicalSw[index].val1);
model->logicalSw[index].val1 = value;
value = TimToVal(cswitchOffset[index]->value());
value = TimToVal(dsbOffset[index]->value());
mod = (mod || value != model->logicalSw[index].val2);
model->logicalSw[index].val2 = value;
break;
case LS_FAMILY_EDGE:
if (sender() == cswitchOffset[index]) {
value = TimToVal(cswitchOffset[index]->value());
if (sender() == dsbOffset[index]) {
value = TimToVal(dsbOffset[index]->value());
mod = (mod || value != model->logicalSw[index].val2);
model->logicalSw[index].val2 = value;
}
else {
value = TimToVal(cswitchOffset2[index]->value()) - model->logicalSw[index].val2;
value = TimToVal(dsbOffset2[index]->value()) - model->logicalSw[index].val2;
mod = (mod || value != model->logicalSw[index].val3);
model->logicalSw[index].val3 = value;
}
@@ -347,8 +350,8 @@ void LogicalSwitchesPanel::updateLine(int i)
lock = true;
unsigned int mask;
csw[i]->setCurrentIndex(csw[i]->findData(model->logicalSw[i].func));
cswitchAnd[i]->setCurrentIndex(cswitchAnd[i]->findData(RawSwitch(model->logicalSw[i].andsw).toValue()));
cbFunction[i]->setCurrentIndex(cbFunction[i]->findData(model->logicalSw[i].func));
cbAndSwitch[i]->setCurrentIndex(cbAndSwitch[i]->findData(RawSwitch(model->logicalSw[i].andsw).toValue()));
if (!model->logicalSw[i].func) {
mask = 0;
@@ -364,27 +367,27 @@ void LogicalSwitchesPanel::updateLine(int i)
RawSource source = RawSource(model->logicalSw[i].val1);
RawSourceRange range = source.getRange(model, generalSettings, model->logicalSw[i].getRangeFlags());
double value = range.step * model->logicalSw[i].val2 + range.offset; /* TODO+source.getRawOffset(model)*/
cswitchSource1[i]->setModel(rawSourceItemModel);
cswitchSource1[i]->setCurrentIndex(cswitchSource1[i]->findData(source.toValue()));
cbSource1[i]->setModel(rawSourceItemModel);
cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(source.toValue()));
if (source.isTimeBased()) {
mask |= VALUE_TO_VISIBLE;
cswitchTOffset[i]->setTimeRange(range.min, range.max);
cswitchTOffset[i]->setSingleStep(range.step);
cswitchTOffset[i]->setPageStep(range.step * 60);
cswitchTOffset[i]->setShowSeconds(range.step != 60);
cswitchTOffset[i]->setTime((int)value);
teOffset[i]->setTimeRange(range.min, range.max);
teOffset[i]->setSingleStep(range.step);
teOffset[i]->setPageStep(range.step * 60);
teOffset[i]->setShowSeconds(range.step != 60);
teOffset[i]->setTime((int)value);
}
else {
mask |= VALUE2_VISIBLE;
if (range.unit.isEmpty())
cswitchOffset[i]->setSuffix("");
dsbOffset[i]->setSuffix("");
else
cswitchOffset[i]->setSuffix(" " + range.unit);
cswitchOffset[i]->setDecimals(range.decimals);
cswitchOffset[i]->setMinimum(range.min);
cswitchOffset[i]->setMaximum(range.max);
cswitchOffset[i]->setSingleStep(range.step);
cswitchOffset[i]->setValue(value);
dsbOffset[i]->setSuffix(" " + range.unit);
dsbOffset[i]->setDecimals(range.decimals);
dsbOffset[i]->setMinimum(range.min);
dsbOffset[i]->setMaximum(range.max);
dsbOffset[i]->setSingleStep(range.step);
dsbOffset[i]->setValue(value);
}
break;
@@ -393,58 +396,58 @@ void LogicalSwitchesPanel::updateLine(int i)
case LS_FAMILY_STICKY: // no break
case LS_FAMILY_VBOOL:
mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE;
cswitchSource1[i]->setModel(rawSwitchItemModel);
cswitchSource1[i]->setCurrentIndex(cswitchSource1[i]->findData(model->logicalSw[i].val1));
cswitchSource2[i]->setModel(rawSwitchItemModel);
cswitchSource2[i]->setCurrentIndex(cswitchSource2[i]->findData(model->logicalSw[i].val2));
cbSource1[i]->setModel(rawSwitchItemModel);
cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1));
cbSource2[i]->setModel(rawSwitchItemModel);
cbSource2[i]->setCurrentIndex(cbSource2[i]->findData(model->logicalSw[i].val2));
break;
case LS_FAMILY_EDGE:
mask |= SOURCE1_VISIBLE | VALUE2_VISIBLE | VALUE3_VISIBLE;
mask &= ~DELAY_ENABLED;
cswitchSource1[i]->setModel(rawSwitchItemModel);
cswitchSource1[i]->setCurrentIndex(cswitchSource1[i]->findData(model->logicalSw[i].val1));
updateTimerParam(cswitchOffset[i], model->logicalSw[i].val2, 0.0);
updateTimerParam(cswitchOffset2[i], model->logicalSw[i].val2+model->logicalSw[i].val3, ValToTim(TimToVal(cswitchOffset[i]->value())-1));
cswitchOffset2[i]->setSuffix((model->logicalSw[i].val3) ? "" : tr(" (infinite)"));
cbSource1[i]->setModel(rawSwitchItemModel);
cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1));
updateTimerParam(dsbOffset[i], model->logicalSw[i].val2, 0.0);
updateTimerParam(dsbOffset2[i], model->logicalSw[i].val2+model->logicalSw[i].val3, ValToTim(TimToVal(dsbOffset[i]->value())-1));
dsbOffset2[i]->setSuffix((model->logicalSw[i].val3) ? "" : tr(" (infinite)"));
break;
case LS_FAMILY_VCOMP:
mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE;
cswitchSource1[i]->setModel(rawSourceItemModel);
cswitchSource1[i]->setCurrentIndex(cswitchSource1[i]->findData(model->logicalSw[i].val1));
cswitchSource2[i]->setModel(rawSourceItemModel);
cswitchSource2[i]->setCurrentIndex(cswitchSource2[i]->findData(model->logicalSw[i].val2));
cbSource1[i]->setModel(rawSourceItemModel);
cbSource1[i]->setCurrentIndex(cbSource1[i]->findData(model->logicalSw[i].val1));
cbSource2[i]->setModel(rawSourceItemModel);
cbSource2[i]->setCurrentIndex(cbSource2[i]->findData(model->logicalSw[i].val2));
break;
case LS_FAMILY_TIMER:
mask |= VALUE1_VISIBLE | VALUE2_VISIBLE;
updateTimerParam(cswitchValue[i], model->logicalSw[i].val1, 0.1);
updateTimerParam(cswitchOffset[i], model->logicalSw[i].val2, 0.1);
updateTimerParam(dsbValue[i], model->logicalSw[i].val1, 0.1);
updateTimerParam(dsbOffset[i], model->logicalSw[i].val2, 0.1);
break;
}
}
cswitchSource1[i]->setVisible(mask & SOURCE1_VISIBLE);
cswitchSource2[i]->setVisible(mask & SOURCE2_VISIBLE);
cswitchValue[i]->setVisible(mask & VALUE1_VISIBLE);
cswitchOffset[i]->setVisible(mask & VALUE2_VISIBLE);
cswitchOffset2[i]->setVisible(mask & VALUE3_VISIBLE);
cswitchTOffset[i]->setVisible(mask & VALUE_TO_VISIBLE);
cswitchAnd[i]->setVisible(mask & LINE_ENABLED);
if (firmware->getCapability(LogicalSwitchesExt)) {
cswitchDuration[i]->setVisible(mask & DURATION_ENABLED);
cswitchDelay[i]->setVisible(mask & DELAY_ENABLED);
cbSource1[i]->setVisible(mask & SOURCE1_VISIBLE);
cbSource2[i]->setVisible(mask & SOURCE2_VISIBLE);
dsbValue[i]->setVisible(mask & VALUE1_VISIBLE);
dsbOffset[i]->setVisible(mask & VALUE2_VISIBLE);
dsbOffset2[i]->setVisible(mask & VALUE3_VISIBLE);
teOffset[i]->setVisible(mask & VALUE_TO_VISIBLE);
cbAndSwitch[i]->setVisible(mask & LINE_ENABLED);
if (lsCapabilityExt) {
dsbDuration[i]->setVisible(mask & DURATION_ENABLED);
dsbDelay[i]->setVisible(mask & DELAY_ENABLED);
if (mask & DURATION_ENABLED)
cswitchDuration[i]->setValue(model->logicalSw[i].duration/10.0);
dsbDuration[i]->setValue(model->logicalSw[i].duration/10.0);
if (mask & DELAY_ENABLED)
cswitchDelay[i]->setValue(model->logicalSw[i].delay/10.0);
dsbDelay[i]->setValue(model->logicalSw[i].delay/10.0);
}
lock = false;
}
void LogicalSwitchesPanel::populateCSWCB(QComboBox *b)
void LogicalSwitchesPanel::populateFunctionCB(QComboBox *b)
{
int order[] = {
LS_FN_OFF,
@@ -476,10 +479,6 @@ void LogicalSwitchesPanel::populateCSWCB(QComboBox *b)
int func = order[i];
if (func == LS_FN_NEQUAL || func == LS_FN_EGREATER || func == LS_FN_ELESS)
continue;
if (!IS_ARM(firmware->getBoard())) {
if (func == LS_FN_VEQUAL || func == LS_FN_EDGE)
continue;
}
b->addItem(LogicalSwitchData(func).funcToString(), func);
}
b->setMaxVisibleItems(10);
@@ -487,90 +486,157 @@ void LogicalSwitchesPanel::populateCSWCB(QComboBox *b)
void LogicalSwitchesPanel::populateAndSwitchCB(QComboBox *b)
{
if (IS_ARM(firmware->getBoard())) {
b->setModel(rawSwitchItemModel);
}
else {
RawSwitch item;
b->clear();
item = RawSwitch(SWITCH_TYPE_NONE);
b->addItem(item.toString(), item.toValue());
for (int i=1; i <= Boards::getCapability(firmware->getBoard(), Board::SwitchPositions); i++) {
item = RawSwitch(SWITCH_TYPE_SWITCH, i);
b->addItem(item.toString(), item.toValue());
}
for (int i=1; i<=6; i++) {
item = RawSwitch(SWITCH_TYPE_VIRTUAL, i);
b->addItem(item.toString(), item.toValue());
}
}
b->setModel(rawSwitchItemModel);
b->setVisible(true);
}
void LogicalSwitchesPanel::update()
{
updateDataModels();
for (int i=0; i<firmware->getCapability(LogicalSwitches); i++) {
for (int i=0; i<lsCapability; i++) {
updateLine(i);
}
}
void LogicalSwitchesPanel::cswPaste()
void LogicalSwitchesPanel::cmPaste()
{
const QClipboard *clipboard = QApplication::clipboard();
const QMimeData *mimeData = clipboard->mimeData();
if (mimeData->hasFormat("application/x-companion-csw")) {
QByteArray cswData = mimeData->data("application/x-companion-csw");
LogicalSwitchData *csw = &model->logicalSw[selectedSwitch];
memcpy(csw, cswData.constData(), sizeof(LogicalSwitchData));
update();
QByteArray data;
if (hasClipboardData(&data)) {
memcpy(&model->logicalSw[selectedIndex], data.constData(), sizeof(LogicalSwitchData));
updateDataModels();
updateLine(selectedIndex);
emit modified();
}
}
void LogicalSwitchesPanel::cswDelete()
void LogicalSwitchesPanel::cmDelete()
{
model->logicalSw[selectedSwitch].clear();
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Logical Switch. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
memmove(&model->logicalSw[selectedIndex], &model->logicalSw[selectedIndex + 1], (CPN_MAX_LOGICAL_SWITCHES - (selectedIndex + 1)) * sizeof(LogicalSwitchData));
model->logicalSw[lsCapability - 1].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, -1);
update();
emit modified();
updateLine(selectedSwitch);
}
void LogicalSwitchesPanel::cswCopy()
void LogicalSwitchesPanel::cmCopy()
{
QByteArray cswData;
cswData.append((char*)&model->logicalSw[selectedSwitch],sizeof(LogicalSwitchData));
QByteArray data;
data.append((char*)&model->logicalSw[selectedIndex], sizeof(LogicalSwitchData));
QMimeData *mimeData = new QMimeData;
mimeData->setData("application/x-companion-csw", cswData);
mimeData->setData(MIMETYPE_LOGICAL_SWITCH, data);
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
}
void LogicalSwitchesPanel::cswCut()
void LogicalSwitchesPanel::cmCut()
{
cswCopy();
cswDelete();
cmCopy();
cmClear();
}
// TODO make something generic here!
void LogicalSwitchesPanel::csw_customContextMenuRequested(QPoint pos)
void LogicalSwitchesPanel::onCustomContextMenuRequested(QPoint pos)
{
QLabel *label = (QLabel *)sender();
selectedSwitch = label->property("index").toInt();
QLabel *label = (QLabel *)sender();
selectedIndex = label->property("index").toInt();
QPoint globalPos = label->mapToGlobal(pos);
QPoint globalPos = label->mapToGlobal(pos);
QMenu contextMenu;
contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"),this,SLOT(cmCopy()));
contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"),this,SLOT(cmCut()));
contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"),this,SLOT(cmPaste()))->setEnabled(hasClipboardData());
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"),this,SLOT(cmClear()));
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"),this,SLOT(cmInsert()))->setEnabled(insertAllowed());
contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"),this,SLOT(cmDelete()));
contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(cmMoveUp()))->setEnabled(moveUpAllowed());
contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(cmMoveDown()))->setEnabled(moveDownAllowed());
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"),this,SLOT(cmClearAll()));
const QClipboard * clipboard = QApplication::clipboard();
const QMimeData * mimeData = clipboard->mimeData();
bool hasData = mimeData->hasFormat("application/x-companion-csw");
contextMenu.exec(globalPos);
}
QMenu contextMenu;
contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(cswCopy()));
contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(cswCut()));
contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(cswPaste()))->setEnabled(hasData);
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(cswDelete()));
bool LogicalSwitchesPanel::hasClipboardData(QByteArray * data) const
{
const QClipboard * clipboard = QApplication::clipboard();
const QMimeData * mimeData = clipboard->mimeData();
if (mimeData->hasFormat(MIMETYPE_LOGICAL_SWITCH)) {
if (data)
data->append(mimeData->data(MIMETYPE_LOGICAL_SWITCH));
return true;
}
return false;
}
contextMenu.exec(globalPos);
bool LogicalSwitchesPanel::insertAllowed() const
{
return ((selectedIndex < lsCapability - 1) && (model->logicalSw[lsCapability - 1].isEmpty()));
}
bool LogicalSwitchesPanel::moveDownAllowed() const
{
return selectedIndex < lsCapability - 1;
}
bool LogicalSwitchesPanel::moveUpAllowed() const
{
return selectedIndex > 0;
}
void LogicalSwitchesPanel::cmMoveUp()
{
swapData(selectedIndex, selectedIndex - 1);
}
void LogicalSwitchesPanel::cmMoveDown()
{
swapData(selectedIndex, selectedIndex + 1);
}
void LogicalSwitchesPanel::cmClear()
{
model->logicalSw[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, selectedIndex);
update();
emit modified();
}
void LogicalSwitchesPanel::cmClearAll()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Logical Switches. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
for (int i=0; i<lsCapability; i++) {
model->logicalSw[i].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_CLEAR, i);
}
update();
emit modified();
}
void LogicalSwitchesPanel::cmInsert()
{
memmove(&model->logicalSw[selectedIndex + 1], &model->logicalSw[selectedIndex], (CPN_MAX_LOGICAL_SWITCHES - (selectedIndex + 1)) * sizeof(LogicalSwitchData));
model->logicalSw[selectedIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SHIFT, selectedIndex, 0, 1);
update();
emit modified();
}
void LogicalSwitchesPanel::swapData(int idx1, int idx2)
{
if ((idx1 != idx2) && (!model->logicalSw[idx1].isEmpty() || !model->logicalSw[idx2].isEmpty())) {
LogicalSwitchData lstmp = model->logicalSw[idx2];
LogicalSwitchData *lsw1 = &model->logicalSw[idx1];
LogicalSwitchData *lsw2 = &model->logicalSw[idx2];
memcpy(lsw2, lsw1, sizeof(LogicalSwitchData));
memcpy(lsw1, &lstmp, sizeof(LogicalSwitchData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_LOGICAL_SWITCH, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
update();
emit modified();
}
}
+39 -27
View File
@@ -28,6 +28,8 @@ class RawSwitchFilterItemModel;
class RawSourceFilterItemModel;
class TimerEdit;
constexpr char MIMETYPE_LOGICAL_SWITCH[] = "application/x-companion-logical-switch";
class LogicalSwitchesPanel : public ModelPanel
{
Q_OBJECT
@@ -40,40 +42,50 @@ class LogicalSwitchesPanel : public ModelPanel
private slots:
void updateDataModels();
void functionChanged();
void v1Edited(int value);
void v2Edited(int value);
void andEdited(int value);
void durationEdited(double duration);
void delayEdited(double delay);
void offsetEdited();
bool offsetEditedAt(int index);
void onFunctionChanged();
void onV1Changed(int value);
void onV2Changed(int value);
void onAndSwitchChanged(int value);
void onDurationChanged(double duration);
void onDelayChanged(double delay);
void onOffsetChanged();
bool offsetChangedAt(int index);
void updateLine(int index);
void csw_customContextMenuRequested(QPoint pos);
void cswDelete();
void cswCopy();
void cswPaste();
void cswCut();
void onCustomContextMenuRequested(QPoint pos);
void cmDelete();
void cmCopy();
void cmPaste();
void cmCut();
void cmMoveUp();
void cmMoveDown();
void cmInsert();
void cmClear();
void cmClearAll();
private:
QComboBox * csw[CPN_MAX_LOGICAL_SWITCHES];
QDoubleSpinBox * cswitchValue[CPN_MAX_LOGICAL_SWITCHES];
QDoubleSpinBox * cswitchOffset[CPN_MAX_LOGICAL_SWITCHES];
QDoubleSpinBox * cswitchOffset2[CPN_MAX_LOGICAL_SWITCHES];
TimerEdit * cswitchTOffset[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cswitchAnd[CPN_MAX_LOGICAL_SWITCHES];
QDoubleSpinBox * cswitchDuration[CPN_MAX_LOGICAL_SWITCHES];
QDoubleSpinBox * cswitchDelay[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cswitchSource1[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cswitchSource2[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cbFunction[CPN_MAX_LOGICAL_SWITCHES];
QDoubleSpinBox * dsbValue[CPN_MAX_LOGICAL_SWITCHES];
QDoubleSpinBox * dsbOffset[CPN_MAX_LOGICAL_SWITCHES];
QDoubleSpinBox * dsbOffset2[CPN_MAX_LOGICAL_SWITCHES];
TimerEdit * teOffset[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cbAndSwitch[CPN_MAX_LOGICAL_SWITCHES];
QDoubleSpinBox * dsbDuration[CPN_MAX_LOGICAL_SWITCHES];
QDoubleSpinBox * dsbDelay[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cbSource1[CPN_MAX_LOGICAL_SWITCHES];
QComboBox * cbSource2[CPN_MAX_LOGICAL_SWITCHES];
RawSwitchFilterItemModel * rawSwitchItemModel;
RawSourceFilterItemModel * rawSourceItemModel;
int selectedSwitch;
void populateCSWCB(QComboBox *b);
int selectedIndex;
void populateFunctionCB(QComboBox *b);
void populateAndSwitchCB(QComboBox *b);
void updateTimerParam(QDoubleSpinBox *sb, int timer, double minimum=0);
int lsCapability;
int lsCapabilityExt;
void swapData(int idx1, int idx2);
bool hasClipboardData(QByteArray * data = nullptr) const;
bool insertAllowed() const;
bool moveDownAllowed() const;
bool moveUpAllowed() const;
};
#endif // _LOGICALSWITCHES_H_
+1 -1
View File
@@ -65,7 +65,7 @@ ModelEdit::ModelEdit(QWidget * parent, RadioData & radioData, int modelId, Firmw
s1.report("LS");
addTab(new CustomFunctionsPanel(this, &radioData.models[modelId], radioData.generalSettings, firmware), tr("Special Functions"));
s1.report("CF");
if (firmware->getCapability(Telemetry) & TM_HASTELEMETRY)
if (firmware->getCapability(Telemetry))
addTab(new TelemetryPanel(this, radioData.models[modelId], radioData.generalSettings, firmware), tr("Telemetry"));
onTabIndexChanged(ui->tabWidget->currentIndex()); // make sure to trigger update on default tab panel
+297 -132
View File
@@ -36,7 +36,6 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge
timer(timer),
ui(new Ui::Timer)
{
Board::Type board = firmware->getBoard();
ui->setupUi(this);
@@ -49,7 +48,7 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge
}
else {
ui->name->setMaxLength(length);
ui->name->setText(timer.name);
//ui->name->setText(timer.name);
}
// Mode
@@ -65,10 +64,8 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge
ui->countdownBeep->setField(timer.countdownBeep, this);
ui->countdownBeep->addItem(tr("Silent"), TimerData::COUNTDOWN_SILENT);
ui->countdownBeep->addItem(tr("Beeps"), TimerData::COUNTDOWN_BEEPS);
if (IS_ARM(board) || IS_2560(board)) {
ui->countdownBeep->addItem(tr("Voice"), TimerData::COUNTDOWN_VOICE);
ui->countdownBeep->addItem(tr("Haptic"), TimerData::COUNTDOWN_HAPTIC);
}
ui->countdownBeep->addItem(tr("Voice"), TimerData::COUNTDOWN_VOICE);
ui->countdownBeep->addItem(tr("Haptic"), TimerData::COUNTDOWN_HAPTIC);
ui->value->setMaximumTime(firmware->getMaxTimerStart());
@@ -85,6 +82,7 @@ TimerPanel::TimerPanel(QWidget *parent, ModelData & model, TimerData & timer, Ge
QWidget::setTabOrder(ui->countdownBeep, ui->minuteBeep);
QWidget::setTabOrder(ui->minuteBeep, ui->persistent);
update();
lock = false;
}
@@ -95,6 +93,9 @@ TimerPanel::~TimerPanel()
void TimerPanel::update()
{
lock = true;
ui->name->setText(timer.name);
int hour = timer.val / 3600;
int min = (timer.val - (hour * 3600)) / 60;
int sec = (timer.val - (hour * 3600)) % 60;
@@ -116,7 +117,10 @@ void TimerPanel::update()
ui->persistentValue->setText(QString(" %1(%2:%3:%4)").arg(sign<0 ? "-" :" ").arg(hours, 2, 10, QLatin1Char('0')).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0')));
}
ui->countdownBeep->updateValue();
ui->minuteBeep->setChecked(timer.minuteBeep);
ui->persistent->updateValue();
lock = false;
}
QWidget * TimerPanel::getLastFocus()
@@ -126,38 +130,43 @@ QWidget * TimerPanel::getLastFocus()
void TimerPanel::on_value_editingFinished()
{
unsigned val = ui->value->time().hour()*3600 + ui->value->time().minute()*60 + ui->value->time().second();
if (timer.val != val) {
timer.val = val;
emit modified();
if (!lock) {
unsigned val = ui->value->time().hour()*3600 + ui->value->time().minute()*60 + ui->value->time().second();
if (timer.val != val) {
timer.val = val;
emit modified();
}
}
}
void TimerPanel::onModeChanged(int index)
{
if (lock)
return;
bool ok;
const RawSwitch rs(ui->mode->itemData(index).toInt(&ok));
if (ok && timer.mode.toValue() != rs.toValue()) {
timer.mode = rs;
emit modified();
if (!lock) {
bool ok;
const RawSwitch rs(ui->mode->itemData(index).toInt(&ok));
if (ok && timer.mode.toValue() != rs.toValue()) {
timer.mode = rs;
emit modified();
}
}
}
void TimerPanel::on_minuteBeep_toggled(bool checked)
{
timer.minuteBeep = checked;
emit modified();
if (!lock) {
timer.minuteBeep = checked;
emit modified();
}
}
void TimerPanel::on_name_editingFinished()
{
if (QString(timer.name) != ui->name->text()) {
int length = ui->name->maxLength();
strncpy(timer.name, ui->name->text().toLatin1(), length);
emit modified();
if (!lock) {
if (QString(timer.name) != ui->name->text()) {
int length = ui->name->maxLength();
strncpy(timer.name, ui->name->text().toLatin1(), length);
emit modified();
}
}
}
@@ -180,6 +189,8 @@ void TimerPanel::on_name_editingFinished()
#define MASK_SBUSPPM_FIELDS (1<<11)
#define MASK_SUBTYPES (1<<12)
#define MASK_ACCESS (1<<13)
#define MASK_RX_FREQ (1<<14)
#define MASK_RF_POWER (1<<15)
quint8 ModulePanel::failsafesValueDisplayType = ModulePanel::FAILSAFE_DISPLAY_PERCENT;
@@ -195,7 +206,7 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
ui->label_module->setText(ModuleData::indexToString(moduleIdx, firmware));
if (moduleIdx < 0) {
if (!IS_TARANIS(firmware->getBoard())) {
if (!IS_TARANIS(firmware->getBoard()) || IS_ACCESS_RADIO(firmware->getBoard(), Firmware::getCurrentVariant()->getId())) {
ui->trainerMode->setItemData(TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE, 0, Qt::UserRole - 1);
ui->trainerMode->setItemData(TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE, 0, Qt::UserRole - 1);
ui->trainerMode->setItemData(TRAINER_MODE_MASTER_BATTERY_COMPARTMENT, 0, Qt::UserRole - 1);
@@ -209,7 +220,7 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
ui->trainerMode->setItemData(TRAINER_MODE_SLAVE_BLUETOOTH, 0, Qt::UserRole - 1);
}
if (!IS_JUMPER_T16(firmware->getBoard())) {
if (!IS_FAMILY_T16(firmware->getBoard())) {
ui->trainerMode->setItemData(TRAINER_MODE_MULTI, 0, Qt::UserRole - 1);
}
@@ -259,7 +270,7 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul
connect(ui->multiProtocol, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &ModulePanel::onMultiProtocolChanged);
connect(this, &ModulePanel::channelsRangeChanged, this, &ModulePanel::setupFailsafes);
connect(ui->btnGrpValueType, static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked), this, &ModulePanel::onFailsafesDisplayValueTypeChanged);
connect(ui->rxFreq, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &ModulePanel::onRfFreqChanged);
connect(ui->clearRx1, SIGNAL(clicked()), this, SLOT(onClearAccessRxClicked()));
connect(ui->clearRx2, SIGNAL(clicked()), this, SLOT(onClearAccessRxClicked()));
connect(ui->clearRx3, SIGNAL(clicked()), this, SLOT(onClearAccessRxClicked()));
@@ -273,27 +284,12 @@ ModulePanel::~ModulePanel()
delete ui;
}
bool ModulePanel::moduleHasFailsafes()
{
return firmware->getCapability(HasFailsafe) && (
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_ISRM ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCST_ISRM_D16 ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_PXX_XJT_X16 ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_PXX_R9M ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M_LITE ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_ACCESS_R9M_LITE_PRO ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_XJT_LITE_X16 ||
(PulsesProtocol)module.protocol == PulsesProtocol::PULSES_MULTIMODULE
);
}
void ModulePanel::setupFailsafes()
{
ChannelFailsafeWidgetsGroup grp;
const int start = module.channelsStart;
const int end = start + module.channelsCount;
const bool hasFailsafe = moduleHasFailsafes();
const bool hasFailsafe = module.hasFailsafes(firmware);
lock = true;
@@ -382,48 +378,6 @@ void ModulePanel::setupFailsafes()
lock = false;
}
int ModulePanel::getMaxChannelCount()
{
const PulsesProtocol protocol = (PulsesProtocol)module.protocol;
switch (protocol) {
case PULSES_ACCESS_ISRM:
return 24;
case PULSES_PXX_R9M:
case PULSES_ACCESS_R9M:
case PULSES_ACCESS_R9M_LITE:
case PULSES_ACCESS_R9M_LITE_PRO:
case PULSES_ACCST_ISRM_D16:
case PULSES_XJT_LITE_X16:
case PULSES_PXX_XJT_X16:
case PULSES_CROSSFIRE:
case PULSES_SBUS:
case PULSES_PPM:
return 16;
case PULSES_XJT_LITE_LR12:
case PULSES_PXX_XJT_LR12:
return 12;
case PULSES_PXX_DJT:
case PULSES_XJT_LITE_D8:
case PULSES_PXX_XJT_D8:
return 8;
case PULSES_LP45:
case PULSES_DSM2:
case PULSES_DSMX:
return 6;
case PULSES_MULTIMODULE:
if (module.multi.rfProtocol == MODULE_SUBTYPE_MULTI_DSM2)
return 12;
else
return 16;
break;
case PULSES_OFF:
break;
default:
break;
}
return 8;
}
void ModulePanel::update()
{
const PulsesProtocol protocol = (PulsesProtocol)module.protocol;
@@ -436,7 +390,7 @@ void ModulePanel::update()
mask |= MASK_PROTOCOL;
switch (protocol) {
case PULSES_PXX_R9M:
mask |= MASK_R9M | MASK_SUBTYPES;
mask |= MASK_R9M | MASK_RF_POWER | MASK_SUBTYPES;
case PULSES_ACCESS_R9M:
case PULSES_ACCESS_R9M_LITE:
case PULSES_ACCESS_R9M_LITE_PRO:
@@ -495,6 +449,11 @@ void ModulePanel::update()
if (pdef.hasFailsafe || (module.multi.rfProtocol == MODULE_SUBTYPE_MULTI_FRSKY && (module.subType == 0 || module.subType == 2 || module.subType > 3 )))
mask |= MASK_FAILSAFES;
break;
case PULSES_AFHDS3:
module.channelsCount = 18;
mask |= MASK_CHANNELS_RANGE| MASK_CHANNELS_COUNT | MASK_FAILSAFES;
mask |= MASK_SUBTYPES | MASK_RX_FREQ | MASK_RF_POWER;
break;
case PULSES_OFF:
break;
default:
@@ -510,7 +469,7 @@ void ModulePanel::update()
mask |= MASK_PPM_FIELDS | MASK_CHANNELS_RANGE | MASK_CHANNELS_COUNT;
}
if (moduleHasFailsafes()) {
if (module.hasFailsafes(firmware)) {
mask |= MASK_FAILSAFES;
}
@@ -527,7 +486,7 @@ void ModulePanel::update()
ui->label_channelsCount->setVisible(mask & MASK_CHANNELS_RANGE);
ui->channelsCount->setVisible(mask & MASK_CHANNELS_RANGE);
ui->channelsCount->setEnabled(mask & MASK_CHANNELS_COUNT);
ui->channelsCount->setMaximum(getMaxChannelCount());
ui->channelsCount->setMaximum(module.getMaxChannelCount());
ui->channelsCount->setValue(module.channelsCount);
ui->channelsCount->setSingleStep(firmware->getCapability(HasPPMStart) ? 1 : 2);
@@ -561,16 +520,16 @@ void ModulePanel::update()
}
// R9M options
ui->r9mPower->setVisible(mask & MASK_R9M);
ui->label_r9mPower->setVisible(mask & MASK_R9M);
ui->r9mPower->setVisible(mask & MASK_RF_POWER);
ui->label_r9mPower->setVisible(mask & MASK_RF_POWER);
ui->warning_r9mPower->setVisible((mask & MASK_R9M) && module.subType == MODULE_SUBTYPE_R9M_EU);
ui->warning_r9mFlex->setVisible((mask & MASK_R9M) && module.subType > MODULE_SUBTYPE_R9M_EU);
if (mask & MASK_R9M) {
if (mask & MASK_RF_POWER) {
const QSignalBlocker blocker(ui->r9mPower);
ui->r9mPower->clear();
ui->r9mPower->addItems(ModuleData::powerValueStrings(module.subType, firmware));
ui->r9mPower->setCurrentIndex(module.pxx.power);
ui->r9mPower->addItems(ModuleData::powerValueStrings(protocol, module.subType, firmware));
ui->r9mPower->setCurrentIndex(mask & MASK_R9M ? module.pxx.power : module.afhds3.rfPower);
}
// module subtype
@@ -587,6 +546,9 @@ void ModulePanel::update()
if (firmware->getCapability(HasModuleR9MFlex))
i = 2;
break;
case PULSES_AFHDS3:
numEntries = 4;
break;
default:
break;
}
@@ -608,7 +570,7 @@ void ModulePanel::update()
ui->lowPower->setVisible(mask & MASK_MULTIMODULE);
ui->autoBind->setVisible(mask & MASK_MULTIMODULE);
if (module.multi.rfProtocol == MODULE_SUBTYPE_MULTI_DSM2)
ui->autoBind->setText(tr("Autodetect Format"));
ui->autoBind->setVisible(false);
else
ui->autoBind->setText(tr("Bind on channel"));
@@ -651,6 +613,8 @@ void ModulePanel::update()
// Failsafes
ui->label_failsafeMode->setVisible(mask & MASK_FAILSAFES);
ui->failsafeMode->setVisible(mask & MASK_FAILSAFES);
//hide reciever mode for afhds3
qobject_cast<QListView *>(ui->failsafeMode->view())->setRowHidden(FAILSAFE_RECEIVER, protocol == PULSES_AFHDS3);
if ((mask & MASK_FAILSAFES) && module.failsafeMode == FAILSAFE_CUSTOM) {
if (ui->failsafesGroupBox->isHidden()) {
@@ -680,6 +644,9 @@ void ModulePanel::update()
}
}
}
ui->label_rxFreq->setVisible((mask & MASK_RX_FREQ));
ui->rxFreq->setVisible((mask & MASK_RX_FREQ));
}
void ModulePanel::on_trainerMode_currentIndexChanged(int index)
@@ -695,7 +662,7 @@ void ModulePanel::onProtocolChanged(int index)
{
if (!lock && module.protocol != ui->protocol->itemData(index).toUInt()) {
module.protocol = ui->protocol->itemData(index).toInt();
module.channelsCount = getMaxChannelCount();
module.channelsCount = module.getMaxChannelCount();
update();
emit modified();
}
@@ -711,9 +678,14 @@ void ModulePanel::on_ppmPolarity_currentIndexChanged(int index)
void ModulePanel::on_r9mPower_currentIndexChanged(int index)
{
if (!lock && module.pxx.power != (unsigned int)index) {
module.pxx.power = index;
emit modified();
if (!lock) {
if (module.protocol == PULSES_AFHDS3 && module.afhds3.rfPower != (unsigned int)index) {
module.afhds3.rfPower = index;
emit modified();
}
else if(module.pxx.power != (unsigned int)index)
module.pxx.power = index;
}
}
@@ -790,7 +762,7 @@ void ModulePanel::onMultiProtocolChanged(int index)
if (rfProtocol > MODULE_SUBTYPE_MULTI_LAST)
maxSubTypes=8;
module.subType = std::min(module.subType, maxSubTypes -1);
module.channelsCount = getMaxChannelCount();
module.channelsCount = module.getMaxChannelCount();
update();
emit modified();
lock = false;
@@ -811,12 +783,21 @@ void ModulePanel::onSubTypeChanged()
if (!lock && module.subType != type) {
lock=true;
module.subType = type;
update();
if (module.protocol != PULSES_AFHDS3) {
update();
}
emit modified();
lock = false;
}
}
void ModulePanel::onRfFreqChanged(int freq) {
if (module.afhds3.rxFreq != (unsigned int)freq) {
module.afhds3.rxFreq = (unsigned int)freq;
emit modified();
}
}
void ModulePanel::on_disableTelem_stateChanged(int state)
{
module.multi.disableTelemetry = (state == Qt::Checked);
@@ -837,18 +818,22 @@ void ModulePanel::on_lowPower_stateChanged(int state)
module.multi.lowPowerMode = (state == Qt::Checked);
}
// updtSb (update spin box(es)): 0=none or bitmask of FailsafeValueDisplayTypes
void ModulePanel::setChannelFailsafeValue(const int channel, const int value, quint8 updtSb)
void ModulePanel::onFailsafeModified(unsigned channel)
{
if (channel < 0 || channel >= CPN_MAX_CHNOUT)
return;
updateFailsafeUI(channel, FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC);
}
module.failsafeChannels[channel] = value;
void ModulePanel::updateFailsafeUI(unsigned channel, quint8 updtSb)
{
int value = model->limitData[channel].failsafe;
double pctVal = divRoundClosest(value * 1000, 1024) / 10.0;
// qDebug() << value << pctVal;
if (failsafeGroupsMap.contains(channel)) {
const ChannelFailsafeWidgetsGroup & grp = failsafeGroupsMap.value(channel);
bool disable = (value == FAILSAFE_CHANNEL_HOLD || value == FAILSAFE_CHANNEL_NOPULSE);
if (grp.combo) {
grp.combo->setCurrentIndex(grp.combo->findData(disable ? value : 0));
}
if ((updtSb & FAILSAFE_DISPLAY_PERCENT) && grp.sbPercent) {
grp.sbPercent->blockSignals(true);
grp.sbPercent->setValue(pctVal);
@@ -860,8 +845,21 @@ void ModulePanel::setChannelFailsafeValue(const int channel, const int value, qu
grp.sbUsec->blockSignals(false);
}
}
if (!lock)
}
// updtSb (update spin box(es)): 0=none or bitmask of FailsafeValueDisplayTypes
void ModulePanel::setChannelFailsafeValue(const int channel, const int value, quint8 updtSb)
{
if (channel < 0 || channel >= CPN_MAX_CHNOUT)
return;
model->limitData[channel].failsafe = value;
updateFailsafeUI(channel, updtSb);
if (!lock) {
emit failsafeModified(channel);
emit modified();
}
}
void ModulePanel::onFailsafeUsecChanged(int value)
@@ -898,8 +896,9 @@ void ModulePanel::onFailsafeComboIndexChanged(int index)
bool ok = false;
int channel = sender()->property("index").toInt(&ok);
if (ok) {
module.failsafeChannels[channel] = cb->itemData(index).toInt();
model->limitData[channel].failsafe = cb->itemData(index).toInt();
updateFailsafe(channel);
emit failsafeModified(channel);
emit modified();
}
lock = false;
@@ -931,12 +930,12 @@ void ModulePanel::onExtendedLimitsToggled()
}
}
void ModulePanel::updateFailsafe(int channel)
void ModulePanel::updateFailsafe(unsigned channel)
{
if (channel >= CPN_MAX_CHNOUT || !failsafeGroupsMap.contains(channel))
return;
const int failsafeValue = module.failsafeChannels[channel];
const int failsafeValue = model->limitData[channel].failsafe;
const ChannelFailsafeWidgetsGroup & grp = failsafeGroupsMap.value(channel);
const bool valDisable = (failsafeValue == FAILSAFE_CHANNEL_HOLD || failsafeValue == FAILSAFE_CHANNEL_NOPULSE);
@@ -948,7 +947,7 @@ void ModulePanel::updateFailsafe(int channel)
grp.sbUsec->setDisabled(valDisable);
if (!valDisable)
setChannelFailsafeValue(channel, failsafeValue, (FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC));
setChannelFailsafeValue(channel, failsafeValue, FAILSAFE_DISPLAY_PERCENT | FAILSAFE_DISPLAY_USEC);
}
void ModulePanel::onClearAccessRxClicked()
@@ -1001,7 +1000,7 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
QDir qd(path);
if (qd.exists()) {
QStringList filters;
if(IS_HORUS(board)) {
if(IS_FAMILY_HORUS_OR_T16(board)) {
filters << "*.bmp" << "*.jpg" << "*.png";
foreach ( QString file, qd.entryList(filters, QDir::Files) ) {
QFileInfo fi(file);
@@ -1032,17 +1031,17 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
ui->image->setCurrentIndex(ui->image->count()-1);
QString fileName = path;
fileName.append(model.bitmap);
if (!IS_HORUS(board))
if (!IS_FAMILY_HORUS_OR_T16(board))
fileName.append(".bmp");
QImage image(fileName);
if (image.isNull() && !IS_HORUS(board)) {
if (image.isNull() && !IS_FAMILY_HORUS_OR_T16(board)) {
fileName = path;
fileName.append(model.bitmap);
fileName.append(".BMP");
image.load(fileName);
}
if (!image.isNull()) {
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
ui->imagePreview->setFixedSize(QSize(192, 114));
ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(192, 114)));
}
@@ -1064,16 +1063,28 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
RawSwitchFilterItemModel * swModel = new RawSwitchFilterItemModel(&generalSettings, &model, RawSwitch::TimersContext, this);
connect(this, &SetupPanel::updated, swModel, &RawSwitchFilterItemModel::update);
for (int i=0; i<CPN_MAX_TIMERS; i++) {
if (i<firmware->getCapability(Timers)) {
timersCount = firmware->getCapability(Timers);
for (int i = 0; i < CPN_MAX_TIMERS; i++) {
if (i < timersCount) {
timers[i] = new TimerPanel(this, model, model.timers[i], generalSettings, firmware, prevFocus, swModel);
ui->gridLayout->addWidget(timers[i], 1+i, 1);
connect(timers[i], &TimerPanel::modified, this, &SetupPanel::modified);
connect(this, &SetupPanel::updated, timers[i], &TimerPanel::update);
connect(this, &SetupPanel::timerUpdated, timers[i], &TimerPanel::update);
prevFocus = timers[i]->getLastFocus();
// TODO more reliable method required
QLabel *label = findChild<QLabel *>(QString("label_timer%1").arg(i + 1));
if (label) { // to stop crashing if not found
label->setProperty("index", i);
label->setContextMenuPolicy(Qt::CustomContextMenu);
label->setToolTip(tr("Popup menu available"));
label->setMouseTracking(true);
connect(label, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onTimerCustomContextMenuRequested(QPoint)));
}
}
else {
foreach(QLabel *label, findChildren<QLabel *>(QRegularExpression(QString("label_timer%1").arg(i+1)))) {
foreach(QLabel *label, findChildren<QLabel *>(QRegularExpression(QString("label_timer%1").arg(i + 1 )))) { //TODO more reliable method required
label->hide();
}
}
@@ -1081,9 +1092,9 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
if (firmware->getCapability(HasTopLcd)) {
ui->toplcdTimer->setField(model.toplcdTimer, this);
for (int i=0; i<CPN_MAX_TIMERS; i++) {
if (i<firmware->getCapability(Timers)) {
ui->toplcdTimer->addItem(tr("Timer %1").arg(i+1), i);
for (int i = 0; i < CPN_MAX_TIMERS; i++) {
if (i<timersCount) {
ui->toplcdTimer->addItem(tr("Timer %1").arg(i + 1), i);
}
}
}
@@ -1191,21 +1202,23 @@ SetupPanel::SetupPanel(QWidget * parent, ModelData & model, GeneralSettings & ge
ui->potWarningMode->hide();
}
if (IS_ARM(board)) {
ui->trimsDisplay->setField(model.trimsDisplay, this);
}
else {
ui->labelTrimsDisplay->hide();
ui->trimsDisplay->hide();
}
ui->trimsDisplay->setField(model.trimsDisplay, this);
for (int i=firmware->getCapability(NumFirstUsableModule); i<firmware->getCapability(NumModules); i++) {
for (int i = firmware->getCapability(NumFirstUsableModule); i < firmware->getCapability(NumModules); i++) {
modules[i] = new ModulePanel(this, model, model.moduleData[i], generalSettings, firmware, i);
ui->modulesLayout->addWidget(modules[i]);
connect(modules[i], &ModulePanel::modified, this, &SetupPanel::modified);
connect(this, &SetupPanel::extendedLimitsToggled, modules[i], &ModulePanel::onExtendedLimitsToggled);
}
for (int i = firmware->getCapability(NumFirstUsableModule); i < firmware->getCapability(NumModules); i++) {
for (int j = firmware->getCapability(NumFirstUsableModule); j < firmware->getCapability(NumModules); j++) {
if (i != j) {
connect(modules[i], SIGNAL(failsafeModified(unsigned)), modules[j], SLOT(onFailsafeModified(unsigned)));
}
}
}
if (firmware->getCapability(ModelTrainerEnable)) {
modules[CPN_MAX_MODULES] = new ModulePanel(this, model, model.moduleData[CPN_MAX_MODULES], generalSettings, firmware, -1);
ui->modulesLayout->addWidget(modules[CPN_MAX_MODULES]);
@@ -1281,17 +1294,17 @@ void SetupPanel::on_image_currentIndexChanged(int index)
if (qd.exists()) {
QString fileName=path;
fileName.append(model->bitmap);
if (!IS_HORUS(board))
if (!IS_FAMILY_HORUS_OR_T16(board))
fileName.append(".bmp");
QImage image(fileName);
if (image.isNull() && !IS_HORUS(board)) {
if (image.isNull() && !IS_FAMILY_HORUS_OR_T16(board)) {
fileName=path;
fileName.append(model->bitmap);
fileName.append(".BMP");
image.load(fileName);
}
if (!image.isNull()) {
if (IS_HORUS(board)) {
if (IS_FAMILY_HORUS_OR_T16(board)) {
ui->imagePreview->setFixedSize(QSize(192, 114));
ui->imagePreview->setPixmap(QPixmap::fromImage(image.scaled(192, 114)));
}
@@ -1528,3 +1541,155 @@ void SetupPanel::on_editText_clicked()
}
}
void SetupPanel::onTimerCustomContextMenuRequested(QPoint pos)
{
QLabel *label = (QLabel *)sender();
selectedTimerIndex = label->property("index").toInt();
QPoint globalPos = label->mapToGlobal(pos);
QMenu contextMenu;
contextMenu.addAction(CompanionIcon("copy.png"), tr("Copy"), this, SLOT(cmTimerCopy()));
contextMenu.addAction(CompanionIcon("cut.png"), tr("Cut"), this, SLOT(cmTimerCut()));
contextMenu.addAction(CompanionIcon("paste.png"), tr("Paste"), this, SLOT(cmTimerPaste()))->setEnabled(hasTimerClipboardData());
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear"), this, SLOT(cmTimerClear()));
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("arrow-right.png"), tr("Insert"), this, SLOT(cmTimerInsert()))->setEnabled(insertTimerAllowed());
contextMenu.addAction(CompanionIcon("arrow-left.png"), tr("Delete"), this, SLOT(cmTimerDelete()));
contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"), this, SLOT(cmTimerMoveUp()))->setEnabled(moveTimerUpAllowed());
contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"), this, SLOT(cmTimerMoveDown()))->setEnabled(moveTimerDownAllowed());
contextMenu.addSeparator();
contextMenu.addAction(CompanionIcon("clear.png"), tr("Clear All"), this, SLOT(cmTimerClearAll()));
contextMenu.exec(globalPos);
}
bool SetupPanel::hasTimerClipboardData(QByteArray * data) const
{
const QClipboard * clipboard = QApplication::clipboard();
const QMimeData * mimeData = clipboard->mimeData();
if (mimeData->hasFormat(MIMETYPE_TIMER)) {
if (data)
data->append(mimeData->data(MIMETYPE_TIMER));
return true;
}
return false;
}
bool SetupPanel::insertTimerAllowed() const
{
return ((selectedTimerIndex < timersCount - 1) && (model->timers[timersCount - 1].isEmpty()));
}
bool SetupPanel::moveTimerDownAllowed() const
{
return selectedTimerIndex < timersCount - 1;
}
bool SetupPanel::moveTimerUpAllowed() const
{
return selectedTimerIndex > 0;
}
void SetupPanel::cmTimerClear()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear Timer. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
model->timers[selectedTimerIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_CLEAR, selectedTimerIndex);
emit timerUpdated();
emit modified();
}
void SetupPanel::cmTimerClearAll()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Clear all Timers. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
for (int i = 0; i < timersCount; i++) {
model->timers[i].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_CLEAR, i);
}
emit timerUpdated();
emit modified();
}
void SetupPanel::cmTimerCopy()
{
QByteArray data;
data.append((char*)&model->timers[selectedTimerIndex], sizeof(TimerData));
QMimeData *mimeData = new QMimeData;
mimeData->setData(MIMETYPE_TIMER, data);
QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard);
}
void SetupPanel::cmTimerCut()
{
cmTimerCopy();
cmTimerClear();
}
void SetupPanel::cmTimerDelete()
{
if (QMessageBox::question(this, CPN_STR_APP_NAME, tr("Delete Timer. Are you sure?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No)
return;
int maxidx = timersCount - 1;
for (int i = selectedTimerIndex; i < maxidx; i++) {
if (!model->timers[i].isEmpty() || !model->timers[i + 1].isEmpty()) {
memcpy(&model->timers[i], &model->timers[i+1], sizeof(TimerData));
}
}
model->timers[maxidx].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SHIFT, selectedTimerIndex, 0, -1);
emit timerUpdated();
emit modified();
}
void SetupPanel::cmTimerInsert()
{
for (int i = (timersCount - 1); i > selectedTimerIndex; i--) {
if (!model->timers[i].isEmpty() || !model->timers[i-1].isEmpty()) {
memcpy(&model->timers[i], &model->timers[i-1], sizeof(TimerData));
}
}
model->timers[selectedTimerIndex].clear();
model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SHIFT, selectedTimerIndex, 0, 1);
emit timerUpdated();
emit modified();
}
void SetupPanel::cmTimerMoveDown()
{
swapTimerData(selectedTimerIndex, selectedTimerIndex + 1);
}
void SetupPanel::cmTimerMoveUp()
{
swapTimerData(selectedTimerIndex, selectedTimerIndex - 1);
}
void SetupPanel::cmTimerPaste()
{
QByteArray data;
if (hasTimerClipboardData(&data)) {
TimerData *td = &model->timers[selectedTimerIndex];
memcpy(td, data.constData(), sizeof(TimerData));
emit timerUpdated();
emit modified();
}
}
void SetupPanel::swapTimerData(int idx1, int idx2)
{
if ((idx1 != idx2) && (!model->timers[idx1].isEmpty() || !model->timers[idx2].isEmpty())) {
TimerData tdtmp = model->timers[idx2];
TimerData *td1 = &model->timers[idx1];
TimerData *td2 = &model->timers[idx2];
memcpy(td2, td1, sizeof(TimerData));
memcpy(td1, &tdtmp, sizeof(TimerData));
model->updateAllReferences(ModelData::REF_UPD_TYPE_TIMER, ModelData::REF_UPD_ACT_SWAP, idx1, idx2);
emit timerUpdated();
emit modified();
}
}
+26 -4
View File
@@ -24,6 +24,8 @@
#include "modeledit.h"
#include "eeprominterface.h"
constexpr char MIMETYPE_TIMER[] = "application/x-companion-timer";
class RawSwitchFilterItemModel;
namespace Ui {
@@ -59,19 +61,19 @@ class ModulePanel : public ModelPanel
Q_OBJECT
public:
ModulePanel(QWidget *parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx);
ModulePanel(QWidget * parent, ModelData & model, ModuleData & module, GeneralSettings & generalSettings, Firmware * firmware, int moduleIdx);
virtual ~ModulePanel();
virtual void update();
bool moduleHasFailsafes();
public slots:
void onExtendedLimitsToggled();
void onFailsafeModified(unsigned index);
signals:
void channelsRangeChanged();
void failsafeModified(unsigned index);
private slots:
int getMaxChannelCount();
void setupFailsafes();
void on_trainerMode_currentIndexChanged(int index);
void onProtocolChanged(int index);
@@ -95,7 +97,8 @@ class ModulePanel : public ModelPanel
void onFailsafeUsecChanged(int value);
void onFailsafePercentChanged(double value);
void onFailsafesDisplayValueTypeChanged(int type);
void updateFailsafe(int channel);
void onRfFreqChanged(int freq);
void updateFailsafe(unsigned channel);
void on_optionValue_editingFinished();
void onClearAccessRxClicked();
@@ -114,6 +117,7 @@ class ModulePanel : public ModelPanel
Ui::Module *ui;
QMap<int, ChannelFailsafeWidgetsGroup> failsafeGroupsMap;
static quint8 failsafesValueDisplayType; // FailsafeValueDisplayTypes
void updateFailsafeUI(unsigned channel, quint8 updtSb);
};
class SetupPanel : public ModelPanel
@@ -129,6 +133,7 @@ class SetupPanel : public ModelPanel
signals:
void extendedLimitsToggled();
void updated();
void timerUpdated();
private slots:
void on_name_editingFinished();
@@ -148,6 +153,16 @@ class SetupPanel : public ModelPanel
void potWarningToggled(bool checked);
void on_potWarningMode_currentIndexChanged(int index);
void on_editText_clicked();
void onTimerCustomContextMenuRequested(QPoint pos);
void cmTimerClear();
void cmTimerClearAll();
void cmTimerCopy();
void cmTimerCut();
void cmTimerDelete();
void cmTimerInsert();
void cmTimerPaste();
void cmTimerMoveDown();
void cmTimerMoveUp();
private:
Ui::Setup *ui;
@@ -161,6 +176,13 @@ class SetupPanel : public ModelPanel
void updatePotWarnings();
void updateBeepCenter();
void populateThrottleSourceCB();
int timersCount;
int selectedTimerIndex;
bool hasTimerClipboardData(QByteArray * data = nullptr) const;
bool insertTimerAllowed() const;
bool moveTimerDownAllowed() const;
bool moveTimerUpAllowed() const;
void swapTimerData(int idx1, int idx2);
};
#endif // _SETUP_H_
+1 -1
View File
@@ -590,7 +590,7 @@ If this is checked the throttle will be reversed. Idle will be forward, trim wi
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_timer3_2">
<widget class="QLabel" name="label_timer3">
<property name="font">
<font>
<weight>50</weight>
+150 -24
View File
@@ -126,6 +126,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
@@ -173,6 +179,15 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="suffix">
<string/>
</property>
@@ -214,6 +229,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
@@ -417,6 +438,7 @@
<item>
<widget class="QCheckBox" name="autoBind">
<property name="text">
<string/>
</property>
</widget>
</item>
@@ -485,6 +507,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
@@ -529,6 +557,12 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
@@ -573,6 +607,15 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="suffix">
<string> ms</string>
</property>
@@ -617,19 +660,58 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_rxFreq">
<property name="text">
<string>RX Frequency</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_option">
<property name="text">
<string>Option value</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="optionValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_ppmOutputType">
<property name="text">
<string>Output type</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QComboBox" name="ppmOutputType">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -652,21 +734,7 @@
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_option">
<property name="text">
<string>Option value</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="optionValue">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<item row="7" column="0" colspan="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -679,6 +747,34 @@
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="rxFreq">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="suffix">
<string> Hz</string>
</property>
<property name="minimum">
<number>50</number>
</property>
<property name="maximum">
<number>400</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
@@ -711,11 +807,17 @@
<item row="0" column="1">
<widget class="QComboBox" name="protocol">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>180</width>
<height>0</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
@@ -754,11 +856,17 @@
<item row="2" column="1">
<widget class="QComboBox" name="multiProtocol">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
@@ -774,11 +882,17 @@
<item row="3" column="1">
<widget class="QComboBox" name="multiSubType">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
@@ -847,11 +961,17 @@
<item row="5" column="1">
<widget class="QComboBox" name="failsafeMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
@@ -901,11 +1021,17 @@
<item row="6" column="1">
<widget class="QComboBox" name="trainerMode">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
@@ -934,17 +1060,17 @@
<string>Master/SBUS in battery compartment</string>
</property>
</item>
<item>
<item>
<property name="text">
<string>Master/Bluetooth</string>
</property>
</item>
<item>
<item>
<property name="text">
<string>Slave/Bluetooth</string>
</property>
</item>
<item>
<item>
<property name="text">
<string>Master/Multi</string>
</property>

Some files were not shown because too many files have changed in this diff Show More