Compare commits
214 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6c44fff39d | |||
| 8848fad8f9 | |||
| bc4028bf8c | |||
| 4fdbed2c76 | |||
| df0162048f | |||
| a6410c7a5b | |||
| 50557c38bc | |||
| f4f99b14ea | |||
| 7b68109f3d | |||
| b6d85433c6 | |||
| 578a305a5f | |||
| 6cb6084afb | |||
| 712a66fe6f | |||
| db97a2653a | |||
| 0d49d27ee2 | |||
| 42d036b510 | |||
| 1bbe107c07 | |||
| 098324f5b9 | |||
| 8c3bcb28b1 | |||
| 1e504d040b | |||
| f01f5cdb89 | |||
| bd2699f2ca | |||
| 37170ea8d6 | |||
| 90874090e7 | |||
| 36c6311cb2 | |||
| 30cccb30a4 | |||
| 6e0a65c0d6 | |||
| 20f933019a | |||
| 5b00408d46 | |||
| 78243be714 | |||
| 64cf7c16f8 | |||
| 1fb0810778 | |||
| 79b94bd361 | |||
| 6e43250671 | |||
| 5656851168 | |||
| 601c0ca80e | |||
| 264a007c6e | |||
| a6509a1380 | |||
| 54b45db3fd | |||
| 5027eac7b3 | |||
| cf9ba4152c | |||
| be3c5c4796 | |||
| 980b30f5bf | |||
| 7b7e195604 | |||
| ae34fa0637 | |||
| ff57ed6c4c | |||
| de00bda9e4 | |||
| 37933643ad | |||
| 53bac0e0b7 | |||
| 65a73161b0 | |||
| b9911c0c71 | |||
| 4355e8e3a4 | |||
| 74e699fd7f | |||
| 23dfbddb1d | |||
| b9c0f8309c | |||
| b7770cb9d0 | |||
| a829f643f6 | |||
| 642b3b2773 | |||
| dc4ccebae8 | |||
| 02c8bcf0fa | |||
| 509a1f27df | |||
| 5c9467f134 | |||
| cdb18612e3 | |||
| 8d0ab09a02 | |||
| becd3fe3a2 | |||
| 61518190e7 | |||
| 7526eb3985 | |||
| 3d59de9f95 | |||
| 187c802b5e | |||
| 345d980bb1 | |||
| c4bf58f13d | |||
| 8c660c356c | |||
| cbfc78e01c | |||
| d54c952a10 | |||
| 1796c5be57 | |||
| 7a9f8576ed | |||
| 2aa401fa28 | |||
| 653dc3d0d0 | |||
| d4033efd84 | |||
| e4b5746c47 | |||
| 2ca2b3be1b | |||
| ab93580b54 | |||
| a60e55d8bc | |||
| ce052fb64c | |||
| c6f694f96f | |||
| 0a1dfa8064 | |||
| b857f928ac | |||
| 9883aeced7 | |||
| d222e0c828 | |||
| 089e50f176 | |||
| cef12652bc | |||
| 9c73f0ba41 | |||
| 25cdeff642 | |||
| d3bad3d98a | |||
| 29fb4a6fda | |||
| 730bc8c608 | |||
| 8c85b7504b | |||
| 787a6ef983 | |||
| 232b9d6c20 | |||
| f1cc0a3666 | |||
| 1eb52f27fb | |||
| 2c6ed340b4 | |||
| 0c3a4883f5 | |||
| bfe760868f | |||
| d135e22b52 | |||
| d1bf393c3c | |||
| 7d0f9efc7b | |||
| 4f99e86706 | |||
| 117977654e | |||
| 218073256c | |||
| a46aa6cd41 | |||
| 30f0cbceb2 | |||
| ec0e2dd441 | |||
| 8cf1f96796 | |||
| 906a36c1d2 | |||
| b2f7ee1349 | |||
| 7975ccb5bf | |||
| cb8c33b60e | |||
| 35ce95d401 | |||
| 07ddec8a1f | |||
| e92ca34661 | |||
| 8d59090460 | |||
| 08f70bc61b | |||
| 0cfd640680 | |||
| 25ce79f9e0 | |||
| bef750fd30 | |||
| 4b5101532e | |||
| 30cc26d38b | |||
| 08c7f53436 | |||
| 377ae33a9e | |||
| 0094efecfb | |||
| 045c381f3c | |||
| 92f4a9491d | |||
| a2c7f2ca73 | |||
| 996961cc09 | |||
| fdb270f663 | |||
| 4784ab7828 | |||
| 253e1bab88 | |||
| 6a15221c2c | |||
| 515cf67b77 | |||
| b9c6d7d40b | |||
| d690f5dda3 | |||
| 72cdc95761 | |||
| 71863e6e36 | |||
| cee474e736 | |||
| 132c61057a | |||
| 55bf59142a | |||
| 2d21fb54e1 | |||
| 894a9a6f04 | |||
| d594b30aa7 | |||
| 55697a1b2c | |||
| 8b0f8a35e0 | |||
| 1cc697d40d | |||
| 6a29d3e5ae | |||
| c5bf0e784a | |||
| 4837bb2f12 | |||
| e6620995b9 | |||
| 2991da1d94 | |||
| 8c9f821bec | |||
| 76568c5f50 | |||
| 919441f457 | |||
| 7aeb2ab303 | |||
| 7b379f3362 | |||
| 02ce3cc0de | |||
| 57cd700211 | |||
| b5e36699b3 | |||
| 8ca138a7ba | |||
| 23c9efa514 | |||
| f261118a1c | |||
| d38a7b05f2 | |||
| cfb54bb70d | |||
| eba227d9da | |||
| 8a5b9f8583 | |||
| 2df15a9f3d | |||
| f70087b5ef | |||
| f0e41eed2e | |||
| 00ab31550c | |||
| 30ef400791 | |||
| 9e50103155 | |||
| e3d1afff56 | |||
| 013de8882d | |||
| 116fe0dcb6 | |||
| cddbcd95fb | |||
| a0fbfee721 | |||
| 6439a977f2 | |||
| 3b0e93a527 | |||
| 6975eef35d | |||
| 8b45512103 | |||
| 4edb931b7c | |||
| c0fd5fafb1 | |||
| 8ecba27adb | |||
| ae029aa3f5 | |||
| 1fc6ca33d1 | |||
| 2633c4549e | |||
| 80bd182513 | |||
| 40ac4608a7 | |||
| c8ff7bb9e2 | |||
| cd2f352772 | |||
| 8c73df5e65 | |||
| ec1eb77ab7 | |||
| 73c03318d2 | |||
| d516b15e82 | |||
| 79d446b2af | |||
| cb9fe3c500 | |||
| e27aeba53f | |||
| 0bdb08e41c | |||
| 7e5f5ce4b1 | |||
| bfa3592810 | |||
| 07f02a29e5 | |||
| 338363b05d | |||
| 047e4f7065 | |||
| 0271823db9 | |||
| d827395434 | |||
| 94ced113c3 |
@@ -673,3 +673,78 @@ John Hennig
|
||||
RK Custom Homes
|
||||
James Houck
|
||||
Piet Teekens
|
||||
Tommy Widenflycht
|
||||
Johan Petrus Theophilus Maria van Melis
|
||||
Ralph Gustafson
|
||||
Paul Luby
|
||||
Andrew Duncan
|
||||
Stephen Crowther
|
||||
Edward Glover
|
||||
Kelly Byrd
|
||||
Brad Curtis
|
||||
Wolfgang Kuhl
|
||||
LitePilots - litepilots.com
|
||||
John Beidl
|
||||
Roy Nixon
|
||||
Glen Roe
|
||||
CY Enterprise
|
||||
Evening Shade Pottery
|
||||
Gilles Dando
|
||||
Patrick Richard
|
||||
Justin Altemeier
|
||||
Constant Dupuis
|
||||
Tony Kenward
|
||||
Pierre Rondel
|
||||
Ernest Luguera Sanchez
|
||||
Adam Brackney
|
||||
Joe Baker
|
||||
单 雷平
|
||||
Ben Fay
|
||||
Chris Monk
|
||||
Stan von Miller
|
||||
Christian Krebs
|
||||
Michel Motte
|
||||
Graziano Rampinelli
|
||||
Joe Baker
|
||||
Jean-Philippe Laurent
|
||||
Romain Rouzaud
|
||||
Michel Garbarino
|
||||
Henri Mirra
|
||||
Otto Fröhlich
|
||||
Thomas Cramer
|
||||
Anthony Trombetta
|
||||
Fernando Rimoldi
|
||||
Dietmar Drees
|
||||
Michal Kowalski
|
||||
Ivan Correa
|
||||
Modellbau
|
||||
Massimo Luigi Stara
|
||||
Graham Baldwin
|
||||
Tomasz Rejman
|
||||
Wolfgang Lang
|
||||
John Greenwood
|
||||
Till von Reumont
|
||||
Paul Pereira Brunner
|
||||
Donald L Singer
|
||||
Junsun Lee
|
||||
Guy Lamaison
|
||||
Erwin Dulken
|
||||
Mike H Dailey
|
||||
Jon Cammarata
|
||||
Martin Krueger
|
||||
Adolfo Perogio
|
||||
Sylvain Techer
|
||||
Wes Warner
|
||||
Kevin Caldwell
|
||||
Ali Ersan Gur
|
||||
Hans-Rudolf Riniker
|
||||
Sébastien Boutard
|
||||
Jean Chessé
|
||||
Mike H Dailey
|
||||
Don Polk
|
||||
Roberto Orsello
|
||||
Borovikov Dmitriy
|
||||
John Lipscomb
|
||||
Peter Glassey
|
||||
Joseph Kramer
|
||||
F.Javier Martinez Velasco
|
||||
|
||||
@@ -1,4 +1,33 @@
|
||||
<h2>Version 2.0.14 / todo</h2>
|
||||
<h2>Version 2.0.16 / 2015-05-03</h2>
|
||||
<ul>
|
||||
<li><i>nooverridech</i> firmware option was not working</li>
|
||||
<li>Fixed setting Expo from gvars for 9XR-Pro (<a href=https://github.com/opentx/opentx/issues/2040>#2040</a>)</li>
|
||||
<li>Added Mixers Monitor screen option <i>mixersmon</i> (<a href=https://github.com/opentx/opentx/issues/1945>#1945</a>)</li>
|
||||
<li>Added audio playing in simulator (<a href=https://github.com/opentx/opentx/issues/457>#457</a>)</li>
|
||||
<li>Fixed sorting of audio tracks (<a href=https://github.com/opentx/opentx/issues/2002>#2002</a>)</li>
|
||||
<li>Model wizard fixes (<a href=https://github.com/opentx/opentx/issues/2091>#2091</a>)</li>
|
||||
<li>GVAR names removed for 9x, radio doesn't support them (<a href=https://github.com/opentx/opentx/issues/2150>#2150</a>)</li>
|
||||
<li>Some LS sources didn't follow the Imperial units setting (<a href=https://github.com/opentx/opentx/issues/2180>#2180</a>)</li>
|
||||
<li>Added more fields to the telemetry simulator (<a href=https://github.com/opentx/opentx/issues/2171>#2171</a>)</li>
|
||||
<li>Log viewer improvements and massive speed increase (<a href=https://github.com/opentx/opentx/issues/1863>#1863</a>, <a href=https://github.com/opentx/opentx/issues/2163>#2163</a>)</li>
|
||||
<li>Added Battery meter range setting (<a href=https://github.com/opentx/opentx/issues/2195>#2195</a>)</li>
|
||||
<li>Improvements in Print and Compare dialogs (<a href=https://github.com/opentx/opentx/issues/2219>#2219</a>)</li>
|
||||
<li>Reset pots to the middle by right double clicking them in Simulator (<a href=https://github.com/opentx/opentx/issues/1939>#1939</a>)</li>
|
||||
<li>Minor fixes: <a href=https://github.com/opentx/opentx/issues/2153>#2153</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/2138>#2138</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/2090>#2090</a>,
|
||||
<a href=https://github.com/opentx/opentx/issues/2122>#2122</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.0.15 / 2015-01-13</h2>
|
||||
<ul>
|
||||
<li>Firmware was not written correctly on radio when compatibility warning check enabled</li>
|
||||
<li>Time format for Special Functions Set Timers</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.14 / 2015-01-12</h2>
|
||||
<ul>
|
||||
<li>OpenTX Companion and Companion9x can now be installed side by side on Linux</li>
|
||||
<li>Improved TAB order in dialogs</li>
|
||||
@@ -12,7 +41,7 @@
|
||||
<li>Added Debug Output window</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
<li>Various small bug-fixes</li>
|
||||
<li>More reliable method of writing EEPROM.BIN and FRIMWARE.BIN to radio</li>
|
||||
<li>More reliable method of writing EEPROM.BIN and FIRMWARE.BIN to radio</li>
|
||||
<li>Fixed issue with Edge function INSTANT for V1>2s</li>
|
||||
<li>Fixed buffer overflow in Joystick code</li>
|
||||
</ul>
|
||||
@@ -87,13 +116,13 @@
|
||||
<ul>
|
||||
<li>Sound should be ok on all platforms</li>
|
||||
<li>Min/Max reviewed in Logical switches (for the whole telemetry)</li>
|
||||
<li>Various bug fixes</li>
|
||||
<li>Various bug fixes</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.3</h2>
|
||||
<ul>
|
||||
<li>EEPROM import bug on AdjustGVAR function</li>
|
||||
<li>Timers correctly displayed in logical switches tab</li>
|
||||
<li>Timers correctly displayed in logical switches tab</li>
|
||||
</ul>
|
||||
|
||||
<h2>Version 2.0.2</h2>
|
||||
@@ -267,4 +296,4 @@
|
||||
<li>Try to reduce modeledit window form MAC</li>
|
||||
<li>Wrong init of RF-Module data</li>
|
||||
<li>Read flash from TX didn't worked for Taranis</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
@@ -2,7 +2,7 @@ PROJECT( companion )
|
||||
|
||||
SET( C9X_VERSION_MAJOR "2" )
|
||||
SET( C9X_VERSION_MINOR "0" )
|
||||
SET( C9X_VERSION_REVISION "14" )
|
||||
SET( C9X_VERSION_REVISION "16" )
|
||||
SET( C9X_VERSION ${C9X_VERSION_MAJOR}.${C9X_VERSION_MINOR}.${C9X_VERSION_REVISION} )
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
|
||||
@@ -33,8 +33,9 @@ IF ( SDL_FOUND )
|
||||
INCLUDE_DIRECTORIES( ${SDL_INCLUDE_DIR} )
|
||||
MESSAGE("SDL Include Path: " ${SDL_INCLUDE_DIR} )
|
||||
ADD_DEFINITIONS( -DJOYSTICKS )
|
||||
ADD_DEFINITIONS( -DSIMU_AUDIO )
|
||||
ELSE()
|
||||
MESSAGE( "SDL not found! Joysticks support will be disabled" )
|
||||
MESSAGE( "SDL not found! Joysticks support will be disabled. Simulator audio will not work." )
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(Qt4 4.8.4 REQUIRED)
|
||||
@@ -106,6 +107,7 @@ include_directories(
|
||||
|
||||
add_subdirectory(modeledit)
|
||||
add_subdirectory(simulation)
|
||||
add_subdirectory(qcustomplot)
|
||||
|
||||
set(common_SRCS
|
||||
eeprominterface.cpp
|
||||
@@ -114,7 +116,7 @@ set(common_SRCS
|
||||
firmwares/er9x/er9xeeprom.cpp
|
||||
firmwares/er9x/er9xinterface.cpp
|
||||
firmwares/gruvin9x/gruvin9xeeprom.cpp
|
||||
firmwares/gruvin9x/gruvin9xinterface.cpp
|
||||
firmwares/gruvin9x/gruvin9xinterface.cpp
|
||||
firmwares/ersky9x/ersky9xeeprom.cpp
|
||||
firmwares/ersky9x/ersky9xinterface.cpp
|
||||
${RADIO_SRC_DIRECTORY}/bitmaps/sticks.lbm
|
||||
@@ -147,7 +149,7 @@ set(companion_SRCS
|
||||
mdichild.cpp
|
||||
generaledit.cpp
|
||||
modelslist.cpp
|
||||
mountlist.cpp
|
||||
mountlist.cpp
|
||||
avroutputdialog.cpp
|
||||
apppreferencesdialog.cpp
|
||||
fwpreferencesdialog.cpp
|
||||
@@ -164,7 +166,6 @@ set(companion_SRCS
|
||||
mainwindow.cpp
|
||||
companion.cpp
|
||||
radionotfound.cpp
|
||||
qcustomplot.cpp
|
||||
wizarddata.cpp
|
||||
wizarddialog.cpp
|
||||
)
|
||||
@@ -189,12 +190,11 @@ set(companion_MOC_HDRS
|
||||
mdichild.h
|
||||
mainwindow.h
|
||||
radionotfound.h
|
||||
qcustomplot.h
|
||||
qautocombobox.h
|
||||
helpers.h
|
||||
wizarddialog.h
|
||||
)
|
||||
|
||||
|
||||
set(companion_UIS
|
||||
mdichild.ui
|
||||
avroutputdialog.ui
|
||||
@@ -276,14 +276,18 @@ QT4_ADD_RESOURCES( companion_SRCS ${companion_RCS} )
|
||||
ADD_DEFINITIONS( -DQT_TRANSLATIONS_DIR="${QT_TRANSLATIONS_DIR}" )
|
||||
|
||||
IF( APPLE )
|
||||
ADD_EXECUTABLE( ${PROJECT_NAME} MACOSX_BUNDLE ${companion_SRCS} ${companion_QM} )
|
||||
ADD_EXECUTABLE(companion MACOSX_BUNDLE ${companion_SRCS} ${companion_QM})
|
||||
# OS X compiler no longer automatically includes /Library/Frameworks in search path
|
||||
SET( CMAKE_EXE_LINKER_FLAGS -F/Library/Frameworks )
|
||||
ELSE( )
|
||||
ADD_EXECUTABLE( ${PROJECT_NAME} WIN32 ${companion_SRCS} ${companion_QM} )
|
||||
ADD_EXECUTABLE(companion WIN32 ${companion_SRCS} ${companion_QM})
|
||||
ENDIF( )
|
||||
|
||||
TARGET_LINK_LIBRARIES( ${PROJECT_NAME} modeledit simulation common ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${XERCESC_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS} )
|
||||
if(SDL_FOUND)
|
||||
target_link_libraries(companion modeledit simulation common qcustomplot ${QT_LIBRARIES} ${XERCESC_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS} )
|
||||
else()
|
||||
target_link_libraries(companion modeledit simulation common qcustomplot ${QT_LIBRARIES} ${QT_QTMAIN_LIBRARY} ${XERCESC_LIBRARY} ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${PHONON_LIBS} )
|
||||
endif()
|
||||
|
||||
############# Standalone simu ###############
|
||||
|
||||
@@ -354,6 +358,7 @@ endif()
|
||||
|
||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
INSTALL( TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin )
|
||||
INSTALL( TARGETS simulator DESTINATION ${CMAKE_INSTALL_PREFIX}/bin )
|
||||
INSTALL( FILES companion.desktop DESTINATION share/applications )
|
||||
INSTALL( FILES images/linuxicons/16x16/companion.png DESTINATION /usr/share/icons/hicolor/16x16/apps )
|
||||
INSTALL( FILES images/linuxicons/22x22/companion.png DESTINATION /usr/share/icons/hicolor/22x22/apps )
|
||||
@@ -373,20 +378,20 @@ ENDIF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
IF( WIN32 )
|
||||
IF( MSVC )
|
||||
SET( NSI_IN_FILE companion-vs.nsi.in )
|
||||
SET( NSI_IN_FILE companion-vs.nsi.in )
|
||||
ELSE( )
|
||||
SET( NSI_IN_FILE companion-msys.nsi.in )
|
||||
ENDIF( )
|
||||
|
||||
SET( SYSDIR "$ENV{windir}/system32" )
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${NSI_IN_FILE} ${CMAKE_CURRENT_BINARY_DIR}/companion.nsi @ONLY)
|
||||
SET( SYSDIR "$ENV{windir}/system32" )
|
||||
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/../targets/windows/${NSI_IN_FILE} ${CMAKE_CURRENT_BINARY_DIR}/companion.nsi @ONLY)
|
||||
|
||||
FIND_PROGRAM(NSIS_EXE makensis.exe PATHS
|
||||
"C:/Program Files/NSIS"
|
||||
"C:/Program Files (x86)/NSIS"
|
||||
"C:/Program Files (x86)/NSIS"
|
||||
"C:/Programs/NSIS"
|
||||
)
|
||||
|
||||
|
||||
ADD_CUSTOM_COMMAND(OUTPUT ${PROJECT_BINARY_DIR}/companionInstall.exe
|
||||
COMMAND "${NSIS_EXE}" ARGS companion.nsi
|
||||
DEPENDS ${PROJECT_NAME} simulator ${PROJECT_BINARY_DIR}/companion.nsi
|
||||
@@ -405,11 +410,11 @@ IF( APPLE )
|
||||
ELSE( )
|
||||
SET( WORK_DIR ${PROJECT_BINARY_DIR} )
|
||||
ENDIF()
|
||||
|
||||
ADD_CUSTOM_TARGET( addframeworks ALL
|
||||
|
||||
ADD_CUSTOM_TARGET( addframeworks ALL
|
||||
COMMAND mkdir -p companion.app/Contents/Frameworks
|
||||
COMMAND mkdir -p companion.app/Contents/Resources
|
||||
COMMAND mkdir -p companion.app/Contents/translations
|
||||
COMMAND mkdir -p companion.app/Contents/translations
|
||||
COMMAND rsync ${PROJECT_SOURCE_DIR}/images/${MACOSX_BUNDLE_ICON_FILE} companion.app/Contents/Resources/${MACOSX_BUNDLE_ICON_FILE} # Copy the icon files
|
||||
COMMAND rsync -r --exclude=.svn ${PROJECT_SOURCE_DIR}/../targets/mac/qt_menu.nib companion.app/Contents/Resources/
|
||||
COMMAND rsync -r /Library/Frameworks/SDL.framework companion.app/Contents/Frameworks/
|
||||
@@ -418,7 +423,7 @@ IF( APPLE )
|
||||
COMMAND install_name_tool -change @rpath/SDL.framework/Versions/A/SDL @executable_path/../Frameworks/SDL.framework/Versions/A/SDL companion.app/Contents/MacOS/companion
|
||||
WORKING_DIRECTORY ${WORK_DIR}
|
||||
DEPENDS ${PROJECT_NAME} )
|
||||
|
||||
|
||||
ADD_CUSTOM_TARGET( makedmg
|
||||
COMMAND ${QT_BINARY_DIR}/macdeployqt companion.app -dmg -no-plugins
|
||||
WORKING_DIRECTORY ${WORK_DIR}
|
||||
@@ -427,7 +432,7 @@ IF( APPLE )
|
||||
ENDIF( )
|
||||
|
||||
ADD_CUSTOM_TARGET( stamp
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/version.h ${CMAKE_SOURCE_DIR}/../companion.stamp
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/version.h ${CMAKE_SOURCE_DIR}/../companion.stamp
|
||||
DEPENDS ${CMAKE_BINARY_DIR}/version.h )
|
||||
|
||||
IF(WIN32)
|
||||
@@ -463,6 +468,6 @@ else(DPKG_PROGRAM)
|
||||
SET(CPACK_RPM_PACKAGE_VERSION ${C9X_VERSION})
|
||||
SET(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY})
|
||||
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME_LOWERCASE}-${C9X_VERSION}-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif(DPKG_PROGRAM)
|
||||
endif(DPKG_PROGRAM)
|
||||
|
||||
INCLUDE(CPack)
|
||||
|
||||
+61
-23
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Kjell Kernen
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
@@ -20,7 +20,7 @@ AppData g;
|
||||
// ** CompStoreObj class********************
|
||||
void CompStoreObj::clear (const QString tag1, const QString tag2, const QString tag3)
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (tag2.isEmpty())
|
||||
{
|
||||
settings.remove(tag1);
|
||||
@@ -43,7 +43,7 @@ void CompStoreObj::clear (const QString tag1, const QString tag2, const QString
|
||||
|
||||
void CompStoreObj::store(const QByteArray newArray, QByteArray &array, const QString tag, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
@@ -56,7 +56,7 @@ void CompStoreObj::store(const QByteArray newArray, QByteArray &array, const QSt
|
||||
|
||||
void CompStoreObj::store(const QStringList newSList, QStringList &stringList, const QString tag, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
@@ -69,7 +69,7 @@ void CompStoreObj::store(const QStringList newSList, QStringList &stringList, co
|
||||
|
||||
void CompStoreObj::store(const QString newString, QString &string, const QString tag, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
@@ -82,7 +82,7 @@ void CompStoreObj::store(const QString newString, QString &string, const QString
|
||||
|
||||
void CompStoreObj::store(const bool newTruth, bool &truth, const QString tag, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
@@ -95,7 +95,7 @@ void CompStoreObj::store(const bool newTruth, bool &truth, const QString tag, co
|
||||
|
||||
void CompStoreObj::store(const int newNumber, int &number, const QString tag, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
@@ -109,7 +109,7 @@ void CompStoreObj::store(const int newNumber, int &number, const QString tag, co
|
||||
// Retrieval functions
|
||||
void CompStoreObj::retrieve( QByteArray &array, const QString tag, const QString def, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
@@ -121,7 +121,7 @@ void CompStoreObj::retrieve( QByteArray &array, const QString tag, const QString
|
||||
|
||||
void CompStoreObj::retrieve( QStringList &stringList, const QString tag, const QString def, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
@@ -133,7 +133,7 @@ void CompStoreObj::retrieve( QStringList &stringList, const QString tag, const Q
|
||||
|
||||
void CompStoreObj::retrieve( QString &string, const QString tag, const QString def, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
@@ -145,7 +145,7 @@ void CompStoreObj::retrieve( QString &string, const QString tag, const QString d
|
||||
|
||||
void CompStoreObj::retrieve( bool &truth, const QString tag, const bool def, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
@@ -157,7 +157,7 @@ void CompStoreObj::retrieve( bool &truth, const QString tag, const bool def, con
|
||||
|
||||
void CompStoreObj::retrieve( int &number, const QString tag, const int def, const QString group1, const QString group2 )
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (!group1.isEmpty()) settings.beginGroup(group1);
|
||||
if (!group2.isEmpty()) settings.beginGroup(group2);
|
||||
|
||||
@@ -241,7 +241,7 @@ JStickData::JStickData()
|
||||
void JStickData::remove()
|
||||
{
|
||||
// Remove all JStickData values from settings file
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
settings.beginGroup( "JsCalibration" );
|
||||
settings.remove( QString( "stick%1_axe").arg(index) );
|
||||
settings.remove( QString( "stick%1_min").arg(index) );
|
||||
@@ -256,7 +256,7 @@ void JStickData::remove()
|
||||
|
||||
bool JStickData::existsOnDisk()
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
settings.beginGroup("JsCalibration");
|
||||
int axe = settings.value( QString("stick%1_axe").arg(index), -1 ).toInt();
|
||||
settings.endGroup();
|
||||
@@ -295,8 +295,10 @@ QString Profile::fwName() const { return _fwName; }
|
||||
QString Profile::fwType() const { return _fwType; }
|
||||
QString Profile::name() const { return _name; }
|
||||
QString Profile::sdPath() const { return _sdPath; }
|
||||
QString Profile::pBackupDir() const { return _pBackupDir; }
|
||||
QString Profile::splashFile() const { return _splashFile; }
|
||||
bool Profile::burnFirmware() const { return _burnFirmware; }
|
||||
bool Profile::penableBackup() const { return _penableBackup; }
|
||||
bool Profile::renameFwFiles() const { return _renameFwFiles; }
|
||||
int Profile::channelOrder() const { return _channelOrder; }
|
||||
int Profile::defaultMode() const { return _defaultMode; }
|
||||
@@ -313,6 +315,8 @@ int Profile::currentCalib() const { return _currentCalib; }
|
||||
int Profile::gsStickMode() const { return _gsStickMode; }
|
||||
int Profile::ppmMultiplier() const { return _ppmMultiplier; }
|
||||
int Profile::vBatCalib() const { return _vBatCalib; }
|
||||
int Profile::vBatMin() const { return _vBatMin; }
|
||||
int Profile::vBatMax() const { return _vBatMax; }
|
||||
int Profile::vBatWarn() const { return _vBatWarn; }
|
||||
|
||||
// Set declarations
|
||||
@@ -320,9 +324,11 @@ void Profile::name (const QString x) { store(x, _name, "Name"
|
||||
void Profile::fwName (const QString x) { store(x, _fwName, "fwName" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::fwType (const QString x) { store(x, _fwType, "fwType" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::sdPath (const QString x) { store(x, _sdPath, "sdPath" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::pBackupDir (const QString x) { store(x, _pBackupDir, "pBackupDir" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::splashFile (const QString x) { store(x, _splashFile, "SplashFileName" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::burnFirmware (const bool x) { store(x, _burnFirmware, "burnFirmware" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::renameFwFiles (const bool x) { store(x, _renameFwFiles, "rename_firmware_files" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::penableBackup (const bool x) { store(x, _penableBackup, "penableBackup" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::channelOrder (const int x) { store(x, _channelOrder, "default_channel_order" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::defaultMode (const int x) { store(x, _defaultMode, "default_mode" ,"Profiles", QString("profile%1").arg(index));}
|
||||
|
||||
@@ -338,6 +344,8 @@ void Profile::currentCalib (const int x) { store(x, _currentCalib, "curren
|
||||
void Profile::gsStickMode (const int x) { store(x, _gsStickMode, "GSStickMode" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::ppmMultiplier (const int x) { store(x, _ppmMultiplier, "PPM_Multiplier" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::vBatCalib (const int x) { store(x, _vBatCalib, "VbatCalib" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::vBatMin (const int x) { store(x, _vBatMin, "VbatMin" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::vBatMax (const int x) { store(x, _vBatMax, "VbatMax" ,"Profiles", QString("profile%1").arg(index));}
|
||||
void Profile::vBatWarn (const int x) { store(x, _vBatWarn, "vBatWarn" ,"Profiles", QString("profile%1").arg(index));}
|
||||
|
||||
// Constructor
|
||||
@@ -346,16 +354,18 @@ Profile::Profile()
|
||||
index = -1;
|
||||
}
|
||||
|
||||
// The default copy operator can not be used since the index variable would be destroyed
|
||||
// The default copy operator can not be used since the index variable would be destroyed
|
||||
Profile& Profile::operator=(const Profile& rhs)
|
||||
{
|
||||
name ( rhs.name() );
|
||||
fwName ( rhs.fwName() );
|
||||
fwType ( rhs.fwType() );
|
||||
sdPath ( rhs.sdPath() );
|
||||
pBackupDir ( rhs.pBackupDir() );
|
||||
splashFile ( rhs.splashFile() );
|
||||
burnFirmware ( rhs.burnFirmware() );
|
||||
renameFwFiles( rhs.renameFwFiles() );
|
||||
penableBackup( rhs.penableBackup() );
|
||||
channelOrder ( rhs.channelOrder() );
|
||||
defaultMode ( rhs.defaultMode() );
|
||||
beeper ( rhs.beeper() );
|
||||
@@ -369,6 +379,8 @@ Profile& Profile::operator=(const Profile& rhs)
|
||||
gsStickMode ( rhs.gsStickMode() );
|
||||
ppmMultiplier( rhs.ppmMultiplier() );
|
||||
vBatCalib ( rhs.vBatCalib() );
|
||||
vBatMin ( rhs.vBatMin() );
|
||||
vBatMax ( rhs.vBatMax() );
|
||||
vBatWarn ( rhs.vBatWarn() );
|
||||
|
||||
return *this;
|
||||
@@ -377,7 +389,7 @@ Profile& Profile::operator=(const Profile& rhs)
|
||||
void Profile::remove()
|
||||
{
|
||||
// Remove all profile values from settings file
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
settings.beginGroup("Profiles");
|
||||
settings.remove(QString("profile%1").arg(index));
|
||||
settings.endGroup();
|
||||
@@ -388,7 +400,7 @@ void Profile::remove()
|
||||
|
||||
bool Profile::existsOnDisk()
|
||||
{
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
settings.beginGroup("Profiles");
|
||||
settings.beginGroup(QString("profile%1").arg(index));
|
||||
QStringList keyList = settings.allKeys();
|
||||
@@ -413,6 +425,8 @@ void Profile::initFwVariables()
|
||||
_gsStickMode = 0;
|
||||
_ppmMultiplier = 0;
|
||||
_vBatCalib = 0;
|
||||
_vBatMin = 0;
|
||||
_vBatMax = 0;
|
||||
_vBatWarn = 0;
|
||||
}
|
||||
|
||||
@@ -424,9 +438,11 @@ void Profile::init(int newIndex)
|
||||
_fwType = "";
|
||||
_name = "";
|
||||
_sdPath = "";
|
||||
_pBackupDir = "";
|
||||
_splashFile = "";
|
||||
_burnFirmware = false;
|
||||
_renameFwFiles = false;
|
||||
_penableBackup = false;
|
||||
_channelOrder = 0;
|
||||
_defaultMode = 1;
|
||||
|
||||
@@ -446,8 +462,10 @@ void Profile::flush()
|
||||
getset( _fwType, "fwType" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _name, "Name" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _sdPath, "sdPath" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _pBackupDir, "pBackupDir" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _splashFile, "SplashFileName" ,"" ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _burnFirmware, "burnFirmware" ,false ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _penableBackup, "penableBackup" ,false ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _renameFwFiles, "rename_firmware_files" ,false ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _channelOrder, "default_channel_order" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _defaultMode, "default_mode" ,1 ,"Profiles", QString("profile%1").arg(index));
|
||||
@@ -464,6 +482,8 @@ void Profile::flush()
|
||||
getset( _gsStickMode, "GSStickMode" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _ppmMultiplier, "PPM_Multiplier" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _vBatCalib, "VbatCalib" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _vBatMin, "VbatMin" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _vBatMax, "VbatMax" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
getset( _vBatWarn, "vBatWarn" ,0 ,"Profiles", QString("profile%1").arg(index));
|
||||
}
|
||||
|
||||
@@ -583,11 +603,29 @@ AppData::AppData()
|
||||
for (int i=0; i<MAX_JOYSTICKS; i++)
|
||||
joystick[i].init( i );
|
||||
|
||||
// Import settings from companion9x, but only do it one time.
|
||||
QSettings c9x_settings("companion9x", "companion9x");
|
||||
QSettings settings(PRODUCT, COMPANY);
|
||||
if (profile[0].name().isEmpty() )
|
||||
// Move existing 2.0 settings if present
|
||||
QSettings settings(COMPANY, PRODUCT);
|
||||
if (profile[0].name().isEmpty())
|
||||
{
|
||||
QSettings pre2016settings("OpenTX", "OpenTX Companion");
|
||||
|
||||
QStringList keys = pre2016settings.allKeys();
|
||||
for (QStringList::iterator i=keys.begin(); i!=keys.end(); i++)
|
||||
{
|
||||
settings.setValue(*i, pre2016settings.value(*i));
|
||||
}
|
||||
|
||||
//Reload profiles
|
||||
for (int i=0; i<MAX_PROFILES; i++)
|
||||
profile[i].init( i );
|
||||
|
||||
pre2016settings.clear();
|
||||
}
|
||||
|
||||
// Else import settings from companion9x if present
|
||||
if (profile[0].name().isEmpty())
|
||||
{
|
||||
QSettings c9x_settings("companion9x", "companion9x");
|
||||
// Copy all settings from companion9x to companion
|
||||
QStringList keys = c9x_settings.allKeys();
|
||||
for (QStringList::iterator i=keys.begin(); i!=keys.end(); i++)
|
||||
@@ -631,7 +669,7 @@ AppData::AppData()
|
||||
settings.remove("patchImage");
|
||||
settings.remove("rename_firmware_files");
|
||||
settings.remove("sdPath");
|
||||
settings.remove("SplashFileName");
|
||||
settings.remove("SplashFileName");
|
||||
settings.remove("startup_check_companion9x");
|
||||
settings.remove("wizardEnable");
|
||||
|
||||
@@ -647,7 +685,7 @@ AppData::AppData()
|
||||
|
||||
// Load and store all variables. Use default values if setting values are missing
|
||||
QString _tempString; // Do not touch. Do not change the settings version before a new verson update!
|
||||
getset( _tempString, "settings_version" ,"20" ); // This is a version marker. Will be used to upgrade the settings later on.
|
||||
getset( _tempString, "settings_version" ,"201" ); // This is a version marker. Will be used to upgrade the settings later on.
|
||||
|
||||
getset( _recentFiles, "recentFileList" ,"" );
|
||||
getset( _mainWinGeo, "mainWindowGeometry" ,"" );
|
||||
|
||||
+18
-6
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Kjell Kernen
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
@@ -12,7 +12,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// All temporary and permanent global variables are defined here to make
|
||||
// All temporary and permanent global variables are defined here to make
|
||||
// initialization and storage safe and visible.
|
||||
// Do not access variables in QSettings directly, it is not type safe!
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
#include <QString>
|
||||
#include <QSettings>
|
||||
|
||||
#define COMPANY "OpenTX Companion"
|
||||
#define PRODUCT "OpenTX"
|
||||
#define COMPANY "OpenTX"
|
||||
#define PRODUCT "Companion 2.0"
|
||||
|
||||
#define MAX_PROFILES 15
|
||||
#define MAX_JOYSTICKS 8
|
||||
@@ -53,7 +53,7 @@ class CompStoreObj
|
||||
void getset( QString &string, const QString tag, const QString def, const QString group1="", const QString group2="" );
|
||||
void getset( bool &truth, const QString tag, const bool def, const QString group1="", const QString group2="" );
|
||||
void getset( int &number, const QString tag, const int def, const QString group1="", const QString group2="" );
|
||||
};
|
||||
};
|
||||
|
||||
class FwRevision: protected CompStoreObj
|
||||
{
|
||||
@@ -107,8 +107,10 @@ class Profile: protected CompStoreObj
|
||||
QString _fwType;
|
||||
QString _name;
|
||||
QString _sdPath;
|
||||
QString _pBackupDir;
|
||||
QString _splashFile;
|
||||
bool _burnFirmware;
|
||||
bool _penableBackup;
|
||||
bool _renameFwFiles;
|
||||
int _channelOrder;
|
||||
int _defaultMode;
|
||||
@@ -126,6 +128,8 @@ class Profile: protected CompStoreObj
|
||||
int _gsStickMode;
|
||||
int _ppmMultiplier;
|
||||
int _vBatCalib;
|
||||
int _vBatMin;
|
||||
int _vBatMax;
|
||||
int _vBatWarn;
|
||||
|
||||
public:
|
||||
@@ -134,9 +138,11 @@ class Profile: protected CompStoreObj
|
||||
QString fwType() const;
|
||||
QString name() const;
|
||||
QString sdPath() const;
|
||||
QString pBackupDir() const;
|
||||
QString splashFile() const;
|
||||
bool burnFirmware() const;
|
||||
bool renameFwFiles() const;
|
||||
bool penableBackup() const;
|
||||
int channelOrder() const;
|
||||
int defaultMode() const;
|
||||
|
||||
@@ -152,6 +158,8 @@ class Profile: protected CompStoreObj
|
||||
int gsStickMode() const;
|
||||
int ppmMultiplier() const;
|
||||
int vBatCalib() const;
|
||||
int vBatMin() const;
|
||||
int vBatMax() const;
|
||||
int vBatWarn() const;
|
||||
|
||||
// All the set definitions
|
||||
@@ -159,9 +167,11 @@ class Profile: protected CompStoreObj
|
||||
void fwName (const QString);
|
||||
void fwType (const QString);
|
||||
void sdPath (const QString);
|
||||
void pBackupDir (const QString);
|
||||
void splashFile (const QString);
|
||||
void burnFirmware (const bool);
|
||||
void renameFwFiles (const bool);
|
||||
void penableBackup (const bool);
|
||||
void channelOrder (const int);
|
||||
void defaultMode (const int);
|
||||
|
||||
@@ -177,6 +187,8 @@ class Profile: protected CompStoreObj
|
||||
void gsStickMode (const int);
|
||||
void ppmMultiplier (const int);
|
||||
void vBatCalib (const int);
|
||||
void vBatMin (const int);
|
||||
void vBatMax (const int);
|
||||
void vBatWarn (const int);
|
||||
|
||||
Profile();
|
||||
@@ -260,7 +272,7 @@ class AppData: protected CompStoreObj
|
||||
QString avrdudeLocation();
|
||||
QString dfuArguments();
|
||||
QString dfuLocation();
|
||||
QString lastFw();
|
||||
QString lastFw();
|
||||
QString locale();
|
||||
QString mcu();
|
||||
QString programmer();
|
||||
|
||||
@@ -66,6 +66,8 @@ void AppPreferencesDialog::writeValues()
|
||||
g.profile[g.id()].renameFwFiles(ui->renameFirmware->isChecked());
|
||||
g.profile[g.id()].burnFirmware(ui->burnFirmware->isChecked());
|
||||
g.profile[g.id()].sdPath(ui->sdPath->text());
|
||||
g.profile[g.id()].pBackupDir(ui->profilebackupPath->text());
|
||||
g.profile[g.id()].penableBackup(ui->pbackupEnable->isChecked());
|
||||
g.profile[g.id()].splashFile(ui->SplashFileName->text());
|
||||
|
||||
// The profile name may NEVER be empty
|
||||
@@ -164,6 +166,18 @@ void AppPreferencesDialog::initSettings()
|
||||
ui->stickmodeCB->setCurrentIndex(g.profile[g.id()].defaultMode());
|
||||
ui->renameFirmware->setChecked(g.profile[g.id()].renameFwFiles());
|
||||
ui->sdPath->setText(g.profile[g.id()].sdPath());
|
||||
if (!g.profile[g.id()].pBackupDir().isEmpty()) {
|
||||
if (QDir(g.profile[g.id()].pBackupDir()).exists()) {
|
||||
ui->profilebackupPath->setText(g.profile[g.id()].pBackupDir());
|
||||
ui->pbackupEnable->setEnabled(true);
|
||||
ui->pbackupEnable->setChecked(g.profile[g.id()].penableBackup());
|
||||
} else {
|
||||
ui->pbackupEnable->setDisabled(true);
|
||||
}
|
||||
} else {
|
||||
ui->pbackupEnable->setDisabled(true);
|
||||
}
|
||||
|
||||
ui->profileNameLE->setText(g.profile[g.id()].name());
|
||||
ui->SplashFileName->setText(g.profile[g.id()].splashFile());
|
||||
|
||||
@@ -224,8 +238,17 @@ void AppPreferencesDialog::on_backupPathButton_clicked()
|
||||
if (!fileName.isEmpty()) {
|
||||
g.backupDir(fileName);
|
||||
ui->backupPath->setText(fileName);
|
||||
ui->backupEnable->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_ProfilebackupPathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this,tr("Select your Models and Settings backup folder"), g.backupDir());
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->profilebackupPath->setText(fileName);
|
||||
ui->pbackupEnable->setEnabled(true);
|
||||
}
|
||||
ui->backupEnable->setEnabled(true);
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_ge_pathButton_clicked()
|
||||
|
||||
@@ -47,8 +47,9 @@ class AppPreferencesDialog : public QDialog
|
||||
void on_snapshotPathButton_clicked();
|
||||
void on_snapshotClipboardCKB_clicked();
|
||||
void on_backupPathButton_clicked();
|
||||
void on_ProfilebackupPathButton_clicked();
|
||||
void on_ge_pathButton_clicked();
|
||||
|
||||
|
||||
void on_sdPathButton_clicked();
|
||||
void on_removeProfileButton_clicked();
|
||||
void on_SplashSelect_clicked();
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>685</width>
|
||||
<width>686</width>
|
||||
<height>550</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -26,13 +26,7 @@
|
||||
<string>Edit Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="verticalSpacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@@ -42,7 +36,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
@@ -51,110 +45,8 @@
|
||||
<attribute name="title">
|
||||
<string>Radio Profile</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,0,1,0,0,0,0,0">
|
||||
<item row="21" column="7">
|
||||
<widget class="QPushButton" name="sdPathButton">
|
||||
<property name="text">
|
||||
<string>Open Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="25" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Default Channel Order</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Build Options</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="langLabel">
|
||||
<property name="text">
|
||||
<string>Menu Language</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="23" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Default Stick Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="7">
|
||||
<widget class="QPushButton" name="SplashSelect">
|
||||
<property name="text">
|
||||
<string>Select Image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="22" column="1">
|
||||
<widget class="QLabel" name="lblGeneralSettings">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">General Settings Label</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="8">
|
||||
<widget class="Line" name="line_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1" colspan="7">
|
||||
<layout class="QGridLayout" name="optionsLayout"/>
|
||||
</item>
|
||||
<item row="14" 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="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Splash Screen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1,0,0">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="font">
|
||||
<font>
|
||||
@@ -167,51 +59,17 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="7">
|
||||
<widget class="QPushButton" name="clearImageButton">
|
||||
<property name="text">
|
||||
<string>Clear Image</string>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="profileNameLE"/>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<widget class="Line" name="line_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="1">
|
||||
<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>212</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
@@ -234,57 +92,24 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="19" column="0" colspan="8">
|
||||
<widget class="Line" name="line_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="downloadVerCB">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="8">
|
||||
<widget class="Line" name="line_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="20" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="langLabel">
|
||||
<property name="text">
|
||||
<string>Other Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="22" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>General Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="21" column="0">
|
||||
<widget class="QLabel" name="sdPathLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>SD Structure path</string>
|
||||
<string>Menu Language</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1" colspan="7">
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1,1">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
@@ -338,14 +163,46 @@ May be different from firmware language</string>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="7">
|
||||
<widget class="QComboBox" name="downloadVerCB">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Build Options</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1" colspan="6">
|
||||
<item row="4" column="1">
|
||||
<layout class="QGridLayout" name="optionsLayout"/>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="4">
|
||||
<widget class="Line" name="line_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" 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="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Splash Screen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="SplashFileName">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
@@ -355,17 +212,150 @@ May be different from firmware language</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="21" column="1" colspan="6">
|
||||
<item row="7" column="1">
|
||||
<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>212</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="4">
|
||||
<widget class="Line" name="line_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Other Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="sdPathLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>SD Structure path</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="sdPath">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="23" column="1" colspan="6">
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="profilebackupPathLabel">
|
||||
<property name="toolTip">
|
||||
<string>The profile specific folder, if set, will override general Backup folder</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Backup folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QLineEdit" name="profilebackupPath">
|
||||
<property name="toolTip">
|
||||
<string>If set it will override the application general setting</string>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QCheckBox" name="pbackupEnable">
|
||||
<property name="toolTip">
|
||||
<string>if set, will override general backup enable</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable automatic backup before writing firmware</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>General Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QLabel" name="lblGeneralSettings">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">General Settings Label</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Default Stick Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QComboBox" name="stickmodeCB">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
@@ -419,7 +409,23 @@ Mode 4:
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="25" column="1" colspan="6">
|
||||
<item row="15" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Default Channel Order</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<widget class="QComboBox" name="channelorderCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
@@ -567,31 +573,21 @@ Mode 4:
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="6">
|
||||
<widget class="QLineEdit" name="profileNameLE"/>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<widget class="QPushButton" name="removeProfileButton">
|
||||
<property name="text">
|
||||
<string>Remove Profile</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="26" column="1" colspan="7">
|
||||
<item row="16" column="1">
|
||||
<widget class="QCheckBox" name="renameFirmware">
|
||||
<property name="text">
|
||||
<string>Append version number to FW file name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="27" column="1" colspan="7">
|
||||
<item row="17" column="1">
|
||||
<widget class="QCheckBox" name="burnFirmware">
|
||||
<property name="text">
|
||||
<string>Offer to write FW to Tx after download</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="28" column="1">
|
||||
<item row="18" column="1">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -604,6 +600,44 @@ Mode 4:
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="7" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="clearImageButton">
|
||||
<property name="text">
|
||||
<string>Clear Image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="SplashSelect">
|
||||
<property name="text">
|
||||
<string>Select Image</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="removeProfileButton">
|
||||
<property name="text">
|
||||
<string>Remove Profile</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="sdPathButton">
|
||||
<property name="text">
|
||||
<string>Open Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="ProfilebackupPathButton">
|
||||
<property name="toolTip">
|
||||
<string>The profile specific folder, if set, will override general Backup folder</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="applicationTab">
|
||||
@@ -611,17 +645,7 @@ Mode 4:
|
||||
<string>Application Settings</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="4" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="showSplash">
|
||||
<property name="text">
|
||||
<string>Show splash screen when Companion starts</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1" colspan="4">
|
||||
<item row="7" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="startupCheck_companion9x">
|
||||
<property name="text">
|
||||
<string>Automatic check for Companion updates</string>
|
||||
@@ -631,28 +655,38 @@ Mode 4:
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1" colspan="4">
|
||||
<item row="4" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="showSplash">
|
||||
<property name="text">
|
||||
<string>Show splash screen when Companion starts</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="backupEnable">
|
||||
<property name="text">
|
||||
<string>Enable automatic backup before writing firmware</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="4">
|
||||
<item row="3" column="1" colspan="3">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1" colspan="4">
|
||||
<item row="8" column="1" colspan="3">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="4">
|
||||
<item row="6" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="startupCheck_fw">
|
||||
<property name="text">
|
||||
<string>Automatic check for OpenTX firmware updates</string>
|
||||
@@ -668,23 +702,10 @@ Mode 4:
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
@@ -698,13 +719,6 @@ Mode 4:
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="9" column="4">
|
||||
<widget class="QPushButton" name="backupPathButton">
|
||||
<property name="text">
|
||||
<string>Open Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="sizePolicy">
|
||||
@@ -731,27 +745,13 @@ Mode 4:
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QPushButton" name="ge_pathButton">
|
||||
<property name="text">
|
||||
<string>Find Executable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="4">
|
||||
<item row="1" column="1" colspan="3">
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="4">
|
||||
<widget class="QPushButton" name="libraryPathButton">
|
||||
<property name="text">
|
||||
<string>Open Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLineEdit" name="backupPath">
|
||||
<property name="minimumSize">
|
||||
@@ -761,7 +761,7 @@ Mode 4:
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -772,26 +772,6 @@ Mode 4:
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" 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="13" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="sizePolicy">
|
||||
@@ -834,18 +814,39 @@ Mode 4:
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<item row="11" column="1" colspan="3">
|
||||
<widget class="Line" name="line_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="modelWizard_CB">
|
||||
<property name="text">
|
||||
<string>Use model wizard when creating a new model</string>
|
||||
</property>
|
||||
</spacer>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" 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="0" column="1">
|
||||
<widget class="QLineEdit" name="ge_lineedit">
|
||||
@@ -860,17 +861,24 @@ Mode 4:
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1" colspan="4">
|
||||
<widget class="Line" name="line_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<item row="0" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="ge_pathButton">
|
||||
<property name="text">
|
||||
<string>Find Executable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="4">
|
||||
<widget class="QCheckBox" name="modelWizard_CB">
|
||||
<item row="9" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="backupPathButton">
|
||||
<property name="text">
|
||||
<string>Use model wizard when creating a new model</string>
|
||||
<string>Open Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="libraryPathButton">
|
||||
<property name="text">
|
||||
<string>Open Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -1050,7 +1058,6 @@ Mode 4:
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>tabWidget</tabstop>
|
||||
<tabstop>profileNameLE</tabstop>
|
||||
<tabstop>removeProfileButton</tabstop>
|
||||
<tabstop>downloadVerCB</tabstop>
|
||||
<tabstop>langCombo</tabstop>
|
||||
|
||||
@@ -426,6 +426,7 @@ void burnDialog::on_BurnFlashButton_clicked()
|
||||
tempFile = generateProcessUniqueTempFileName("flash.hex");
|
||||
else
|
||||
tempFile = generateProcessUniqueTempFileName("flash.bin");
|
||||
qDebug() << "burnDialog::on_BurnFlashButton_clicked(): patching" << fileName << "with custom splash screen and saving to" << tempFile;
|
||||
FlashInterface flash(fileName);
|
||||
flash.setSplash(image);
|
||||
if (flash.saveFlash(tempFile) > 0) {
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
# XSD_FOUND, If false, don't try to use xsd
|
||||
|
||||
FIND_PATH( XSD_INCLUDE_DIR xsd/cxx/parser/elements.hxx
|
||||
"/opt/local/xsd-3.3.0-i686-macosx/libxsd"
|
||||
"/opt/local/xsd-3.3.0-i686-macosx/libxsd"
|
||||
"C:/Programs/xsd-3.3.0/libxsd"
|
||||
"C:/Program Files/CodeSynthesis XSD 3.2/include"
|
||||
"C:/mingw/xsd-3.3.0-i686-windows/libxsd"
|
||||
$ENV{XSDDIR}/include
|
||||
$ENV{CODESYNTH}/include
|
||||
/usr/local/include /usr/include
|
||||
/usr/local/include /usr/include
|
||||
$ENV{XSDDIR}/libxsd
|
||||
)
|
||||
|
||||
IF( WIN32 )
|
||||
@@ -27,18 +28,19 @@ ENDIF( )
|
||||
FIND_PROGRAM( XSDCXX_EXECUTABLE
|
||||
NAMES
|
||||
${XSDCXX_FILENAME1} ${XSDCXX_FILENAME2}
|
||||
PATHS
|
||||
PATHS
|
||||
"/opt/local/xsd-3.3.0-i686-macosx/bin"
|
||||
"C:/Programs/xsd-3.3.0/bin"
|
||||
"C:/mingw/xsd-3.3.0-i686-windows/bin"
|
||||
"C:/mingw/xsd-3.3.0-i686-windows/bin"
|
||||
"C:/Program Files/CodeSynthesis XSD 3.2/bin"
|
||||
$ENV{XSDDIR}/bin
|
||||
/usr/local/bin
|
||||
/usr/bin
|
||||
$ENV{XSDDIR}/xsd
|
||||
)
|
||||
|
||||
MESSAGE(STATUS ${XSDCXX_EXECUTABLE})
|
||||
|
||||
|
||||
# if the include and the program are found then we have it
|
||||
IF( XSD_INCLUDE_DIR )
|
||||
IF( XSDCXX_EXECUTABLE )
|
||||
@@ -49,4 +51,4 @@ ENDIF( XSD_INCLUDE_DIR )
|
||||
MARK_AS_ADVANCED(
|
||||
XSD_INCLUDE_DIR
|
||||
XSDCXX_EXECUTABLE
|
||||
)
|
||||
)
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
#include <QSplashScreen>
|
||||
#include <QThread>
|
||||
#include <iostream>
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
#include "mainwindow.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "appdata.h"
|
||||
@@ -95,9 +98,22 @@ int main(int argc, char *argv[])
|
||||
app.installTranslator(&qtTranslator);
|
||||
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
RegisterEepromInterfaces();
|
||||
registerOpenTxFirmwares();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
uint32_t sdlFlags = 0;
|
||||
#ifdef JOYSTICKS
|
||||
sdlFlags |= SDL_INIT_JOYSTICK;
|
||||
#endif
|
||||
#ifdef SIMU_AUDIO
|
||||
sdlFlags |= SDL_INIT_AUDIO;
|
||||
#endif
|
||||
if (SDL_Init(sdlFlags) < 0) {
|
||||
fprintf(stderr, "ERROR: couldn't initialize SDL: %s\n", SDL_GetError());
|
||||
}
|
||||
#endif
|
||||
|
||||
RegisterEepromInterfaces();
|
||||
registerOpenTxFirmwares();
|
||||
|
||||
if (g.profile[g.id()].fwType().isEmpty()){
|
||||
g.profile[g.id()].fwType(default_firmware_variant->getId());
|
||||
@@ -133,5 +149,9 @@ int main(int argc, char *argv[])
|
||||
UnregisterFirmwares();
|
||||
UnregisterEepromInterfaces();
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
SDL_Quit();
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+197
-80
@@ -24,8 +24,9 @@ public:
|
||||
uint8_t models[C9X_MAX_MODELS];
|
||||
};
|
||||
|
||||
CompareDialog::CompareDialog(QWidget * parent):
|
||||
CompareDialog::CompareDialog(QWidget * parent, FirmwareInterface * firmware):
|
||||
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
||||
firmware(firmware),
|
||||
model1(0),
|
||||
model2(0),
|
||||
ui(new Ui::CompareDialog)
|
||||
@@ -75,6 +76,8 @@ void CompareDialog::dragLeaveEvent(QDragLeaveEvent *event)
|
||||
void CompareDialog::printDiff()
|
||||
{
|
||||
te->clear();
|
||||
curvefile1=generateProcessUniqueTempFileName("curve1.png");
|
||||
curvefile2=generateProcessUniqueTempFileName("curve2.png");
|
||||
printSetup();
|
||||
if (GetCurrentFirmware()->getCapability(FlightModes)) {
|
||||
printPhases();
|
||||
@@ -160,8 +163,8 @@ void CompareDialog::closeEvent(QCloseEvent *event)
|
||||
|
||||
CompareDialog::~CompareDialog()
|
||||
{
|
||||
qunlink(curvefile5);
|
||||
qunlink(curvefile9);
|
||||
qunlink(curvefile1);
|
||||
qunlink(curvefile1);
|
||||
delete ui;
|
||||
}
|
||||
|
||||
@@ -250,10 +253,20 @@ void CompareDialog::printSetup()
|
||||
str.append(fv(tr("Timer1"), getTimerStr(g_model1->timers[0]), color)); //value, mode, count up/down
|
||||
color=getColor1(getTimerStr(g_model1->timers[1]), getTimerStr(g_model2->timers[1]));
|
||||
str.append(fv(tr("Timer2"), getTimerStr(g_model1->timers[1]), color)); //value, mode, count up/down
|
||||
color=getColor1(getProtocol(g_model1),getProtocol(g_model2));
|
||||
str.append(fv(tr("Protocol"), getProtocol(g_model1), color)); //proto, numch, delay,
|
||||
color=getColor1(g_model1->moduleData[0].ppmPulsePol, g_model2->moduleData[0].ppmPulsePol);
|
||||
str.append(fv(tr("Pulse Polarity"), g_model1->moduleData[0].polarityToString(), color));
|
||||
color=getColor1(getProtocol(g_model1->moduleData[0]),getProtocol(g_model2->moduleData[0]));
|
||||
if (firmware->getCapability(NumModules)>1) {
|
||||
str.append("<b>"+(IS_TARANIS(firmware->getBoard()) ? tr("Internal Radio System") : tr("Radio System") )+"</b><br> "); //proto, numch, delay,
|
||||
}
|
||||
str.append(fv(tr("Protocol"), getProtocol(g_model1->moduleData[0]),color));
|
||||
if (firmware->getCapability(NumModules)>1) {
|
||||
color=getColor1(getProtocol(g_model1->moduleData[1]),getProtocol(g_model2->moduleData[1]));
|
||||
str.append("<b>"+(IS_TARANIS(firmware->getBoard()) ? tr("External Radio Module") : tr("Extra Radio System"))+"</b><br> "); //proto, numch, delay,
|
||||
str.append(fv(tr("Protocol"), getProtocol(g_model1->moduleData[1]),color));
|
||||
}
|
||||
if (IS_TARANIS(firmware->getBoard())){
|
||||
color=getColor1(getTrainerMode(g_model1->trainerMode, g_model1->moduleData[2]),getTrainerMode(g_model2->trainerMode, g_model2->moduleData[2]));
|
||||
str.append(fv(tr("Trainer port mode"), getTrainerMode(g_model1->trainerMode, g_model1->moduleData[2]),color));
|
||||
}
|
||||
color=getColor1(g_model1->thrTrim,g_model2->thrTrim);
|
||||
str.append(fv(tr("Throttle Trim"), g_model1->thrTrim ? tr("Enabled") : tr("Disabled"), color));
|
||||
color=getColor1(getTrimInc(g_model1),getTrimInc(g_model2));
|
||||
@@ -270,10 +283,20 @@ void CompareDialog::printSetup()
|
||||
str.append(fv(tr("Timer1"), getTimerStr(g_model2->timers[0]),color)); //value, mode, count up/down
|
||||
color=getColor2(getTimerStr(g_model1->timers[1]), getTimerStr(g_model2->timers[1]));
|
||||
str.append(fv(tr("Timer2"), getTimerStr(g_model2->timers[1]),color)); //value, mode, count up/down
|
||||
color=getColor2(getProtocol(g_model1),getProtocol(g_model2));
|
||||
str.append(fv(tr("Protocol"), getProtocol(g_model2), color)); //proto, numch, delay,
|
||||
color=getColor2(g_model1->moduleData[0].ppmPulsePol, g_model2->moduleData[0].ppmPulsePol);
|
||||
str.append(fv(tr("Pulse Polarity"), g_model2->moduleData[0].polarityToString(), color));
|
||||
color=getColor2(getProtocol(g_model1->moduleData[0]),getProtocol(g_model2->moduleData[0]));
|
||||
if (firmware->getCapability(NumModules)>1) {
|
||||
str.append("<b>"+(IS_TARANIS(firmware->getBoard()) ? tr("Internal Radio System") : tr("Radio System") )+"</b><br> "); //proto, numch, delay,
|
||||
}
|
||||
str.append(fv(tr("Protocol"), getProtocol(g_model2->moduleData[0]),color));
|
||||
if (firmware->getCapability(NumModules)>1) {
|
||||
color=getColor2(getProtocol(g_model1->moduleData[1]),getProtocol(g_model2->moduleData[1]));
|
||||
str.append("<b>"+(IS_TARANIS(firmware->getBoard()) ? tr("External Radio Module") : tr("Extra Radio System"))+"</b><br> "); //proto, numch, delay,
|
||||
str.append(fv(tr("Protocol"), getProtocol(g_model2->moduleData[1]),color));
|
||||
}
|
||||
if (IS_TARANIS(firmware->getBoard())){
|
||||
color=getColor2(getTrainerMode(g_model1->trainerMode, g_model1->moduleData[2]),getTrainerMode(g_model2->trainerMode, g_model2->moduleData[2]));
|
||||
str.append(fv(tr("Trainer port mode"), getTrainerMode(g_model2->trainerMode, g_model2->moduleData[2]),color));
|
||||
}
|
||||
color=getColor2(g_model1->thrTrim,g_model2->thrTrim);
|
||||
str.append(fv(tr("Throttle Trim"), g_model2->thrTrim ? tr("Enabled") : tr("Disabled"), color));
|
||||
color=getColor2(getTrimInc(g_model1),getTrimInc(g_model2));
|
||||
@@ -928,82 +951,176 @@ void CompareDialog::printMixers()
|
||||
|
||||
void CompareDialog::printCurves()
|
||||
{
|
||||
#if 0
|
||||
int i,r,g,b,c;
|
||||
int i,r,g,b,c,count1,count2,usedcurves=0;
|
||||
QString cm1y,cm1x, cm2y,cm2x;
|
||||
char buffer [16];
|
||||
QString color;
|
||||
QColor * qplot_color[8];
|
||||
qplot_color[0]=new QColor(0,0,127);
|
||||
qplot_color[1]=new QColor(0,127,0);
|
||||
qplot_color[2]=new QColor(127,0,0);
|
||||
qplot_color[3]=new QColor(127,127,0);
|
||||
qplot_color[4]=new QColor(0,0,255);
|
||||
qplot_color[5]=new QColor(0,255,0);
|
||||
qplot_color[6]=new QColor(255,0,0);
|
||||
qplot_color[7]=new QColor(255,255,0);
|
||||
QPen pen(Qt::black, 2, Qt::SolidLine);
|
||||
int numcurves=firmware->getCapability(NumCurves);
|
||||
if (numcurves==0) {
|
||||
numcurves=16;
|
||||
}
|
||||
|
||||
QString str = "<table border=1 cellspacing=0 cellpadding=3 style=\"page-break-after:always;\" width=\"100%\"><tr><td><h2>";
|
||||
str.append(tr("Curves"));
|
||||
str.append("</h2></td></tr><tr><td>");
|
||||
str.append("<table border=1 cellspacing=0 cellpadding=3 width=\"100%\"><tr><td colspan=11><b>"+tr("5 Point Curves")+"</b></td></tr><tr>");
|
||||
for(i=0; i<5; i++)
|
||||
str.append(doTC(tr("pt %1").arg(i+1), "", true));
|
||||
str.append("<td></td>");
|
||||
for(i=0; i<5; i++)
|
||||
str.append(doTC(tr("pt %1").arg(i+1), "", true));
|
||||
str.append("</tr>");
|
||||
str.append("<table border=1 cellspacing=0 cellpadding=3 width=\"100%\">");
|
||||
QImage qi1(ISIZE+1,ISIZE+1,QImage::Format_RGB32);
|
||||
QPainter painter1(&qi1);
|
||||
QImage qi2(ISIZE+1,ISIZE+1,QImage::Format_RGB32);
|
||||
QPainter painter2(&qi2);
|
||||
painter1.setBrush(QBrush("#FFFFFF"));
|
||||
painter2.setBrush(QBrush("#FFFFFF"));
|
||||
painter1.setPen(QColor(0,0,0));
|
||||
painter2.setPen(QColor(0,0,0));
|
||||
painter1.drawRect(0,0,ISIZE,ISIZE);
|
||||
painter2.drawRect(0,0,ISIZE,ISIZE);
|
||||
|
||||
for(i=0; i<numcurves; i++) {
|
||||
count1=0;
|
||||
for(int j=0; j<g_model1->curves[i].count; j++) {
|
||||
if (g_model1->curves[i].points[j].y!=0)
|
||||
count1++;
|
||||
}
|
||||
count2=0;
|
||||
for(int j=0; j<g_model2->curves[i].count; j++) {
|
||||
if (g_model2->curves[i].points[j].y!=0)
|
||||
count2++;
|
||||
}
|
||||
if ((count1>0) || (g_model1->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)|| (g_model1->curves[i].count !=5) ||
|
||||
(count2>0) || (g_model2->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)|| (g_model2->curves[i].count !=5)) {
|
||||
pen.setColor(colors[usedcurves]);
|
||||
painter1.setPen(pen);
|
||||
painter2.setPen(pen);
|
||||
|
||||
for(i=0; i<MAX_CURVE5; i++) {
|
||||
qplot_color[i]->getRgb(&r,&g,&b);
|
||||
c=r;
|
||||
c*=256;
|
||||
c+=g;
|
||||
c*=256;
|
||||
c+=b;
|
||||
sprintf(buffer,"%06x",c);
|
||||
str.append("<tr>");
|
||||
for(int j=0; j<5; j++) {
|
||||
color=getColor1(g_model2->curves5[i][j],g_model2->curves5[i][j]);
|
||||
str.append(doTR(QString::number(g_model1->curves5[i][j]),color));
|
||||
}
|
||||
str.append(QString("<td width=\"10%\" align=\"center\"><font color=#%1><b>").arg(buffer)+tr("Curve")+QString(" %1</b></font></td>").arg(i+1));
|
||||
for(int j=0; j<5; j++) {
|
||||
color=getColor1(g_model2->curves5[i][j],g_model2->curves5[i][j]);
|
||||
str.append(doTR(QString::number(g_model2->curves5[i][j]),color));
|
||||
}
|
||||
str.append("</tr>");
|
||||
}
|
||||
str.append("</table></td></tr><tr><td>");
|
||||
colors[usedcurves].getRgb(&r,&g,&b);
|
||||
c=r;
|
||||
c*=256;
|
||||
c+=g;
|
||||
c*=256;
|
||||
c+=b;
|
||||
sprintf(buffer,"%06x",c);
|
||||
// curves are different in number of points or curve type so makes little sense to compare they are just different
|
||||
if ((g_model1->curves[i].count!=g_model2->curves[i].count) || (g_model1->curves[i].type!=g_model2->curves[i].type)) {
|
||||
cm1y="[";
|
||||
cm1x="[";
|
||||
for(int j=0; j<g_model1->curves[i].count; j++) {
|
||||
cm1y.append(QString("%1").arg(g_model1->curves[i].points[j].y));
|
||||
cm1x.append(QString("%1").arg(g_model1->curves[i].points[j].x));
|
||||
if (j<(g_model1->curves[i].count-1)) {
|
||||
cm1y.append(",");
|
||||
cm1x.append(",");
|
||||
}
|
||||
if (g_model1->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)
|
||||
painter1.drawLine(ISIZE/2+(ISIZE*g_model1->curves[i].points[j-1].x)/200,ISIZE/2-(ISIZE*g_model1->curves[i].points[j-1].y)/200,ISIZE/2+(ISIZE*g_model1->curves[i].points[j].x)/200,ISIZE/2-(ISIZE*g_model1->curves[i].points[j].y)/200);
|
||||
else
|
||||
painter1.drawLine(ISIZE*(j-1)/(g_model1->curves[i].count-1),ISIZE/2-(ISIZE*g_model1->curves[i].points[j-1].y)/200,ISIZE*(j)/(g_model1->curves[i].count-1),ISIZE/2-(ISIZE*g_model1->curves[i].points[j].y)/200);
|
||||
|
||||
}
|
||||
cm1y.append("]");
|
||||
cm1x.append("]");
|
||||
cm2y="[";
|
||||
cm2x="[";
|
||||
for(int j=0; j<g_model2->curves[i].count; j++) {
|
||||
cm2y.append(QString("%1").arg(g_model2->curves[i].points[j].y));
|
||||
cm2x.append(QString("%1").arg(g_model2->curves[i].points[j].x));
|
||||
if (j<(g_model2->curves[i].count-1)) {
|
||||
cm2y.append(",");
|
||||
cm2x.append(",");
|
||||
}
|
||||
if (g_model2->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)
|
||||
painter2.drawLine(ISIZE/2+(ISIZE*g_model2->curves[i].points[j-1].x)/200,ISIZE/2-(ISIZE*g_model2->curves[i].points[j-1].y)/200,ISIZE/2+(ISIZE*g_model2->curves[i].points[j].x)/200,ISIZE/2-(ISIZE*g_model2->curves[i].points[j].y)/200);
|
||||
else
|
||||
painter2.drawLine(ISIZE*(j-1)/(g_model2->curves[i].count-1),ISIZE/2-(ISIZE*g_model2->curves[i].points[j-1].y)/200,ISIZE*(j)/(g_model2->curves[i].count-1),ISIZE/2-(ISIZE*g_model2->curves[i].points[j].y)/200);
|
||||
|
||||
}
|
||||
cm2y.append("]");
|
||||
cm2x.append("]");
|
||||
str.append("<tr><td nowrap width=\"45%\"><font color=green>");
|
||||
str.append(cm1y);
|
||||
if ((g_model1->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)) {
|
||||
str.append(QString("<br>")+cm1x+QString("</font></td>"));
|
||||
}
|
||||
str.append(QString("<td width=\"10%\" align=\"center\"><font color=#%1><b>").arg(buffer)+tr("Curve")+QString(" %1</b></font></td>").arg(i+1));
|
||||
str.append("<td nowrap width=\"45%\"><font color=red>");
|
||||
str.append(cm2y);
|
||||
if ((g_model2->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)) {
|
||||
str.append(QString("<br>")+cm2x+QString("</font></td></tr>"));
|
||||
}
|
||||
} else {
|
||||
// curves have the same number of points and the same type, we can compare them point by point
|
||||
cm1y="[";
|
||||
cm1x="[";
|
||||
cm2y="[";
|
||||
cm2x="[";
|
||||
for(int j=0; j<g_model1->curves[i].count; j++) {
|
||||
if (g_model1->curves[i].points[j].y!=g_model2->curves[i].points[j].y) {
|
||||
cm1y.append(QString("<font color=green>%1</font>").arg(g_model1->curves[i].points[j].y));
|
||||
cm2y.append(QString("<font color=red>%1</font>").arg(g_model2->curves[i].points[j].y));
|
||||
} else {
|
||||
cm1y.append(QString("<font color=grey>%1</font>").arg(g_model1->curves[i].points[j].y));
|
||||
cm2y.append(QString("<font color=grey>%1</font>").arg(g_model2->curves[i].points[j].y));
|
||||
}
|
||||
if (g_model1->curves[i].points[j].x!=g_model2->curves[i].points[j].x) {
|
||||
cm1x.append(QString("<font color=green>%1</font>").arg(g_model1->curves[i].points[j].x));
|
||||
cm2x.append(QString("<font color=red>%1</font>").arg(g_model2->curves[i].points[j].x));
|
||||
} else {
|
||||
cm1x.append(QString("<font color=grey>%1</font>").arg(g_model1->curves[i].points[j].x));
|
||||
cm2x.append(QString("<font color=grey>%1</font>").arg(g_model2->curves[i].points[j].x));
|
||||
}
|
||||
if (j<(g_model1->curves[i].count-1)) {
|
||||
cm1y.append(",");
|
||||
cm1x.append(",");
|
||||
cm2y.append(",");
|
||||
cm2x.append(",");
|
||||
}
|
||||
if (g_model1->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)
|
||||
painter1.drawLine(ISIZE/2+(ISIZE*g_model1->curves[i].points[j-1].x)/200,ISIZE/2-(ISIZE*g_model1->curves[i].points[j-1].y)/200,ISIZE/2+(ISIZE*g_model1->curves[i].points[j].x)/200,ISIZE/2-(ISIZE*g_model1->curves[i].points[j].y)/200);
|
||||
else
|
||||
painter1.drawLine(ISIZE*(j-1)/(g_model1->curves[i].count-1),ISIZE/2-(ISIZE*g_model1->curves[i].points[j-1].y)/200,ISIZE*(j)/(g_model1->curves[i].count-1),ISIZE/2-(ISIZE*g_model1->curves[i].points[j].y)/200);
|
||||
if (g_model2->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)
|
||||
painter2.drawLine(ISIZE/2+(ISIZE*g_model2->curves[i].points[j-1].x)/200,ISIZE/2-(ISIZE*g_model2->curves[i].points[j-1].y)/200,ISIZE/2+(ISIZE*g_model2->curves[i].points[j].x)/200,ISIZE/2-(ISIZE*g_model2->curves[i].points[j].y)/200);
|
||||
else
|
||||
painter2.drawLine(ISIZE*(j-1)/(g_model2->curves[i].count-1),ISIZE/2-(ISIZE*g_model2->curves[i].points[j-1].y)/200,ISIZE*(j)/(g_model2->curves[i].count-1),ISIZE/2-(ISIZE*g_model2->curves[i].points[j].y)/200);
|
||||
}
|
||||
painter1.setPen(QColor(0,0,0));
|
||||
painter2.setPen(QColor(0,0,0));
|
||||
painter1.drawLine(0,ISIZE/2,ISIZE,ISIZE/2);
|
||||
painter2.drawLine(0,ISIZE/2,ISIZE,ISIZE/2);
|
||||
painter1.drawLine(ISIZE/2,0,ISIZE/2,ISIZE);
|
||||
painter2.drawLine(ISIZE/2,0,ISIZE/2,ISIZE);
|
||||
for(i=0; i<21; i++) {
|
||||
painter1.drawLine(ISIZE/2-5,(ISIZE*i)/(20),ISIZE/2+5,(ISIZE*i)/(20));
|
||||
painter2.drawLine(ISIZE/2-5,(ISIZE*i)/(20),ISIZE/2+5,(ISIZE*i)/(20));
|
||||
painter1.drawLine((ISIZE*i)/(20),ISIZE/2-5,(ISIZE*i)/(20),ISIZE/2+5);
|
||||
painter2.drawLine((ISIZE*i)/(20),ISIZE/2-5,(ISIZE*i)/(20),ISIZE/2+5);
|
||||
}
|
||||
|
||||
str.append("<table border=1 cellspacing=0 cellpadding=3 width=\"100%\"><tr><td colspan=19><b>"+tr("9 Point Curves")+"</b></td></tr><tr>");
|
||||
for(i=0; i<9; i++)
|
||||
str.append(doTC(tr("pt %1").arg(i+1), "", true));
|
||||
str.append("<td></td>");
|
||||
for(i=0; i<9; i++)
|
||||
str.append(doTC(tr("pt %1").arg(i+1), "", true));
|
||||
str.append("</tr>");
|
||||
for(i=0; i<MAX_CURVE9; i++) {
|
||||
qplot_color[i]->getRgb(&r,&g,&b);
|
||||
c=r;
|
||||
c*=256;
|
||||
c+=g;
|
||||
c*=256;
|
||||
c+=b;
|
||||
sprintf(buffer,"%06x",c);
|
||||
str.append("<tr>");
|
||||
for(int j=0; j<9; j++) {
|
||||
color=getColor1(g_model2->curves9[i][j],g_model2->curves9[i][j]);
|
||||
str.append(doTR(QString::number(g_model1->curves5[i][j]),color));
|
||||
cm1y.append("]");
|
||||
cm1x.append("]");
|
||||
cm2y.append("]");
|
||||
cm2x.append("]");
|
||||
str.append("<tr><td nowrap width=\"45%\">");
|
||||
str.append(cm1y);
|
||||
if ((g_model1->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)) {
|
||||
str.append(QString("<br>")+cm1x+QString("</td>"));
|
||||
}
|
||||
str.append(QString("<td width=\"10%\" align=\"center\"><font color=#%1><b>").arg(buffer)+tr("Curve")+QString(" %1</b></font></td>").arg(i+1));
|
||||
str.append("<td nowrap width=\"45%\">");
|
||||
str.append(cm2y);
|
||||
if ((g_model2->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)) {
|
||||
str.append(QString("<br>")+cm2x+QString("</td></tr>"));
|
||||
}
|
||||
}
|
||||
usedcurves++;
|
||||
}
|
||||
str.append(QString("<td width=\"10%\" align=\"center\"><font color=#%1><b>").arg(buffer)+tr("Curve")+QString(" %1</b></font></td>").arg(i+1+MAX_CURVE5));
|
||||
for(int j=0; j<9; j++) {
|
||||
color=getColor1(g_model2->curves9[i][j],g_model2->curves9[i][j]);
|
||||
str.append(doTR(QString::number(g_model2->curves9[i][j]),color));
|
||||
}
|
||||
str.append("</tr>");
|
||||
}
|
||||
str.append("</table></td></tr></table>");
|
||||
te->append(str);
|
||||
#endif
|
||||
if (usedcurves>0) {
|
||||
str.append(QString("<tr><td width=45 align=center><img src=\"%1\" border=0></td><td> </td><td width=45 align=center><img src=\"%2\" border=0></td>").arg(curvefile1).arg(curvefile2));
|
||||
str.append("</table></td></tr></table>");
|
||||
qi1.save(curvefile1, "png",100);
|
||||
qi2.save(curvefile2, "png",100);
|
||||
te->append(str);
|
||||
}
|
||||
}
|
||||
|
||||
void CompareDialog::printSwitches()
|
||||
@@ -1056,7 +1173,7 @@ void CompareDialog::printFSwitches()
|
||||
for(int i=0; i<GetCurrentFirmware()->getCapability(CustomFunctions); i++)
|
||||
{
|
||||
if (g_model1->funcSw[i].swtch.type || g_model2->funcSw[i].swtch.type) {
|
||||
if ((g_model1->funcSw[i].swtch != g_model2->funcSw[i].swtch) || (g_model1->funcSw[i].func!=g_model2->funcSw[i].func) || (g_model1->funcSw[i].adjustMode!=g_model2->funcSw[i].adjustMode) || (g_model1->funcSw[i].param!=g_model2->funcSw[i].param)) {
|
||||
if ((g_model1->funcSw[i].swtch != g_model2->funcSw[i].swtch) || (g_model1->funcSw[i].func!=g_model2->funcSw[i].func) || (g_model1->funcSw[i].adjustMode!=g_model2->funcSw[i].adjustMode) || (g_model1->funcSw[i].param!=g_model2->funcSw[i].param) || (g_model1->funcSw[i].enabled != g_model2->funcSw[i].enabled) || (g_model1->funcSw[i].repeatParam != g_model2->funcSw[i].repeatParam)) {
|
||||
color1="green";
|
||||
color2="red";
|
||||
} else {
|
||||
|
||||
@@ -15,8 +15,9 @@ class CompareDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CompareDialog(QWidget *parent);
|
||||
CompareDialog(QWidget *parent, FirmwareInterface * firmware);
|
||||
~CompareDialog();
|
||||
FirmwareInterface * firmware;
|
||||
|
||||
protected:
|
||||
GeneralSettings * settings;
|
||||
@@ -64,8 +65,8 @@ class CompareDialog : public QDialog
|
||||
bool ChannelHasMix(MixData * mixArray, uint8_t destCh);
|
||||
|
||||
QTextEdit * te;
|
||||
QString curvefile5;
|
||||
QString curvefile9;
|
||||
QString curvefile1;
|
||||
QString curvefile2;
|
||||
QDir *qd;
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -85,6 +85,7 @@ contributorsDialog::contributorsDialog(QWidget *parent, int contest, QString rnu
|
||||
QFile file(":/releasenotes.txt");
|
||||
if(file.open( QIODevice::ReadOnly | QIODevice::Text ) ) {
|
||||
ui->textEditor->setHtml(file.readAll());
|
||||
ui->textEditor->setOpenExternalLinks(true);
|
||||
}
|
||||
ui->textEditor->scroll(0,0);
|
||||
setWindowTitle(tr("Companion Release Notes"));
|
||||
@@ -124,6 +125,7 @@ contributorsDialog::~contributorsDialog()
|
||||
void contributorsDialog::replyFinished(QNetworkReply * reply)
|
||||
{
|
||||
ui->textEditor->setHtml(reply->readAll());
|
||||
ui->textEditor->setOpenExternalLinks(true);
|
||||
}
|
||||
|
||||
void contributorsDialog::forceClose()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTextEdit" name="textEditor">
|
||||
<widget class="QTextBrowser" name="textEditor">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
|
||||
@@ -229,7 +229,15 @@ RawSourceRange RawSource::getRange(const ModelData & model, const GeneralSetting
|
||||
case TELEMETRY_SOURCE_DIST_MAX:
|
||||
result.step = singleprec ? 8 : 1;
|
||||
result.max = singleprec ? 2040 : 10000;
|
||||
result.unit = QObject::tr("m");
|
||||
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 = QObject::tr("ft");
|
||||
}
|
||||
else {
|
||||
result.unit = QObject::tr("m");
|
||||
}
|
||||
break;
|
||||
case TELEMETRY_SOURCE_CELL:
|
||||
case TELEMETRY_SOURCE_CELL_MIN:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -361,9 +361,9 @@ class RawSource {
|
||||
}
|
||||
|
||||
QString toString(const ModelData & model);
|
||||
|
||||
|
||||
RawSourceRange getRange(const ModelData & model, const GeneralSettings & settings, unsigned int flags=0) const;
|
||||
|
||||
|
||||
bool operator == ( const RawSource & other) {
|
||||
return (this->type == other.type) && (this->index == other.index);
|
||||
}
|
||||
@@ -1053,9 +1053,9 @@ class ModelData {
|
||||
};
|
||||
|
||||
class RadioData {
|
||||
public:
|
||||
public:
|
||||
GeneralSettings generalSettings;
|
||||
ModelData models[C9X_MAX_MODELS];
|
||||
ModelData models[C9X_MAX_MODELS];
|
||||
};
|
||||
|
||||
// TODO rename FlightPhase to FlightMode
|
||||
@@ -1161,6 +1161,8 @@ enum Capability {
|
||||
MavlinkTelemetry,
|
||||
HasInputDiff,
|
||||
HasMixerExpo,
|
||||
MixersMonitor,
|
||||
HasBatMeterRange
|
||||
};
|
||||
|
||||
class SimulatorInterface;
|
||||
@@ -1180,15 +1182,15 @@ class EEPROMInterface
|
||||
virtual bool load(RadioData &radioData, const uint8_t *eeprom, int size) = 0;
|
||||
|
||||
virtual bool loadBackup(RadioData &radioData, uint8_t *eeprom, int esize, int index) = 0;
|
||||
|
||||
|
||||
virtual bool loadxml(RadioData &radioData, QDomDocument &doc) = 0;
|
||||
|
||||
virtual int save(uint8_t *eeprom, RadioData &radioData, uint32_t variant=0, uint8_t version=0) = 0;
|
||||
|
||||
virtual int getSize(ModelData &) = 0;
|
||||
|
||||
|
||||
virtual int getSize(GeneralSettings &) = 0;
|
||||
|
||||
|
||||
virtual int isAvailable(Protocol proto, int port=0) = 0;
|
||||
|
||||
virtual const int getEEpromSize() = 0;
|
||||
|
||||
@@ -68,6 +68,7 @@ namespace Open9xGruvin9x {
|
||||
#include "radio/src/switches.cpp"
|
||||
#include "radio/src/curves.cpp"
|
||||
#include "radio/src/mixer.cpp"
|
||||
#include "radio/src/timers.cpp"
|
||||
#include "radio/src/pulses/pulses_avr.cpp"
|
||||
#include "radio/src/stamp.cpp"
|
||||
#include "radio/src/maths.cpp"
|
||||
|
||||
@@ -69,6 +69,7 @@ namespace OpenTxM128 {
|
||||
#include "radio/src/switches.cpp"
|
||||
#include "radio/src/curves.cpp"
|
||||
#include "radio/src/mixer.cpp"
|
||||
#include "radio/src/timers.cpp"
|
||||
#include "radio/src/pulses/pulses_avr.cpp"
|
||||
#include "radio/src/stamp.cpp"
|
||||
#include "radio/src/maths.cpp"
|
||||
|
||||
@@ -72,6 +72,7 @@ namespace OpenTxM64 {
|
||||
#include "radio/src/switches.cpp"
|
||||
#include "radio/src/curves.cpp"
|
||||
#include "radio/src/mixer.cpp"
|
||||
#include "radio/src/timers.cpp"
|
||||
#include "radio/src/pulses/pulses_avr.cpp"
|
||||
#include "radio/src/stamp.cpp"
|
||||
#include "radio/src/maths.cpp"
|
||||
|
||||
@@ -80,6 +80,7 @@ namespace Open9xSky9x {
|
||||
#include "radio/src/strhelpers.cpp"
|
||||
#include "radio/src/switches.cpp"
|
||||
#include "radio/src/mixer.cpp"
|
||||
#include "radio/src/timers.cpp"
|
||||
#include "radio/src/curves.cpp"
|
||||
#include "radio/src/targets/sky9x/pulses_driver.cpp"
|
||||
#include "radio/src/pulses/pulses_arm.cpp"
|
||||
@@ -99,6 +100,7 @@ namespace Open9xSky9x {
|
||||
#include "radio/src/logs.cpp"
|
||||
#include "radio/src/targets/sky9x/keys_driver.cpp"
|
||||
#include "radio/src/keys.cpp"
|
||||
#include "radio/src/sdcard.cpp"
|
||||
#include "radio/src/targets/simu/simpgmspace.cpp"
|
||||
#include "radio/src/templates.cpp"
|
||||
#include "radio/src/translations.cpp"
|
||||
@@ -153,11 +155,9 @@ using namespace Open9xSky9x;
|
||||
Open9xSky9xSimulator::Open9xSky9xSimulator()
|
||||
{
|
||||
QString path=g.profile[g.id()].sdPath()+"/";
|
||||
int i=0;
|
||||
for (i=0; i< std::min(path.length(),1022); i++) {
|
||||
simuSdDirectory[i]=path.at(i).toAscii();
|
||||
}
|
||||
simuSdDirectory[i]=0;
|
||||
strncpy (simuSdDirectory, path.toAscii().constData(), sizeof(simuSdDirectory)-1);
|
||||
simuSdDirectory[sizeof(simuSdDirectory)-1] = '\0';
|
||||
|
||||
}
|
||||
|
||||
bool Open9xSky9xSimulator::timer10ms()
|
||||
@@ -166,7 +166,7 @@ bool Open9xSky9xSimulator::timer10ms()
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
uint8_t * Open9xSky9xSimulator::getLcd()
|
||||
::uint8_t * Open9xSky9xSimulator::getLcd()
|
||||
{
|
||||
#define GETLCD_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
@@ -183,6 +183,7 @@ void Open9xSky9xSimulator::start(QByteArray & eeprom, bool tests)
|
||||
g_rotenc[0] = 0;
|
||||
memcpy(Open9xSky9x::eeprom, eeprom.data(), std::min<int>(sizeof(Open9xSky9x::eeprom), eeprom.size()));
|
||||
StartEepromThread(NULL);
|
||||
StartAudioThread();
|
||||
StartMainThread(tests);
|
||||
}
|
||||
|
||||
@@ -190,12 +191,14 @@ void Open9xSky9xSimulator::start(const char * filename, bool tests)
|
||||
{
|
||||
g_rotenc[0] = 0;
|
||||
StartEepromThread(filename);
|
||||
StartAudioThread();
|
||||
StartMainThread(tests);
|
||||
}
|
||||
|
||||
void Open9xSky9xSimulator::stop()
|
||||
{
|
||||
StopMainThread();
|
||||
StopAudioThread();
|
||||
StopEepromThread();
|
||||
}
|
||||
|
||||
@@ -217,27 +220,27 @@ void Open9xSky9xSimulator::setValues(TxInputs &inputs)
|
||||
void Open9xSky9xSimulator::setTrim(unsigned int idx, int value)
|
||||
{
|
||||
idx = Open9xSky9x::modn12x3[4*getStickMode() + idx];
|
||||
uint8_t phase = getTrimFlightPhase(getFlightMode(), idx);
|
||||
::uint8_t phase = getTrimFlightPhase(getFlightMode(), idx);
|
||||
setTrimValue(phase, idx, value);
|
||||
}
|
||||
|
||||
void Open9xSky9xSimulator::getTrims(Trims & trims)
|
||||
{
|
||||
uint8_t phase = getFlightMode();
|
||||
::uint8_t phase = getFlightMode();
|
||||
trims.extended = hasExtendedTrims();
|
||||
for (uint8_t idx=0; idx<4; idx++) {
|
||||
for (::uint8_t idx=0; idx<4; idx++) {
|
||||
trims.values[idx] = getTrimValue(getTrimFlightPhase(phase, idx), idx);
|
||||
}
|
||||
|
||||
for (int i=0; i<2; i++) {
|
||||
uint8_t idx = Open9xSky9x::modn12x3[4*getStickMode() + i];
|
||||
int16_t tmp = trims.values[i];
|
||||
::uint8_t idx = Open9xSky9x::modn12x3[4*getStickMode() + i];
|
||||
::int16_t tmp = trims.values[i];
|
||||
trims.values[i] = trims.values[idx];
|
||||
trims.values[idx] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void Open9xSky9xSimulator::wheelEvent(uint8_t steps)
|
||||
void Open9xSky9xSimulator::wheelEvent(::uint8_t steps)
|
||||
{
|
||||
g_rotenc[0] += steps*4;
|
||||
}
|
||||
@@ -260,7 +263,7 @@ const char * Open9xSky9xSimulator::getError()
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
void Open9xSky9xSimulator::setTrainerInput(unsigned int inputNumber, int16_t value)
|
||||
void Open9xSky9xSimulator::setTrainerInput(unsigned int inputNumber, ::int16_t value)
|
||||
{
|
||||
#define SETTRAINER_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
|
||||
@@ -84,6 +84,7 @@ inline int geteepromsize() {
|
||||
#include "radio/src/switches.cpp"
|
||||
#include "radio/src/curves.cpp"
|
||||
#include "radio/src/mixer.cpp"
|
||||
#include "radio/src/timers.cpp"
|
||||
#include "radio/src/targets/taranis/pulses_driver.cpp"
|
||||
#include "radio/src/targets/taranis/rtc_driver.cpp"
|
||||
#include "radio/src/targets/taranis/trainer_driver.cpp"
|
||||
@@ -110,10 +111,10 @@ inline int geteepromsize() {
|
||||
#include "radio/src/bmp.cpp"
|
||||
#include "radio/src/haptic.cpp"
|
||||
#include "radio/src/targets/taranis/haptic_driver.cpp"
|
||||
// TODO Because FatFS in not C++ there cannot be namespaces there and the functions are defined several times!
|
||||
#undef SDCARD
|
||||
#include "radio/src/sdcard.cpp"
|
||||
// Because FatFS in not C++ there cannot be namespaces there and the functions are defined several times!
|
||||
#define SKIP_FATFS_DECLARATION
|
||||
#include "radio/src/targets/simu/simpgmspace.cpp"
|
||||
#define SDCARD
|
||||
#include "radio/src/translations.cpp"
|
||||
#include "radio/src/fonts.cpp"
|
||||
#include "radio/src/telemetry/frsky.cpp"
|
||||
@@ -196,11 +197,8 @@ OpentxTaranisSimulator::OpentxTaranisSimulator()
|
||||
{
|
||||
taranisSimulatorBoard = GetEepromInterface()->getBoard();
|
||||
QString path=g.profile[g.id()].sdPath()+"/";
|
||||
int i=0;
|
||||
for (i=0; i< std::min(path.length(),1022); i++) {
|
||||
simuSdDirectory[i]=path.at(i).toAscii();
|
||||
}
|
||||
simuSdDirectory[i]=0;
|
||||
strncpy (simuSdDirectory, path.toAscii().constData(), sizeof(simuSdDirectory)-1);
|
||||
simuSdDirectory[sizeof(simuSdDirectory)-1] = '\0';
|
||||
}
|
||||
|
||||
bool OpentxTaranisSimulator::timer10ms()
|
||||
@@ -209,7 +207,7 @@ bool OpentxTaranisSimulator::timer10ms()
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
uint8_t * OpentxTaranisSimulator::getLcd()
|
||||
::uint8_t * OpentxTaranisSimulator::getLcd()
|
||||
{
|
||||
#define GETLCD_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
@@ -225,18 +223,21 @@ void OpentxTaranisSimulator::start(QByteArray & eeprom, bool tests)
|
||||
{
|
||||
memcpy(Open9xX9D::eeprom, eeprom.data(), std::min<int>(sizeof(Open9xX9D::eeprom), eeprom.size()));
|
||||
StartEepromThread(NULL);
|
||||
StartAudioThread();
|
||||
StartMainThread(tests);
|
||||
}
|
||||
|
||||
void OpentxTaranisSimulator::start(const char * filename, bool tests)
|
||||
{
|
||||
StartEepromThread(filename);
|
||||
StartAudioThread();
|
||||
StartMainThread(tests);
|
||||
}
|
||||
|
||||
void OpentxTaranisSimulator::stop()
|
||||
{
|
||||
StopMainThread();
|
||||
StopAudioThread();
|
||||
StopEepromThread();
|
||||
}
|
||||
|
||||
@@ -256,27 +257,27 @@ void OpentxTaranisSimulator::setValues(TxInputs &inputs)
|
||||
void OpentxTaranisSimulator::setTrim(unsigned int idx, int value)
|
||||
{
|
||||
idx = Open9xX9D::modn12x3[4*getStickMode() + idx];
|
||||
uint8_t phase = getTrimFlightPhase(getFlightMode(), idx);
|
||||
::uint8_t phase = getTrimFlightPhase(getFlightMode(), idx);
|
||||
setTrimValue(phase, idx, value);
|
||||
}
|
||||
|
||||
void OpentxTaranisSimulator::getTrims(Trims & trims)
|
||||
{
|
||||
uint8_t phase = getFlightMode();
|
||||
::uint8_t phase = getFlightMode();
|
||||
trims.extended = hasExtendedTrims();
|
||||
for (uint8_t idx=0; idx<4; idx++) {
|
||||
for (::uint8_t idx=0; idx<4; idx++) {
|
||||
trims.values[idx] = getTrimValue(getTrimFlightPhase(phase, idx), idx);
|
||||
}
|
||||
|
||||
for (int i=0; i<2; i++) {
|
||||
uint8_t idx = Open9xX9D::modn12x3[4*getStickMode() + i];
|
||||
int16_t tmp = trims.values[i];
|
||||
::uint8_t idx = Open9xX9D::modn12x3[4*getStickMode() + i];
|
||||
::int16_t tmp = trims.values[i];
|
||||
trims.values[i] = trims.values[idx];
|
||||
trims.values[idx] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
void OpentxTaranisSimulator::wheelEvent(uint8_t steps)
|
||||
void OpentxTaranisSimulator::wheelEvent(::uint8_t steps)
|
||||
{
|
||||
// g_rotenc[0] += steps*4;
|
||||
}
|
||||
@@ -299,12 +300,12 @@ const char * OpentxTaranisSimulator::getError()
|
||||
#include "simulatorimport.h"
|
||||
}
|
||||
|
||||
void OpentxTaranisSimulator::sendTelemetry(uint8_t * data, unsigned int len)
|
||||
void OpentxTaranisSimulator::sendTelemetry(::uint8_t * data, unsigned int len)
|
||||
{
|
||||
frskySportProcessPacket(data);
|
||||
}
|
||||
|
||||
void OpentxTaranisSimulator::setTrainerInput(unsigned int inputNumber, int16_t value)
|
||||
void OpentxTaranisSimulator::setTrainerInput(unsigned int inputNumber, ::int16_t value)
|
||||
{
|
||||
#define SETTRAINER_IMPORT
|
||||
#include "simulatorimport.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Bertrand Songis <bsongis@gmail.com>
|
||||
*
|
||||
*
|
||||
* Based on th9x -> http://code.google.com/p/th9x/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -113,7 +113,7 @@ template <class T>
|
||||
bool OpenTxEepromInterface::loadModel(ModelData &model, uint8_t *data, int index, unsigned int stickMode)
|
||||
{
|
||||
T _model;
|
||||
|
||||
|
||||
if (!data) {
|
||||
// load from EEPROM
|
||||
efile->openRd(FILE_MODEL(index));
|
||||
@@ -309,7 +309,7 @@ bool OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *eeprom, in
|
||||
{
|
||||
std::cout << "trying " << getName() << " import...";
|
||||
|
||||
if (size != getEEpromSize()) {
|
||||
if (size != getEEpromSize()) {
|
||||
if (size==4096) {
|
||||
int notnull=false;
|
||||
for (int i=2048; i<4096; i++) {
|
||||
@@ -337,7 +337,7 @@ bool OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *eeprom, in
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
|
||||
|
||||
uint8_t version;
|
||||
if (efile->readRlc2(&version, 1) != 1) {
|
||||
std::cout << " no\n";
|
||||
@@ -355,7 +355,7 @@ bool OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *eeprom, in
|
||||
std::cout << " ko\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
std::cout << " variant " << radioData.generalSettings.variant;
|
||||
for (int i=0; i<getMaxModels(); i++) {
|
||||
if (!loadModel(version, radioData.models[i], NULL, i, radioData.generalSettings.variant, radioData.generalSettings.stickMode+1)) {
|
||||
@@ -399,7 +399,7 @@ int OpenTxEepromInterface::save(uint8_t *eeprom, RadioData &radioData, uint32_t
|
||||
if (board == BOARD_M128) {
|
||||
variant |= M128_VARIANT;
|
||||
}
|
||||
|
||||
|
||||
int result = saveGeneral<OpenTxGeneralData>(radioData.generalSettings, board, version, variant);
|
||||
if (!result) {
|
||||
return 0;
|
||||
@@ -546,7 +546,7 @@ int OpenTxFirmware::getCapability(const Capability capability)
|
||||
case FlightModesName:
|
||||
return (IS_TARANIS(board) ? 10 : 6);
|
||||
case GvarsName:
|
||||
return 6;
|
||||
return (IS_9X(board) ? 0 : 6);
|
||||
case HasChNames:
|
||||
return (IS_TARANIS(board) ? 1 : 0);
|
||||
case GvarsInCS:
|
||||
@@ -580,7 +580,7 @@ int OpenTxFirmware::getCapability(const Capability capability)
|
||||
else
|
||||
return 16;
|
||||
case SafetyChannelCustomFunction:
|
||||
return id.contains("noovveridech") ? 0 : 1;
|
||||
return id.contains("nooverridech") ? 0 : 1;
|
||||
case LogicalSwitches:
|
||||
if (IS_ARM(board))
|
||||
return 32;
|
||||
@@ -734,7 +734,11 @@ int OpenTxFirmware::getCapability(const Capability capability)
|
||||
return id.contains("mavlink") ? 1 : 0;
|
||||
case HasInputDiff:
|
||||
case HasMixerExpo:
|
||||
return (IS_ARM(board) ? true : false);
|
||||
return (IS_TARANIS(board) ? true : false);
|
||||
case MixersMonitor:
|
||||
return id.contains("mixersmon") ? 1 : 0;
|
||||
case HasBatMeterRange:
|
||||
return (IS_TARANIS(board) ? true : false);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -820,7 +824,7 @@ int OpenTxEepromInterface::isAvailable(Protocol proto, int port)
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (proto) {
|
||||
@@ -1241,7 +1245,7 @@ void registerOpenTxFirmwares()
|
||||
openTx->addOption("bluetooth", QObject::tr("Bluetooth interface"));
|
||||
addOpenTxCommonOptions(openTx);
|
||||
firmwares.push_back(openTx);
|
||||
|
||||
|
||||
/* 9XR-Pro */
|
||||
openTx = new OpenTxFirmware("opentx-9xrpro", QObject::tr("OpenTX for 9XR-PRO"), BOARD_9XRPRO);
|
||||
openTx->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
|
||||
@@ -1260,7 +1264,7 @@ void registerOpenTxFirmwares()
|
||||
openTx->addOption("bluetooth", QObject::tr("Bluetooth interface"));
|
||||
addOpenTxCommonOptions(openTx);
|
||||
firmwares.push_back(openTx);
|
||||
|
||||
|
||||
/* Taranis board */
|
||||
openTx = new OpenTxFirmware("opentx-taranis", QObject::tr("OpenTX for FrSky Taranis"), BOARD_TARANIS);
|
||||
openTx->addOption("noheli", QObject::tr("Disable HELI menu and cyclic mix support"));
|
||||
@@ -1268,15 +1272,17 @@ void registerOpenTxFirmwares()
|
||||
openTx->addOption("haptic", QObject::tr("Haptic module installed"));
|
||||
openTx->addOption("lua", QObject::tr("Support for Lua model scripts"));
|
||||
openTx->addOption("nojoystick", QObject::tr("No Joystick emulation inside the FW (only Mass Storage as in the Bootloader)"));
|
||||
openTx->addOption("mixersmon", QObject::tr("Adds mixers output view to the CHANNELS MONITOR screen, pressing [ENT] switches between the views"));
|
||||
addOpenTxCommonOptions(openTx);
|
||||
firmwares.push_back(openTx);
|
||||
|
||||
|
||||
/* Taranis Plus board */
|
||||
openTx = new OpenTxFirmware("opentx-taranisplus", QObject::tr("OpenTX for FrSky Taranis Plus"), BOARD_TARANIS_PLUS);
|
||||
openTx->addOption("noheli", QObject::tr("Disable HELI menu and cyclic mix support"));
|
||||
openTx->addOption("nogvars", QObject::tr("Disable Global variables"));
|
||||
openTx->addOption("lua", QObject::tr("Support for Lua model scripts"));
|
||||
openTx->addOption("nojoystick", QObject::tr("No Joystick emulation inside the FW (only Mass Storage as in the Bootloader)"));
|
||||
openTx->addOption("mixersmon", QObject::tr("Adds mixers output view to the CHANNELS MONITOR screen, pressing [ENT] switches between the views"));
|
||||
addOpenTxCommonOptions(openTx);
|
||||
firmwares.push_back(openTx);
|
||||
|
||||
|
||||
+506
-474
File diff suppressed because it is too large
Load Diff
@@ -32,7 +32,7 @@ class GeneralEdit : public QDialog
|
||||
|
||||
protected:
|
||||
virtual bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
|
||||
signals:
|
||||
void modelValuesChanged();
|
||||
|
||||
@@ -108,11 +108,11 @@ class GeneralEdit : public QDialog
|
||||
void on_bgVolume_SL_valueChanged();
|
||||
void on_varioVolume_SL_valueChanged();
|
||||
void on_wavVolume_SL_valueChanged();
|
||||
|
||||
|
||||
void on_varioP0_SB_editingFinished();
|
||||
void on_varioPMax_SB_editingFinished();
|
||||
void on_varioR0_SB_editingFinished();
|
||||
|
||||
|
||||
void on_pot1Type_currentIndexChanged(int index);
|
||||
void on_pot2Type_currentIndexChanged(int index);
|
||||
void on_pot3Type_currentIndexChanged(int index);
|
||||
@@ -128,6 +128,8 @@ class GeneralEdit : public QDialog
|
||||
void on_mavbaud_CB_currentIndexChanged(int index);
|
||||
void on_voiceLang_CB_currentIndexChanged(int index);
|
||||
void on_battCalibDSB_editingFinished();
|
||||
void on_vBatMinDSB_editingFinished();
|
||||
void on_vBatMaxDSB_editingFinished();
|
||||
void on_battwarningDSB_editingFinished();
|
||||
void on_contrastSB_editingFinished();
|
||||
void on_calretrieve_PB_clicked();
|
||||
|
||||
+1470
-1397
File diff suppressed because it is too large
Load Diff
@@ -838,16 +838,40 @@ QString getTimerStr(TimerData & timer)
|
||||
return result;
|
||||
}
|
||||
|
||||
QString getProtocol(ModelData * g_model)
|
||||
QString getProtocol(ModuleData & module)
|
||||
{
|
||||
QString str = getProtocolStr(g_model->moduleData[0].protocol);
|
||||
|
||||
if (g_model->moduleData[0].protocol == PPM)
|
||||
str.append(QObject::tr(": %1 Channels, %2usec Delay").arg(g_model->moduleData[0].channelsCount).arg(g_model->moduleData[0].ppmDelay));
|
||||
QString str = getProtocolStr(module.protocol);
|
||||
|
||||
if (module.protocol == PPM)
|
||||
str.append(QObject::tr(": Channel start: %1, %2 Channels, %3usec Delay, Pulse polarity %4").arg(module.channelsStart+1).arg(module.channelsCount).arg(module.ppmDelay).arg(module.polarityToString()));
|
||||
else if (!module.protocol == OFF)
|
||||
str.append(QObject::tr(": Channel start: %1, %2 Channels").arg(module.channelsStart+1).arg(module.channelsCount));
|
||||
return str;
|
||||
}
|
||||
|
||||
QString getTrainerMode(const int trainermode, ModuleData & module)
|
||||
{
|
||||
QString result;
|
||||
switch (trainermode) {
|
||||
case 1:
|
||||
result=QObject::tr("Slave/Jack")+QObject::tr(": Channel start: %1, %2 Channels, %3usec Delay, Pulse polarity %4").arg(module.channelsStart+1).arg(module.channelsCount).arg(module.ppmDelay).arg(module.polarityToString());
|
||||
break;
|
||||
case 2:
|
||||
result=QObject::tr("Master/SBUS Module");
|
||||
break;
|
||||
case 3:
|
||||
result=QObject::tr("Master/CPPM Module");
|
||||
break;
|
||||
case 4:
|
||||
result=QObject::tr("Master/SBUS in battery compartment");
|
||||
break;
|
||||
default:
|
||||
result=QObject::tr("Master/Jack");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
QString getPhasesStr(unsigned int phases, ModelData & model)
|
||||
{
|
||||
int numphases = GetCurrentFirmware()->getCapability(FlightModes);
|
||||
@@ -1038,6 +1062,11 @@ QString generateProcessUniqueTempFileName(const QString & fileName)
|
||||
return QDir::tempPath() + QString("/%1-").arg(QCoreApplication::applicationPid()) + sanitizedFileName;
|
||||
}
|
||||
|
||||
bool isTempFileName(const QString & fileName)
|
||||
{
|
||||
return fileName.startsWith(QDir::tempPath());
|
||||
}
|
||||
|
||||
QString getSoundsPath(const GeneralSettings &generalSettings)
|
||||
{
|
||||
QString path = g.profile[g.id()].sdPath() + "/SOUNDS/";
|
||||
@@ -1063,3 +1092,8 @@ QSet<QString> getFilesSet(const QString &path, const QStringList &filter, int ma
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool caseInsensitiveLessThan(const QString &s1, const QString &s2)
|
||||
{
|
||||
return s1.toLower() < s2.toLower();
|
||||
}
|
||||
|
||||
@@ -125,7 +125,8 @@ int findmult(float value, float base);
|
||||
|
||||
QString getTrimInc(ModelData * g_model);
|
||||
QString getTimerStr(TimerData & timer);
|
||||
QString getProtocol(ModelData * g_model);
|
||||
QString getProtocol(ModuleData & module);
|
||||
QString getTrainerMode(const int trainermode, ModuleData & module);
|
||||
QString getCenterBeepStr(ModelData * g_model);
|
||||
|
||||
/* FrSky helpers */
|
||||
@@ -154,8 +155,11 @@ class QTimeS : public QTime
|
||||
int qunlink(const QString & fileName);
|
||||
|
||||
QString generateProcessUniqueTempFileName(const QString & fileName);
|
||||
bool isTempFileName(const QString & fileName);
|
||||
|
||||
QString getSoundsPath(const GeneralSettings &generalSettings);
|
||||
QSet<QString> getFilesSet(const QString &path, const QStringList &filter, int maxLen);
|
||||
|
||||
bool caseInsensitiveLessThan(const QString &s1, const QString &s2);
|
||||
|
||||
#endif // HELPERS_H
|
||||
|
||||
+356
-377
@@ -1,7 +1,6 @@
|
||||
#include "logsdialog.h"
|
||||
#include "appdata.h"
|
||||
#include "ui_logsdialog.h"
|
||||
#include "qcustomplot.h"
|
||||
#include "helpers.h"
|
||||
#if defined WIN32 || !defined __GNUC__
|
||||
#include <windows.h>
|
||||
@@ -14,53 +13,71 @@ logsDialog::logsDialog(QWidget *parent) :
|
||||
ui(new Ui::logsDialog)
|
||||
{
|
||||
csvlog.clear();
|
||||
srand(QDateTime::currentDateTime().toTime_t());
|
||||
|
||||
ui->setupUi(this);
|
||||
this->setWindowIcon(CompanionIcon("logs.png"));
|
||||
palette.clear();
|
||||
|
||||
plotLock=false;
|
||||
for (int i=0; i< 60; i++)
|
||||
palette << QColor(rand()%245+10, rand()%245+10, rand()%245+10);
|
||||
ui->customPlot->setInteractions(QCustomPlot::iRangeDrag | QCustomPlot::iRangeZoom | QCustomPlot::iSelectAxes |
|
||||
QCustomPlot::iSelectLegend | QCustomPlot::iSelectPlottables | QCustomPlot::iSelectTitle | QCustomPlot::iSelectItems);
|
||||
ui->customPlot->setRangeDrag(Qt::Horizontal|Qt::Vertical);
|
||||
ui->customPlot->setRangeZoom(Qt::Horizontal|Qt::Vertical);
|
||||
ui->customPlot->yAxis->setRange(-1100, 1100);
|
||||
ui->customPlot->setupFullAxesBox();
|
||||
ui->customPlot->setTitle(tr("Telemetry logs"));
|
||||
ui->customPlot->xAxis->setLabel(tr("Time"));
|
||||
ui->customPlot->legend->setVisible(true);
|
||||
|
||||
colors.append(Qt::green);
|
||||
colors.append(Qt::red);
|
||||
colors.append(Qt::yellow);
|
||||
colors.append(Qt::magenta);
|
||||
colors.append(Qt::cyan);
|
||||
colors.append(Qt::darkBlue);
|
||||
colors.append(Qt::darkGreen);
|
||||
colors.append(Qt::darkRed);
|
||||
colors.append(Qt::darkYellow);
|
||||
colors.append(Qt::darkMagenta);
|
||||
colors.append(Qt::darkCyan);
|
||||
colors.append(Qt::blue);
|
||||
pen.setWidthF(1.0);
|
||||
|
||||
// create and prepare a plot title layout element
|
||||
QCPPlotTitle *title = new QCPPlotTitle(ui->customPlot);
|
||||
title->setText(tr("Telemetry logs"));
|
||||
// title->setFont(QFont("sans", 12, QFont::Bold));
|
||||
// add it to the main plot layout
|
||||
ui->customPlot->plotLayout()->insertRow(0);
|
||||
ui->customPlot->plotLayout()->addElement(0, 0, title);
|
||||
|
||||
ui->customPlot->setNoAntialiasingOnDrag(true);
|
||||
|
||||
ui->customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom |
|
||||
QCP::iSelectAxes | QCP::iSelectLegend | QCP::iSelectPlottables);
|
||||
|
||||
ui->customPlot->xAxis->setLabel(tr("Time (hh:mm:ss)"));
|
||||
ui->customPlot->xAxis->setTickLabelType(QCPAxis::ltDateTime);
|
||||
ui->customPlot->xAxis->setDateTimeFormat("hh:mm:ss");
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
ui->customPlot->xAxis->setRange(now.addSecs(-60*60*2).toTime_t(),
|
||||
now.toTime_t());
|
||||
|
||||
ui->customPlot->yAxis->setTickLabels(false);
|
||||
ui->customPlot->yAxis->setAutoTickCount(10);
|
||||
ui->customPlot->xAxis2->setTicks(false);
|
||||
ui->customPlot->yAxis2->setTicks(false);
|
||||
ui->customPlot->setRangeZoomFactor(2, 2);
|
||||
|
||||
QFont legendFont = font();
|
||||
legendFont.setPointSize(10);
|
||||
ui->customPlot->legend->setFont(legendFont);
|
||||
ui->customPlot->legend->setSelectedFont(legendFont);
|
||||
ui->customPlot->legend->setSelectable(QCPLegend::spItems); // legend box shall not be selectable, only legend items
|
||||
ui->customPlot->legend->setVisible(false);
|
||||
|
||||
QString Path=g.gePath();
|
||||
if (Path.isEmpty() || !QFile(Path).exists()) {
|
||||
ui->mapsButton->hide();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// connect slot that ties some axis selections together (especially opposite axes):
|
||||
connect(ui->customPlot, SIGNAL(selectionChangedByUser()), this, SLOT(selectionChanged()));
|
||||
// connect slots that takes care that when an axis is selected, only that direction can be dragged and zoomed:
|
||||
connect(ui->customPlot, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(mousePress()));
|
||||
connect(ui->customPlot, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheel()));
|
||||
|
||||
// make bottom and left axes transfer their ranges to top and right axes:
|
||||
connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->xAxis2, SLOT(setRange(QCPRange)));
|
||||
connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), ui->customPlot->yAxis2, SLOT(setRange(QCPRange)));
|
||||
|
||||
|
||||
// make left axes transfer its range to right axes:
|
||||
connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(setRangeyAxis2(QCPRange)));
|
||||
|
||||
// connect some interaction slots:
|
||||
connect(ui->customPlot, SIGNAL(titleDoubleClick(QMouseEvent*)), this, SLOT(titleDoubleClick()));
|
||||
connect(ui->customPlot, SIGNAL(titleDoubleClick(QMouseEvent*, QCPPlotTitle*)), this, SLOT(titleDoubleClick(QMouseEvent*, QCPPlotTitle*)));
|
||||
connect(ui->customPlot, SIGNAL(axisDoubleClick(QCPAxis*,QCPAxis::SelectablePart,QMouseEvent*)), this, SLOT(axisLabelDoubleClick(QCPAxis*,QCPAxis::SelectablePart)));
|
||||
connect(ui->customPlot, SIGNAL(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*,QMouseEvent*)), this, SLOT(legendDoubleClick(QCPLegend*,QCPAbstractLegendItem*)));
|
||||
connect(ui->customPlot, SIGNAL(plottableDoubleClick(QCPAbstractPlottable *, QMouseEvent *)), this, SLOT(plottableItemDoubleClick(QCPAbstractPlottable *, QMouseEvent *)));
|
||||
connect(ui->FieldsTW, SIGNAL(itemSelectionChanged()), this, SLOT(plotLogs()));
|
||||
connect(ui->logTable, SIGNAL(itemSelectionChanged()), this, SLOT(plotLogs()));
|
||||
connect(ui->Reset_PB, SIGNAL(clicked()), this, SLOT(plotLogs()));
|
||||
@@ -71,27 +88,16 @@ logsDialog::~logsDialog()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
double logsDialog::GetScale(QString channel) {
|
||||
QString Analog="Rud,Ele,Thr,Ail,P1,P2,P3";
|
||||
QString Switches="THR,RUD,ELE,ID0,ID1,ID2,AIL,GEA,TRN";
|
||||
if (Analog.contains(channel)) {
|
||||
return 1.0;
|
||||
}
|
||||
if (Switches.contains(channel)) {
|
||||
return 0.001;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void logsDialog::titleDoubleClick()
|
||||
void logsDialog::titleDoubleClick(QMouseEvent *evt, QCPPlotTitle *title)
|
||||
{
|
||||
// Set the plot title by double clicking on it
|
||||
|
||||
|
||||
bool ok;
|
||||
QString newTitle = QInputDialog::getText(this, "QCustomPlot example", "New plot title:", QLineEdit::Normal, ui->customPlot->title(), &ok);
|
||||
QString newTitle = QInputDialog::getText(this, tr("Plot Title Change"),
|
||||
tr("New plot title:"), QLineEdit::Normal, title->text(), &ok);
|
||||
if (ok)
|
||||
{
|
||||
ui->customPlot->setTitle(newTitle);
|
||||
title->setText(newTitle);
|
||||
ui->customPlot->replot();
|
||||
}
|
||||
}
|
||||
@@ -99,11 +105,10 @@ void logsDialog::titleDoubleClick()
|
||||
void logsDialog::axisLabelDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart part)
|
||||
{
|
||||
// Set an axis label by double clicking on it
|
||||
|
||||
if (part == QCPAxis::spAxisLabel) // only react when the actual axis label is clicked, not tick label or axis backbone
|
||||
{
|
||||
bool ok;
|
||||
QString newLabel = QInputDialog::getText(this, "QCustomPlot example", "New axis label:", QLineEdit::Normal, axis->label(), &ok);
|
||||
QString newLabel = QInputDialog::getText(this, tr("Axis Label Change"), tr("New axis label:"), QLineEdit::Normal, axis->label(), &ok);
|
||||
if (ok)
|
||||
{
|
||||
axis->setLabel(newLabel);
|
||||
@@ -115,13 +120,11 @@ void logsDialog::axisLabelDoubleClick(QCPAxis *axis, QCPAxis::SelectablePart par
|
||||
void logsDialog::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *item)
|
||||
{
|
||||
// Rename a graph by double clicking on its legend item
|
||||
|
||||
Q_UNUSED(legend)
|
||||
if (item) // only react if item was clicked (user could have clicked on border padding of legend where there is no item, then item is 0)
|
||||
{
|
||||
QCPPlottableLegendItem *plItem = qobject_cast<QCPPlottableLegendItem*>(item);
|
||||
bool ok;
|
||||
QString newName = QInputDialog::getText(this, "QCustomPlot example", "New graph name:", QLineEdit::Normal, plItem->plottable()->name(), &ok);
|
||||
QString newName = QInputDialog::getText(this, tr("Graph Name Change"), tr("New graph name:"), QLineEdit::Normal, plItem->plottable()->name(), &ok);
|
||||
if (ok)
|
||||
{
|
||||
plItem->plottable()->setName(newName);
|
||||
@@ -129,10 +132,6 @@ void logsDialog::legendDoubleClick(QCPLegend *legend, QCPAbstractLegendItem *ite
|
||||
}
|
||||
}
|
||||
}
|
||||
void logsDialog::plottableItemDoubleClick(QCPAbstractPlottable * plottable, QMouseEvent * event)
|
||||
{
|
||||
// qDebug() << plottable->
|
||||
}
|
||||
|
||||
void logsDialog::selectionChanged()
|
||||
{
|
||||
@@ -140,31 +139,39 @@ void logsDialog::selectionChanged()
|
||||
normally, axis base line, axis tick labels and axis labels are selectable separately, but we want
|
||||
the user only to be able to select the axis as a whole, so we tie the selected states of the tick labels
|
||||
and the axis base line together. However, the axis label shall be selectable individually.
|
||||
|
||||
|
||||
The selection state of the left and right axes shall be synchronized as well as the state of the
|
||||
bottom and top axes.
|
||||
|
||||
|
||||
Further, we want to synchronize the selection of the graphs with the selection state of the respective
|
||||
legend item belonging to that graph. So the user can select a graph by either clicking on the graph itself
|
||||
or on its legend item.
|
||||
*/
|
||||
if (plotLock)
|
||||
return;
|
||||
// make top and bottom axes be selected synchronously, and handle axis and tick labels as one selectable object:
|
||||
if (ui->customPlot->xAxis->selected().testFlag(QCPAxis::spAxis) || ui->customPlot->xAxis->selected().testFlag(QCPAxis::spTickLabels) ||
|
||||
ui->customPlot->xAxis2->selected().testFlag(QCPAxis::spAxis) || ui->customPlot->xAxis2->selected().testFlag(QCPAxis::spTickLabels))
|
||||
|
||||
if (plotLock) return;
|
||||
|
||||
// handle bottom axis and tick labels as one selectable object:
|
||||
if (ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spTickLabels))
|
||||
{
|
||||
ui->customPlot->xAxis2->setSelected(QCPAxis::spAxis|QCPAxis::spTickLabels);
|
||||
ui->customPlot->xAxis->setSelected(QCPAxis::spAxis|QCPAxis::spTickLabels);
|
||||
ui->customPlot->xAxis->setSelectedParts(QCPAxis::spAxis |
|
||||
QCPAxis::spTickLabels);
|
||||
}
|
||||
// make left and right axes be selected synchronously, and handle axis and tick labels as one selectable object:
|
||||
if (ui->customPlot->yAxis->selected().testFlag(QCPAxis::spAxis) || ui->customPlot->yAxis->selected().testFlag(QCPAxis::spTickLabels) ||
|
||||
ui->customPlot->yAxis2->selected().testFlag(QCPAxis::spAxis) || ui->customPlot->yAxis2->selected().testFlag(QCPAxis::spTickLabels))
|
||||
// make left and right axes be selected synchronously,
|
||||
// and handle axis and tick labels as one selectable object:
|
||||
if (ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spTickLabels) ||
|
||||
ui->customPlot->yAxis2->selectedParts().testFlag(QCPAxis::spAxis) ||
|
||||
ui->customPlot->yAxis2->selectedParts().testFlag(QCPAxis::spTickLabels))
|
||||
{
|
||||
ui->customPlot->yAxis2->setSelected(QCPAxis::spAxis|QCPAxis::spTickLabels);
|
||||
ui->customPlot->yAxis->setSelected(QCPAxis::spAxis|QCPAxis::spTickLabels);
|
||||
ui->customPlot->yAxis->setSelectedParts(QCPAxis::spAxis |
|
||||
QCPAxis::spTickLabels);
|
||||
if (hasyAxis2) {
|
||||
ui->customPlot->yAxis2->setSelectedParts(QCPAxis::spAxis |
|
||||
QCPAxis::spTickLabels);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// synchronize selection of graphs with selection of corresponding legend items:
|
||||
for (int i=0; i<ui->customPlot->graphCount(); ++i)
|
||||
{
|
||||
@@ -178,7 +185,8 @@ void logsDialog::selectionChanged()
|
||||
}
|
||||
}
|
||||
|
||||
void logsDialog::on_mapsButton_clicked() {
|
||||
void logsDialog::on_mapsButton_clicked()
|
||||
{
|
||||
int n = csvlog.count(); // number of points in graph
|
||||
if (n==0) return;
|
||||
int latcol=0, longcol=0, altcol=0, speedcol=0;
|
||||
@@ -186,13 +194,13 @@ void logsDialog::on_mapsButton_clicked() {
|
||||
bool rangeSelected=false;
|
||||
ui->FieldsTW->setDisabled(true);
|
||||
ui->logTable->setDisabled(true);
|
||||
|
||||
|
||||
QString gePath=g.gePath();
|
||||
if (gePath.isEmpty() || !QFile(gePath).exists()) {
|
||||
ui->FieldsTW->setDisabled(false);
|
||||
ui->logTable->setDisabled(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
QSet<int> nondataCols;
|
||||
for (int i=1; i<csvlog.at(0).count(); i++) {
|
||||
//Long,Lat,Course,GPS Speed,GPS Alt
|
||||
@@ -225,7 +233,7 @@ void logsDialog::on_mapsButton_clicked() {
|
||||
if (itemSelected==0) {
|
||||
itemSelected=n-1;
|
||||
}
|
||||
|
||||
|
||||
QString geIconFilename = generateProcessUniqueTempFileName("track0.png");
|
||||
if (QFile::exists(geIconFilename)) {
|
||||
QFile::remove(geIconFilename);
|
||||
@@ -247,7 +255,7 @@ void logsDialog::on_mapsButton_clicked() {
|
||||
return;
|
||||
}
|
||||
QString latitude,longitude;
|
||||
double flatitude, flongitude,temp;
|
||||
double flatitude, flongitude,temp;
|
||||
QTextStream outputStream(&geFile);
|
||||
outputStream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">\n";
|
||||
outputStream << "\t<Document>\n\t\t<name>" << logFilename << "</name>\n";
|
||||
@@ -269,7 +277,7 @@ void logsDialog::on_mapsButton_clicked() {
|
||||
}
|
||||
}
|
||||
outputStream << "\t\t</Schema>\n";
|
||||
|
||||
|
||||
QString planeName;
|
||||
if (logFilename.indexOf("-")>0) {
|
||||
planeName=logFilename.left(logFilename.indexOf("-"));
|
||||
@@ -286,7 +294,7 @@ void logsDialog::on_mapsButton_clicked() {
|
||||
outputStream << "\t\t\t\t\t<when>"<< tstamp <<"</when>\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i=1; i<n; i++) {
|
||||
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
|
||||
latitude=csvlog.at(i).at(latcol).trimmed();
|
||||
@@ -348,13 +356,13 @@ void logsDialog::mousePress()
|
||||
{
|
||||
// if an axis is selected, only allow the direction of that axis to be dragged
|
||||
// if no axis is selected, both directions may be dragged
|
||||
|
||||
if (ui->customPlot->xAxis->selected().testFlag(QCPAxis::spAxis))
|
||||
ui->customPlot->setRangeDrag(ui->customPlot->xAxis->orientation());
|
||||
else if (ui->customPlot->yAxis->selected().testFlag(QCPAxis::spAxis))
|
||||
ui->customPlot->setRangeDrag(ui->customPlot->yAxis->orientation());
|
||||
|
||||
if (ui->customPlot->xAxis->selectedParts().testFlag(QCPAxis::spAxis))
|
||||
ui->customPlot->axisRect()->setRangeDrag(ui->customPlot->xAxis->orientation());
|
||||
else if (ui->customPlot->yAxis->selectedParts().testFlag(QCPAxis::spAxis))
|
||||
ui->customPlot->axisRect()->setRangeDrag(ui->customPlot->yAxis->orientation());
|
||||
else
|
||||
ui->customPlot->setRangeDrag(Qt::Horizontal|Qt::Vertical);
|
||||
ui->customPlot->axisRect()->setRangeDrag(Qt::Horizontal | Qt::Vertical);
|
||||
}
|
||||
|
||||
void logsDialog::mouseWheel()
|
||||
@@ -369,174 +377,9 @@ void logsDialog::mouseWheel()
|
||||
orientation|=Qt::Vertical;
|
||||
}
|
||||
if (orientation) {
|
||||
ui->customPlot->setRangeZoom((Qt::Orientation)orientation);
|
||||
}
|
||||
}
|
||||
|
||||
void logsDialog::plotValue(int index, int plot, int numplots)
|
||||
{
|
||||
if (plotLock)
|
||||
return;
|
||||
int n = csvlog.count(); // number of points in graph
|
||||
bool rangeSelected=false;
|
||||
uint minx;
|
||||
uint maxx;
|
||||
uint itemSelected=0;
|
||||
uint itemCount=0;
|
||||
double miny=9999;
|
||||
double maxy=-9999;
|
||||
minx=-1;
|
||||
maxx=0;
|
||||
double tmpval,yscale;
|
||||
for (int i=1; i<n; i++) {
|
||||
if (ui->logTable->item(i-1,1)->isSelected()) {
|
||||
rangeSelected=true;
|
||||
itemSelected++;
|
||||
}
|
||||
}
|
||||
if (itemSelected==0) {
|
||||
itemSelected=n-1;
|
||||
}
|
||||
QVector<double> x(itemSelected), y(itemSelected);
|
||||
if (numplots<3) {
|
||||
for (int i=1; i<n; i++) {
|
||||
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
|
||||
double tmp;
|
||||
QString tstamp=csvlog.at(i).at(0)+QString(" ")+csvlog.at(i).at(1);
|
||||
if (csvlog.at(i).at(1).contains(".")) {
|
||||
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss.zzz").toTime_t();
|
||||
tmp+=csvlog.at(i).at(1).mid(csvlog.at(i).at(1).indexOf(".")).toDouble();
|
||||
} else {
|
||||
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss").toTime_t();
|
||||
}
|
||||
if (minx>tmp) {
|
||||
minx=tmp;
|
||||
}
|
||||
if (maxx<tmp) {
|
||||
maxx=tmp;
|
||||
}
|
||||
tmpval = csvlog.at(i).at(index).toDouble();
|
||||
if (tmpval>maxy) {
|
||||
maxy=tmpval;
|
||||
}
|
||||
if (tmpval<miny) {
|
||||
miny=tmpval;
|
||||
}
|
||||
}
|
||||
}
|
||||
yscale=1;
|
||||
ui->customPlot->axisRect()->setRangeZoom((Qt::Orientation)orientation);
|
||||
} else {
|
||||
yscale=GetScale(csvlog.at(0).at(index));
|
||||
for (int i=1; i<n; i++)
|
||||
{
|
||||
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
|
||||
double tmp;
|
||||
QString tstamp=csvlog.at(i).at(0)+QString(" ")+csvlog.at(i).at(1);
|
||||
if (csvlog.at(i).at(1).contains(".")) {
|
||||
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss.zzz").toTime_t();
|
||||
tmp+=csvlog.at(i).at(1).mid(csvlog.at(i).at(1).indexOf(".")).toDouble();
|
||||
} else {
|
||||
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss").toTime_t();
|
||||
}
|
||||
if (minx>tmp) {
|
||||
minx=tmp;
|
||||
}
|
||||
if (maxx<tmp) {
|
||||
maxx=tmp;
|
||||
}
|
||||
if (yscale<0) {
|
||||
tmpval = csvlog.at(i).at(index).toDouble();
|
||||
if (tmpval>maxy) {
|
||||
maxy=tmpval;
|
||||
}
|
||||
if (tmpval<miny) {
|
||||
miny=tmpval;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (yscale<0) {
|
||||
if (miny<0) {
|
||||
miny=-miny;
|
||||
}
|
||||
if (maxy<0) {
|
||||
maxy=-maxy;
|
||||
}
|
||||
if (miny>maxy) {
|
||||
yscale=miny/1000.0;
|
||||
} else {
|
||||
yscale=maxy/1000.0;
|
||||
}
|
||||
if (yscale==0) {
|
||||
yscale=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i=1; i<n; i++) {
|
||||
if ((ui->logTable->item(i-1,1)->isSelected() &&rangeSelected) || !rangeSelected) {
|
||||
double tmp;
|
||||
QString tstamp=csvlog.at(i).at(0)+QString(" ")+csvlog.at(i).at(1);
|
||||
if (csvlog.at(i).at(1).contains(".")) {
|
||||
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss.zzz").toTime_t();
|
||||
tmp+=csvlog.at(i).at(1).mid(csvlog.at(i).at(1).indexOf(".")).toDouble();
|
||||
} else {
|
||||
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss").toTime_t();
|
||||
}
|
||||
x[itemCount] = tmp-minx;
|
||||
y[itemCount] = csvlog.at(i).at(index).toDouble()/yscale;
|
||||
itemCount++;
|
||||
}
|
||||
}
|
||||
QPen graphPen;
|
||||
QColor color=palette.at(index % 60);
|
||||
graphPen.setColor(color);
|
||||
graphPen.setWidthF(1.5);
|
||||
if (numplots<3) {
|
||||
if (plot==1) {
|
||||
ui->customPlot->xAxis->setRange(0, maxx-minx);
|
||||
ui->customPlot->yAxis->setRange(miny,maxy);
|
||||
ui->customPlot->yAxis->setLabelColor(color);
|
||||
ui->customPlot->yAxis->setLabel(csvlog.at(0).at(index));
|
||||
ui->customPlot->yAxis->setTickLabels(true);
|
||||
ui->customPlot->yAxis->setVisible(true);
|
||||
ui->customPlot->yAxis2->setVisible(false);
|
||||
ui->customPlot->addGraph(ui->customPlot->xAxis, ui->customPlot->yAxis);
|
||||
ui->customPlot->graph(0)->setName(csvlog.at(0).at(index));
|
||||
ui->customPlot->graph(0)->setData(x, y);
|
||||
ui->customPlot->graph(0)->setLineStyle(QCPGraph::lsLine);
|
||||
ui->customPlot->graph(0)->setScatterStyle(QCP::ssNone);
|
||||
//ui->customPlot->graph()->setLineStyle((QCPGraph::LineStyle)(rand()%5+1));
|
||||
ui->customPlot->graph(0)->setPen(graphPen);
|
||||
}
|
||||
else {
|
||||
ui->customPlot->xAxis2->setRange(0, maxx-minx);
|
||||
ui->customPlot->yAxis2->setTickLabels(true);
|
||||
ui->customPlot->yAxis2->setRange(miny,maxy);
|
||||
ui->customPlot->yAxis2->setVisible(true);
|
||||
ui->customPlot->yAxis2->setLabelColor(color);
|
||||
ui->customPlot->yAxis2->setLabel(csvlog.at(0).at(index));
|
||||
ui->customPlot->addGraph(ui->customPlot->xAxis2, ui->customPlot->yAxis2);
|
||||
ui->customPlot->graph(1)->setName(csvlog.at(0).at(index));
|
||||
ui->customPlot->graph(1)->setData(x, y);
|
||||
ui->customPlot->graph(1)->setLineStyle(QCPGraph::lsLine);
|
||||
ui->customPlot->graph(1)->setScatterStyle(QCP::ssNone);
|
||||
//ui->customPlot->graph()->setLineStyle((QCPGraph::LineStyle)(rand()%5+1));
|
||||
ui->customPlot->graph(1)->setPen(graphPen);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ui->customPlot->yAxis->setTickLabels(false);
|
||||
ui->customPlot->yAxis2->setTickLabels(false);
|
||||
ui->customPlot->yAxis->setRange(-1100, 1100);
|
||||
ui->customPlot->yAxis->setVisible(false);
|
||||
ui->customPlot->yAxis2->setVisible(false);
|
||||
ui->customPlot->addGraph();
|
||||
ui->customPlot->graph()->setName(csvlog.at(0).at(index));
|
||||
ui->customPlot->graph()->setData(x, y);
|
||||
ui->customPlot->graph()->setLineStyle(QCPGraph::lsLine);
|
||||
ui->customPlot->graph()->setScatterStyle(QCP::ssNone);
|
||||
//ui->customPlot->graph()->setLineStyle((QCPGraph::LineStyle)(rand()%5+1));
|
||||
ui->customPlot->graph()->setPen(graphPen);
|
||||
ui->customPlot->axisRect()->setRangeZoom(Qt::Horizontal|Qt::Vertical);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,27 +395,17 @@ void logsDialog::removeSelectedGraph()
|
||||
void logsDialog::removeAllGraphs()
|
||||
{
|
||||
ui->customPlot->clearGraphs();
|
||||
ui->customPlot->legend->setVisible(false);
|
||||
ui->customPlot->yAxis2->setVisible(false);
|
||||
ui->customPlot->yAxis->setTickLabels(false);
|
||||
ui->customPlot->replot();
|
||||
}
|
||||
|
||||
void logsDialog::moveLegend()
|
||||
{
|
||||
if (QAction* contextAction = qobject_cast<QAction*>(sender())) // make sure this slot is really called by a context menu action, so it carries the data we need
|
||||
{
|
||||
bool ok;
|
||||
int dataInt = contextAction->data().toInt(&ok);
|
||||
if (ok)
|
||||
{
|
||||
ui->customPlot->legend->setPositionStyle((QCPLegend::PositionStyle)dataInt);
|
||||
ui->customPlot->replot();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void logsDialog::on_fileOpen_BT_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this,tr("Select your log file"), g.logDir());
|
||||
if (!fileName.isEmpty()) {
|
||||
|
||||
g.logDir( fileName );
|
||||
ui->FileName_LE->setText(fileName);
|
||||
if (cvsFileParse()) {
|
||||
@@ -592,29 +425,28 @@ void logsDialog::on_fileOpen_BT_clicked()
|
||||
ui->logTable->setColumnCount(csvlog.at(0).count());
|
||||
ui->logTable->setRowCount(csvlog.count()-1);
|
||||
ui->logTable->setHorizontalHeaderLabels(csvlog.at(0));
|
||||
|
||||
QAbstractItemModel *model = ui->logTable->model();
|
||||
for (int i=1; i<csvlog.count(); i++) {
|
||||
for (int j=0; j<csvlog.at(0).count(); j++) {
|
||||
QTableWidgetItem* item= new QTableWidgetItem(csvlog.at(i).at(j));
|
||||
if (j>1) {
|
||||
item->setTextAlignment(Qt::AlignRight);
|
||||
} else {
|
||||
item->setTextAlignment(Qt::AlignCenter);
|
||||
}
|
||||
ui->logTable->setItem(i-1,j,item );
|
||||
model->setData(model->index(i - 1, j, QModelIndex()), csvlog.at(i).at(j));
|
||||
}
|
||||
}
|
||||
ui->logTable->resizeColumnsToContents();
|
||||
ui->logTable->resizeRowsToContents();
|
||||
// Hack - add some pixel of space to columns as Qt resize them too small
|
||||
for (int j=0; j<csvlog.at(0).count(); j++) {
|
||||
int width=ui->logTable->columnWidth(j);
|
||||
ui->logTable->setColumnWidth(j,width+5);
|
||||
}
|
||||
|
||||
ui->logTable->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents);
|
||||
QVarLengthArray<int> sizes;
|
||||
for (int i = 0; i < ui->logTable->columnCount(); i++) {
|
||||
sizes.append(ui->logTable->columnWidth(i));
|
||||
}
|
||||
ui->logTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
|
||||
for (int i = 0; i < ui->logTable->columnCount(); i++) {
|
||||
ui->logTable->setColumnWidth(i, sizes.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool logsDialog::cvsFileParse()
|
||||
bool logsDialog::cvsFileParse()
|
||||
{
|
||||
QFile file(ui->FileName_LE->text());
|
||||
int errors=0;
|
||||
@@ -623,159 +455,306 @@ bool logsDialog::cvsFileParse()
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file
|
||||
return false;
|
||||
} else {
|
||||
ui->sessions_CB->clear();
|
||||
csvlog.clear();
|
||||
logFilename.clear();
|
||||
QTextStream inputStream(&file);
|
||||
QRegExp rx2("(?:\"([^\"]*)\";?)|(?:([^,]*),?)");
|
||||
QStringList list;
|
||||
QString buffer = file.readLine();
|
||||
|
||||
if (buffer.startsWith("Date,Time")) {
|
||||
file.reset();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
int numfields=-1;
|
||||
while (!file.atEnd()) {
|
||||
int pos2 = 0;
|
||||
QString buffer = file.readLine();
|
||||
QString line=buffer.trimmed();
|
||||
list.clear();
|
||||
if(line.size()<1){
|
||||
list << "";
|
||||
} else {
|
||||
while (line.size()>pos2 && (pos2 = rx2.indexIn(line, pos2)) != -1) {
|
||||
QString col;
|
||||
if(rx2.cap(1).size()>0) {
|
||||
col = rx2.cap(1);
|
||||
} else if(rx2.cap(2).size()>0) {
|
||||
col = rx2.cap(2);
|
||||
}
|
||||
if (col.contains(".")) {
|
||||
if (col.indexOf(".")==(col.length()-3)) {
|
||||
col.append("0");
|
||||
}
|
||||
}
|
||||
list<<col;
|
||||
if(col.size()) {
|
||||
pos2 += rx2.matchedLength();
|
||||
} else {
|
||||
pos2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
QString line = file.readLine().trimmed();
|
||||
QStringList columns = line.split(',');
|
||||
if (numfields==-1) {
|
||||
numfields=list.count();
|
||||
numfields=columns.count();
|
||||
}
|
||||
if (list.count()==numfields) {
|
||||
csvlog.append(list);
|
||||
if (columns.count()==numfields) {
|
||||
csvlog.append(columns);
|
||||
} else {
|
||||
errors++;
|
||||
}
|
||||
lines++;
|
||||
}
|
||||
|
||||
logFilename=QFileInfo(file.fileName()).baseName();
|
||||
}
|
||||
|
||||
|
||||
file.close();
|
||||
if (errors>1) {
|
||||
QMessageBox::warning(this, "Companion", tr("The selected logfile contains %1 invalid lines out of %2 total lines").arg(errors).arg(lines));
|
||||
}
|
||||
plotLock=true;
|
||||
|
||||
int n=csvlog.count();
|
||||
if (n==1) {
|
||||
csvlog.clear();
|
||||
return false;
|
||||
}
|
||||
int lastvalue=0;
|
||||
int tmp;
|
||||
|
||||
plotLock = true;
|
||||
|
||||
ui->sessions_CB->clear();
|
||||
ui->sessions_CB->addItem("---");
|
||||
for (int i=1; i<n; i++) {
|
||||
QString tstamp=csvlog.at(i).at(0)+QString(" ")+csvlog.at(i).at(1);
|
||||
|
||||
double lastvalue = 0;
|
||||
double tmp;
|
||||
for (int i = 1; i < n; i++) {
|
||||
QString tstamp = csvlog.at(i).at(0) + QString(" ") + csvlog.at(i).at(1);
|
||||
|
||||
if (csvlog.at(i).at(1).contains(".")) {
|
||||
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss.zzz").toTime_t();
|
||||
tmp+=csvlog.at(i).at(1).mid(csvlog.at(i).at(1).indexOf(".")).toDouble();
|
||||
tmp = QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss.zzz").toTime_t();
|
||||
tmp += csvlog.at(i).at(1).mid(csvlog.at(i).at(1).indexOf(".")).toDouble();
|
||||
} else {
|
||||
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss").toTime_t();
|
||||
tmp = QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss").toTime_t();
|
||||
}
|
||||
if (tmp>(lastvalue+60)) {
|
||||
ui->sessions_CB->addItem(tstamp, tmp);
|
||||
lastvalue=tmp;
|
||||
|
||||
if (tmp > (lastvalue+60)) {
|
||||
ui->sessions_CB->addItem(tstamp, i - 1);
|
||||
lastvalue = tmp;
|
||||
} else {
|
||||
lastvalue=tmp;
|
||||
lastvalue = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
plotLock=false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void logsDialog::on_sessions_CB_currentIndexChanged(int index)
|
||||
{
|
||||
if (plotLock)
|
||||
return;
|
||||
plotLock=true;
|
||||
int start=0;
|
||||
int stop=-1;
|
||||
if (index!=0) {
|
||||
start=ui->sessions_CB->itemData(index,Qt::UserRole).toInt();
|
||||
if (index<(ui->sessions_CB->count()-1)) {
|
||||
stop=ui->sessions_CB->itemData(index+1,Qt::UserRole).toInt();
|
||||
}
|
||||
}
|
||||
// if (ui->logTable->item(i-1,1)->isSelected()) {
|
||||
if (plotLock) return;
|
||||
plotLock = true;
|
||||
|
||||
ui->logTable->clearSelection();
|
||||
if (start>0) {
|
||||
int n=csvlog.count();
|
||||
int tmp;
|
||||
ui->logTable->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
for (int i=1; i<n; i++) {
|
||||
QString tstamp=csvlog.at(i).at(0)+QString(" ")+csvlog.at(i).at(1);
|
||||
if (csvlog.at(i).at(1).contains(".")) {
|
||||
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss.zzz").toTime_t();
|
||||
tmp+=csvlog.at(i).at(1).mid(csvlog.at(i).at(1).indexOf(".")).toDouble();
|
||||
} else {
|
||||
tmp=QDateTime::fromString(tstamp, "yyyy-MM-dd HH:mm:ss").toTime_t();
|
||||
}
|
||||
if (stop>0) {
|
||||
if (tmp==start) {
|
||||
ui->logTable->selectionModel()->select(ui->logTable->model()->index(i-1,0), QItemSelectionModel::SelectCurrent|QItemSelectionModel::Rows);
|
||||
} else if (tmp>start && tmp<stop) {
|
||||
ui->logTable->selectionModel()->select(ui->logTable->model()->index(i-1,0), QItemSelectionModel::Select|QItemSelectionModel::Rows);
|
||||
}
|
||||
} else {
|
||||
if (tmp==start) {
|
||||
ui->logTable->selectionModel()->select(ui->logTable->model()->index(i-1,0), QItemSelectionModel::SelectCurrent|QItemSelectionModel::Rows);
|
||||
} else if (tmp>start) {
|
||||
ui->logTable->selectionModel()->select(ui->logTable->model()->index(i-1,0), QItemSelectionModel::Select|QItemSelectionModel::Rows);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index != 0) {
|
||||
int bottom;
|
||||
if (index < ui->sessions_CB->count() - 1) {
|
||||
bottom = ui->sessions_CB->itemData(index + 1, Qt::UserRole).toInt();
|
||||
} else {
|
||||
bottom = ui->logTable->rowCount();
|
||||
}
|
||||
|
||||
QModelIndex topLeft = ui->logTable->model()->index(
|
||||
ui->sessions_CB->itemData(index, Qt::UserRole).toInt(), 0 , QModelIndex());
|
||||
QModelIndex bottomRight = ui->logTable->model()->index(
|
||||
bottom - 1, ui->logTable->columnCount() - 1, QModelIndex());
|
||||
|
||||
QItemSelection selection(topLeft, bottomRight);
|
||||
ui->logTable->selectionModel()->select(selection, QItemSelectionModel::Select);
|
||||
}
|
||||
plotLock=false;
|
||||
|
||||
plotLock = false;
|
||||
plotLogs();
|
||||
}
|
||||
|
||||
void logsDialog::plotLogs()
|
||||
{
|
||||
if (plotLock)
|
||||
if (plotLock) return;
|
||||
|
||||
if (!ui->FieldsTW->selectedItems().length()) {
|
||||
removeAllGraphs();
|
||||
return;
|
||||
int n = csvlog.at(0).count(); // number of points in graph
|
||||
}
|
||||
|
||||
plotsCollection plots;
|
||||
|
||||
QModelIndexList selection = ui->logTable->selectionModel()->selectedRows();
|
||||
int rowCount = selection.length();
|
||||
bool hasLogSelection;
|
||||
QVarLengthArray<int> selectedRows;
|
||||
|
||||
if (rowCount) {
|
||||
hasLogSelection = true;
|
||||
foreach (QModelIndex index, selection) {
|
||||
selectedRows.append(index.row());
|
||||
}
|
||||
qSort(selectedRows.begin(), selectedRows.end());
|
||||
} else {
|
||||
hasLogSelection = false;
|
||||
rowCount = ui->logTable->rowCount();
|
||||
}
|
||||
|
||||
plots.min_x = QDateTime::currentDateTime().toTime_t();
|
||||
plots.max_x = 0;
|
||||
|
||||
foreach (QTableWidgetItem *plot, ui->FieldsTW->selectedItems()) {
|
||||
coords plotCoords;
|
||||
int plotColumn = plot->row() + 2; // Date and Time first
|
||||
|
||||
plotCoords.min_y = 999999;
|
||||
plotCoords.max_y = -999999;
|
||||
plotCoords.secondRange = false;
|
||||
plotCoords.name = plot->text();
|
||||
|
||||
for (int row = 0; row < rowCount; row++) {
|
||||
QTableWidgetItem *logValue;
|
||||
double y;
|
||||
double time;
|
||||
QString time_str;
|
||||
|
||||
if (hasLogSelection) {
|
||||
logValue = ui->logTable->item(selectedRows.at(row), plotColumn);
|
||||
time_str = ui->logTable->item(selectedRows.at(row), 0)->text() +
|
||||
QString(" ") + ui->logTable->item(selectedRows.at(row), 1)->text();
|
||||
} else {
|
||||
logValue = ui->logTable->item(row, plotColumn);
|
||||
time_str = ui->logTable->item(row, 0)->text() + QString(" ") +
|
||||
ui->logTable->item(row, 1)->text();
|
||||
}
|
||||
|
||||
y = logValue->text().toDouble();
|
||||
plotCoords.y.push_back(y);
|
||||
|
||||
if (plotCoords.min_y > y) {
|
||||
plotCoords.min_y = y;
|
||||
} else if (plotCoords.max_y < y) {
|
||||
plotCoords.max_y = y;
|
||||
}
|
||||
|
||||
if (time_str.contains('.')) {
|
||||
time = QDateTime::fromString(time_str, "yyyy-MM-dd HH:mm:ss.zzz")
|
||||
.toTime_t();
|
||||
time += time_str.mid(time_str.indexOf('.')).toDouble();
|
||||
} else {
|
||||
time = QDateTime::fromString(time_str, "yyyy-MM-dd HH:mm:ss")
|
||||
.toTime_t();
|
||||
}
|
||||
plotCoords.x.push_back(time);
|
||||
|
||||
if (plots.min_x > time) {
|
||||
plots.min_x = time;
|
||||
} else if (plots.max_x < time) {
|
||||
plots.max_x = time;
|
||||
}
|
||||
}
|
||||
plots.coords.append(plotCoords);
|
||||
}
|
||||
|
||||
plots.rangeOneMin = plots.coords.at(0).min_y;
|
||||
plots.rangeOneMax = plots.coords.at(0).max_y;
|
||||
plots.twoRanges = false;
|
||||
plots.tooManyRanges = false;
|
||||
|
||||
for (int i = 1; i < plots.coords.size(); i++) {
|
||||
if (plots.tooManyRanges) {
|
||||
if (plots.coords.at(i).min_y < plots.rangeOneMin) {
|
||||
plots.rangeOneMin = plots.coords.at(i).min_y;
|
||||
}
|
||||
if (plots.coords.at(i).max_y > plots.rangeOneMax) {
|
||||
plots.rangeOneMax = plots.coords.at(i).max_y;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
double actualRange = plots.rangeOneMax - plots.rangeOneMin;
|
||||
double thisRange = plots.coords.at(i).max_y - plots.coords.at(i).min_y;
|
||||
|
||||
if (thisRange > actualRange * 1.3 || thisRange * 1.3 < actualRange ||
|
||||
plots.coords.at(i).min_y > plots.rangeOneMax ||
|
||||
plots.coords.at(i).max_y < plots.rangeOneMin) {
|
||||
plots.coords[i].secondRange = true;
|
||||
if (plots.twoRanges) {
|
||||
actualRange = plots.rangeTwoMax - plots.rangeTwoMin;
|
||||
if (thisRange > actualRange * 1.3 || thisRange * 1.3 < actualRange ||
|
||||
plots.coords.at(i).min_y > plots.rangeTwoMax ||
|
||||
plots.coords.at(i).max_y < plots.rangeTwoMin) {
|
||||
plots.tooManyRanges = true;
|
||||
plots.twoRanges = false;
|
||||
if (plots.rangeTwoMin < plots.rangeOneMin) {
|
||||
plots.rangeOneMin = plots.rangeTwoMin;
|
||||
}
|
||||
if (plots.rangeTwoMax > plots.rangeOneMax) {
|
||||
plots.rangeOneMax = plots.rangeTwoMax;
|
||||
}
|
||||
if (plots.coords.at(i).min_y < plots.rangeOneMin) {
|
||||
plots.rangeOneMin = plots.coords.at(i).min_y;
|
||||
}
|
||||
if (plots.coords.at(i).max_y > plots.rangeOneMax) {
|
||||
plots.rangeOneMax = plots.coords.at(i).max_y;
|
||||
}
|
||||
} else {
|
||||
if (plots.coords.at(i).min_y < plots.rangeTwoMin) {
|
||||
plots.rangeTwoMin = plots.coords.at(i).min_y;
|
||||
}
|
||||
if (plots.coords.at(i).max_y > plots.rangeTwoMax) {
|
||||
plots.rangeTwoMax = plots.coords.at(i).max_y;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
plots.twoRanges = true;
|
||||
plots.rangeTwoMax = plots.coords.at(i).max_y;
|
||||
plots.rangeTwoMin = plots.coords.at(i).min_y;
|
||||
}
|
||||
} else {
|
||||
if (plots.coords.at(i).min_y < plots.rangeOneMin) {
|
||||
plots.rangeOneMin = plots.coords.at(i).min_y;
|
||||
}
|
||||
if (plots.coords.at(i).max_y > plots.rangeOneMax) {
|
||||
plots.rangeOneMax = plots.coords.at(i).max_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plots.twoRanges) {
|
||||
rangeRatio = (plots.rangeTwoMax - plots.rangeTwoMin) /
|
||||
(plots.rangeOneMax - plots.rangeOneMin);
|
||||
rangeyAxisMin = plots.rangeOneMin;
|
||||
rangeyAxisMax = plots.rangeOneMax;
|
||||
rangeyAxis2Min = plots.rangeTwoMin;
|
||||
rangeyAxis2Max = plots.rangeTwoMax;
|
||||
|
||||
hasyAxis2 = true;
|
||||
} else {
|
||||
hasyAxis2 = false;
|
||||
}
|
||||
|
||||
removeAllGraphs();
|
||||
int numplots=0;
|
||||
int plots=0;
|
||||
for (int i=0; i<n-2; i++) {
|
||||
if (ui->FieldsTW->item(0,i)->isSelected()) {
|
||||
numplots++;
|
||||
}
|
||||
|
||||
ui->customPlot->xAxis->setRange(plots.min_x, plots.max_x);
|
||||
|
||||
ui->customPlot->yAxis->setRange(plots.rangeOneMin, plots.rangeOneMax);
|
||||
ui->customPlot->yAxis->setTickLabels(true);
|
||||
|
||||
if (plots.twoRanges) {
|
||||
ui->customPlot->yAxis2->setRange(plots.rangeTwoMin, plots.rangeTwoMax);
|
||||
ui->customPlot->yAxis2->setVisible(true);
|
||||
}
|
||||
for (int i=0; i<n-2; i++) {
|
||||
if (ui->FieldsTW->item(0,i)->isSelected()) {
|
||||
plots++;
|
||||
plotValue(i+2,plots, numplots);
|
||||
|
||||
for (int i = 0; i < plots.coords.size(); i++) {
|
||||
if (plots.coords.at(i).secondRange && plots.twoRanges) {
|
||||
ui->customPlot->addGraph(ui->customPlot->xAxis, ui->customPlot->yAxis2);
|
||||
} else {
|
||||
ui->customPlot->addGraph();
|
||||
}
|
||||
ui->customPlot->graph(i)->setData(plots.coords.at(i).x,
|
||||
plots.coords.at(i).y);
|
||||
pen.setColor(colors.at(i % colors.size()));
|
||||
ui->customPlot->graph(i)->setPen(pen);
|
||||
ui->customPlot->graph(i)->setName(plots.coords.at(i).name);
|
||||
}
|
||||
ui->customPlot->legend->setVisible((numplots>2));
|
||||
ui->customPlot->replot();
|
||||
|
||||
ui->customPlot->legend->setVisible(true);
|
||||
ui->customPlot->replot();
|
||||
}
|
||||
|
||||
void logsDialog::setRangeyAxis2(QCPRange range)
|
||||
{
|
||||
if (hasyAxis2) {
|
||||
double lowerChange = (range.lower - rangeyAxisMin) * rangeRatio;
|
||||
double upperChange = (range.upper - rangeyAxisMax) * rangeRatio;
|
||||
rangeyAxisMin = range.lower;
|
||||
rangeyAxisMax = range.upper;
|
||||
rangeyAxis2Min += lowerChange;
|
||||
rangeyAxis2Max += upperChange;
|
||||
|
||||
ui->customPlot->yAxis2->setRange(rangeyAxis2Min, rangeyAxis2Max);
|
||||
}
|
||||
}
|
||||
|
||||
+36
-12
@@ -3,7 +3,27 @@
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include "qcustomplot.h"
|
||||
#include "qcustomplot/qcustomplot.h"
|
||||
|
||||
struct coords {
|
||||
QVector<double> x, y;
|
||||
double min_y;
|
||||
double max_y;
|
||||
bool secondRange;
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct plotsCollection {
|
||||
QVarLengthArray<struct coords> coords;
|
||||
double min_x;
|
||||
double max_x;
|
||||
bool twoRanges;
|
||||
bool tooManyRanges;
|
||||
double rangeOneMin;
|
||||
double rangeOneMax;
|
||||
double rangeTwoMin;
|
||||
double rangeTwoMax;
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
class logsDialog;
|
||||
@@ -12,14 +32,13 @@ namespace Ui {
|
||||
class logsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
|
||||
public:
|
||||
explicit logsDialog(QWidget *parent = 0);
|
||||
~logsDialog();
|
||||
|
||||
|
||||
private slots:
|
||||
void titleDoubleClick();
|
||||
void titleDoubleClick(QMouseEvent *evt, QCPPlotTitle *title);
|
||||
void axisLabelDoubleClick(QCPAxis* axis, QCPAxis::SelectablePart part);
|
||||
void legendDoubleClick(QCPLegend* legend, QCPAbstractLegendItem* item);
|
||||
void selectionChanged();
|
||||
@@ -27,23 +46,28 @@ private slots:
|
||||
void mouseWheel();
|
||||
void removeSelectedGraph();
|
||||
void removeAllGraphs();
|
||||
void moveLegend();
|
||||
void plotLogs();
|
||||
void plotValue(int index, int plot, int numplots);
|
||||
void plottableItemDoubleClick(QCPAbstractPlottable * plottable, QMouseEvent * event);
|
||||
// void graphClicked(QCPAbstractPlottable *plottable);
|
||||
void on_fileOpen_BT_clicked();
|
||||
void on_sessions_CB_currentIndexChanged(int index);
|
||||
void on_mapsButton_clicked();
|
||||
|
||||
void setRangeyAxis2(QCPRange range);
|
||||
|
||||
private:
|
||||
QList<QStringList> csvlog;
|
||||
Ui::logsDialog *ui;
|
||||
bool cvsFileParse();
|
||||
double GetScale(QString channel);
|
||||
QList<QColor> palette;
|
||||
bool plotLock;
|
||||
QString logFilename;
|
||||
|
||||
QVarLengthArray<Qt::GlobalColor> colors;
|
||||
QPen pen;
|
||||
|
||||
bool hasyAxis2;
|
||||
double rangeRatio;
|
||||
double rangeyAxisMin;
|
||||
double rangeyAxisMax;
|
||||
double rangeyAxis2Min;
|
||||
double rangeyAxis2Max;
|
||||
};
|
||||
|
||||
#endif // LOGSDIALOG_H
|
||||
|
||||
@@ -283,7 +283,7 @@
|
||||
<customwidget>
|
||||
<class>QCustomPlot</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>./qcustomplot.h</header>
|
||||
<header>qcustomplot/qcustomplot.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
|
||||
+129
-93
@@ -184,6 +184,44 @@ void MainWindow::displayWarnings()
|
||||
}
|
||||
}
|
||||
|
||||
QString MainWindow::getBackupPath() {
|
||||
QString backupPath;
|
||||
bool backupEnable = g.profile[g.id()].penableBackup();
|
||||
if (backupEnable) {
|
||||
backupPath=g.profile[g.id()].pBackupDir();
|
||||
if (!backupPath.isEmpty()) {
|
||||
if (!QDir(backupPath).exists()) {
|
||||
backupEnable = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
backupEnable = false;
|
||||
}
|
||||
}
|
||||
if (!backupEnable) {
|
||||
backupEnable=g.enableBackup();
|
||||
backupPath = g.backupDir();
|
||||
if (!backupPath.isEmpty()) {
|
||||
if (!QDir(backupPath).exists()) {
|
||||
backupEnable = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
backupEnable = false;
|
||||
}
|
||||
}
|
||||
if ((g.enableBackup() || g.profile[g.id()].penableBackup()) && !(backupEnable) && !IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||
if (!QDir(backupPath).exists()) {
|
||||
QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
backupEnable=false;
|
||||
}
|
||||
if (!backupEnable) backupPath.clear();
|
||||
return backupPath;
|
||||
}
|
||||
|
||||
void MainWindow::doAutoUpdates()
|
||||
{
|
||||
if (g.autoCheckApp())
|
||||
@@ -409,7 +447,7 @@ void MainWindow::checkForFirmwareUpdateFinished(QNetworkReply * reply)
|
||||
QString rn = GetCurrentFirmware()->getReleaseNotesUrl();
|
||||
QAbstractButton *rnButton = NULL;
|
||||
msgBox.setWindowTitle("Companion");
|
||||
msgBox.setInformativeText(tr("Firmware %1 does not seem to have ever been downloaded.\nRelease %2 is available.\nDo you want to download it now?").arg(current_firmware_variant->getId()).arg(versionString));
|
||||
msgBox.setInformativeText(tr("Firmware %1 does not seem to have ever been downloaded.\nRelease %2 is available.\nDo you want to download it now?\n\nWe recommend you view the release notes using the button below to learn about any changes that may be important to you.").arg(current_firmware_variant->getId()).arg(versionString));
|
||||
QAbstractButton *YesButton = msgBox.addButton(trUtf8("Yes"), QMessageBox::YesRole);
|
||||
msgBox.addButton(trUtf8("No"), QMessageBox::NoRole);
|
||||
if (!rn.isEmpty()) {
|
||||
@@ -438,7 +476,7 @@ void MainWindow::checkForFirmwareUpdateFinished(QNetworkReply * reply)
|
||||
QString rn = GetCurrentFirmware()->getReleaseNotesUrl();
|
||||
QAbstractButton *rnButton = NULL;
|
||||
msgBox.setText("Companion");
|
||||
msgBox.setInformativeText(tr("A new version of %1 firmware is available:\n - current is %2\n - newer is %3\n\nDo you want to download it now ?").arg(current_firmware_variant->getId()).arg(currentVersionString).arg(versionString));
|
||||
msgBox.setInformativeText(tr("A new version of %1 firmware is available:\n - current is %2\n - newer is %3\n\nDo you want to download it now?\n\nWe recommend you view the release notes using the button below to learn about any changes that may be important to you.").arg(current_firmware_variant->getId()).arg(currentVersionString).arg(versionString));
|
||||
QAbstractButton *YesButton = msgBox.addButton(trUtf8("Yes"), QMessageBox::YesRole);
|
||||
msgBox.addButton(trUtf8("No"), QMessageBox::NoRole);
|
||||
if (!rn.isEmpty()) {
|
||||
@@ -982,6 +1020,7 @@ bool MainWindow::readFirmwareFromRadio(const QString filename)
|
||||
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
|
||||
QString path = FindMassstoragePath("FIRMWARE.BIN");
|
||||
if (!path.isEmpty()) {
|
||||
qDebug() << "MainWindow::readFirmwareFromRadio(): reading" << path << "into" << filename;
|
||||
QStringList str;
|
||||
str << path << filename;
|
||||
avrOutputDialog *ad = new avrOutputDialog(this, "", str, message);
|
||||
@@ -994,6 +1033,7 @@ bool MainWindow::readFirmwareFromRadio(const QString filename)
|
||||
|
||||
if (result == false) {
|
||||
QStringList str = GetReceiveFlashCommand(filename);
|
||||
qDebug() << "MainWindow::readFirmwareFromRadio(): reading" << filename << "with avrdude:" << str;
|
||||
avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, message);
|
||||
ad->setWindowIcon(CompanionIcon("read_flash.png"));
|
||||
ad->exec();
|
||||
@@ -1016,6 +1056,7 @@ bool MainWindow::writeFirmwareToRadio(const QString filename)
|
||||
if (IS_ARM(GetCurrentFirmware()->getBoard())) {
|
||||
QString path = FindMassstoragePath("FIRMWARE.BIN");
|
||||
if (!path.isEmpty()) {
|
||||
qDebug() << "MainWindow::writeFirmwareToRadio(): writing" << path << "from" << filename;
|
||||
QStringList str;
|
||||
str << filename << path;
|
||||
avrOutputDialog *ad = new avrOutputDialog(this, "", str, message);
|
||||
@@ -1028,6 +1069,7 @@ bool MainWindow::writeFirmwareToRadio(const QString filename)
|
||||
|
||||
if (result == false) {
|
||||
QStringList str = GetSendFlashCommand(filename);
|
||||
qDebug() << "MainWindow::writeFirmwareToRadio(): writing" << filename << "with avrdude:" << str;
|
||||
avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, message, AVR_DIALOG_CLOSE_IF_SUCCESSFUL);
|
||||
CompanionIcon iconw("write_flash.png");
|
||||
ad->setWindowIcon(iconw);
|
||||
@@ -1149,20 +1191,9 @@ void MainWindow::writeBackup()
|
||||
if (!isValidEEPROM(fileName))
|
||||
ret = QMessageBox::question(this, "Companion", tr("The file %1\nhas not been recognized as a valid Models and Settings file\nWrite anyway ?").arg(QFileInfo(fileName).fileName()), QMessageBox::Yes | QMessageBox::No);
|
||||
if (ret != QMessageBox::Yes) return;
|
||||
bool backupEnable = g.enableBackup();
|
||||
QString backupPath = g.backupDir();
|
||||
if (!backupPath.isEmpty()) {
|
||||
if (!QDir(backupPath).exists()) {
|
||||
if (backupEnable) {
|
||||
QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist"));
|
||||
}
|
||||
backupEnable = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
backupEnable = false;
|
||||
}
|
||||
|
||||
bool backupEnable=true;
|
||||
QString backupPath=getBackupPath();
|
||||
if (backupPath.isEmpty()) backupEnable=false;
|
||||
if (backup) {
|
||||
if (backupEnable) {
|
||||
QString backupFile = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin";
|
||||
@@ -1294,92 +1325,97 @@ bool MainWindow::convertEEPROM(QString backupFile, QString restoreFile, QString
|
||||
|
||||
void MainWindow::writeFlash(QString fileToFlash)
|
||||
{
|
||||
QString fileName;
|
||||
bool backup = g.backupOnFlash();
|
||||
if(!fileToFlash.isEmpty())
|
||||
fileName = fileToFlash;
|
||||
burnDialog *cd = new burnDialog(this, 2, &fileName, &backup);
|
||||
cd->exec();
|
||||
if (IS_TARANIS(GetEepromInterface()->getBoard()))
|
||||
backup=false;
|
||||
if (!fileName.isEmpty()) {
|
||||
if (g.checkHardwareCompatibility()) {
|
||||
QString tempFlash = generateProcessUniqueTempFileName("flash.bin");
|
||||
if (!readFirmwareFromRadio(tempFlash)) {
|
||||
QMessageBox::warning(this, tr("Firmware check failed"), tr("Could not check firmware from radio"));
|
||||
return;
|
||||
}
|
||||
FlashInterface previousFlash(tempFlash);
|
||||
FlashInterface newFlash(fileName);
|
||||
if (!newFlash.isHardwareCompatible(previousFlash)) {
|
||||
QMessageBox::warning(this, tr("Firmware check failed"), tr("New firmware is not compatible with the one currently installed!"));
|
||||
return;
|
||||
}
|
||||
qDebug() << "MainWindow::writeFlash(): started with" << fileToFlash;
|
||||
QString fileName;
|
||||
bool backup = g.backupOnFlash();
|
||||
if(!fileToFlash.isEmpty()) {
|
||||
fileName = fileToFlash;
|
||||
}
|
||||
|
||||
burnDialog *cd = new burnDialog(this, 2, &fileName, &backup);
|
||||
cd->exec();
|
||||
qDebug() << "MainWindow::writeFlash(): flashing " << fileName;
|
||||
|
||||
if (IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||
backup=false;
|
||||
}
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
if (g.checkHardwareCompatibility()) {
|
||||
QString tempFlash = generateProcessUniqueTempFileName("flash-check.bin");
|
||||
if (!readFirmwareFromRadio(tempFlash)) {
|
||||
QMessageBox::warning(this, tr("Firmware check failed"), tr("Could not check firmware from radio"));
|
||||
return;
|
||||
}
|
||||
g.backupOnFlash(backup);
|
||||
if (backup) {
|
||||
QString backupFile = generateProcessUniqueTempFileName("backup.bin");
|
||||
bool backupEnable=g.enableBackup();
|
||||
QString backupPath=g.backupDir();
|
||||
if (!backupPath.isEmpty() && !IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||
if (!QDir(backupPath).exists()) {
|
||||
if (backupEnable) {
|
||||
QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist"));
|
||||
}
|
||||
backupEnable=false;
|
||||
FlashInterface previousFlash(tempFlash);
|
||||
qunlink(tempFlash);
|
||||
FlashInterface newFlash(fileName);
|
||||
qDebug() << "MainWindow::writeFlash(): checking firmware compatibility between " << tempFlash << "and" << fileName;
|
||||
if (!newFlash.isHardwareCompatible(previousFlash)) {
|
||||
QMessageBox::warning(this, tr("Firmware check failed"), tr("New firmware is not compatible with the one currently installed!"));
|
||||
if (isTempFileName(fileName)) {
|
||||
qDebug() << "MainWindow::writeFlash(): removing temporary file" << fileName;
|
||||
qunlink(fileName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
g.backupOnFlash(backup);
|
||||
if (backup) {
|
||||
bool backupEnable=true;
|
||||
QString backupFile;
|
||||
QString backupPath=getBackupPath();
|
||||
if (backupPath.isEmpty()) {
|
||||
backupEnable=false;
|
||||
backupFile = generateProcessUniqueTempFileName("backup.bin");
|
||||
}
|
||||
else {
|
||||
QDateTime datetime;
|
||||
backupFile = backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss")+".bin";
|
||||
}
|
||||
|
||||
if (readEepromFromRadio(backupFile, tr("Backup Models and Settings From Radio"))) {
|
||||
sleep(2);
|
||||
int res = writeFirmwareToRadio(fileName);
|
||||
if (res) {
|
||||
QString restoreFile = generateProcessUniqueTempFileName("restore.bin");
|
||||
if (!convertEEPROM(backupFile, restoreFile, fileName)) {
|
||||
QMessageBox::warning(this, tr("Conversion failed"), tr("Cannot convert Models and Settings for use with this firmware, original data will be used"));
|
||||
restoreFile = backupFile;
|
||||
}
|
||||
}
|
||||
else {
|
||||
backupEnable=false;
|
||||
}
|
||||
|
||||
if (backupEnable) {
|
||||
QDateTime datetime;
|
||||
backupFile.clear();
|
||||
backupFile = backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss")+".bin";
|
||||
}
|
||||
|
||||
if (readEepromFromRadio(backupFile, tr("Backup Models and Settings From Radio"))) {
|
||||
sleep(2);
|
||||
int res = writeFirmwareToRadio(fileName);
|
||||
if (res) {
|
||||
QString restoreFile = generateProcessUniqueTempFileName("restore.bin");
|
||||
if (!convertEEPROM(backupFile, restoreFile, fileName)) {
|
||||
QMessageBox::warning(this, tr("Conversion failed"), tr("Cannot convert Models and Settings for use with this firmware, original data will be used"));
|
||||
restoreFile = backupFile;
|
||||
}
|
||||
sleep(2);
|
||||
if (!writeEepromToRadio(restoreFile, tr("Restore Models and Settings To Radio"))) {
|
||||
QMessageBox::warning(this, tr("Restore failed"), tr("Could not restore Models and Settings to Radio. The models and settings data file can be found at: %1").arg(backupFile));
|
||||
}
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this, tr("Firmware write failed"), tr("Could not write firmware to radio. The models and settings data file can be found at: %1").arg(backupFile));
|
||||
if (!writeEepromToRadio(restoreFile, tr("Restore Models and Settings To Radio"))) {
|
||||
QMessageBox::warning(this, tr("Restore failed"), tr("Could not restore Models and Settings to Radio. The models and settings data file can be found at: %1").arg(backupFile));
|
||||
}
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(this, tr("Backup failed"), tr("Cannot backup existing Models and Settings from Radio. Firmware write process aborted"));
|
||||
QMessageBox::warning(this, tr("Firmware write failed"), tr("Could not write firmware to radio. The models and settings data file can be found at: %1").arg(backupFile));
|
||||
}
|
||||
}
|
||||
else {
|
||||
bool backupEnable=g.enableBackup();
|
||||
QString backupPath=g.backupDir();
|
||||
if (!QDir(backupPath).exists()) {
|
||||
if (backupEnable) {
|
||||
QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist"));
|
||||
}
|
||||
backupEnable=false;
|
||||
}
|
||||
if (backupEnable && !IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||
QDateTime datetime;
|
||||
QString backupFile = backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss")+".bin";
|
||||
readEepromFromRadio(backupFile, tr("Backup Models and Settings From Radio"));
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
writeFirmwareToRadio(fileName);
|
||||
QMessageBox::warning(this, tr("Backup failed"), tr("Cannot backup existing Models and Settings from Radio. Firmware write process aborted"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
bool backupEnable=true;
|
||||
QString backupPath=getBackupPath();
|
||||
if (backupPath.isEmpty()) {
|
||||
backupEnable=false;
|
||||
}
|
||||
if (backupEnable && !IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||
QDateTime datetime;
|
||||
QString backupFile = backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss")+".bin";
|
||||
readEepromFromRadio(backupFile, tr("Backup Models and Settings From Radio"));
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
writeFirmwareToRadio(fileName);
|
||||
}
|
||||
if (isTempFileName(fileName)) {
|
||||
qDebug() << "MainWindow::writeFlash(): removing temporary file" << fileName;
|
||||
qunlink(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::readBackup()
|
||||
@@ -1421,7 +1457,7 @@ void MainWindow::burnFuses()
|
||||
|
||||
void MainWindow::compare()
|
||||
{
|
||||
CompareDialog *fd = new CompareDialog(this);
|
||||
CompareDialog *fd = new CompareDialog(this,GetCurrentFirmware());
|
||||
fd->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
fd->show();
|
||||
}
|
||||
@@ -1475,7 +1511,7 @@ void MainWindow::updateMenus()
|
||||
updateIconSizeActions();
|
||||
updateIconThemeActions();
|
||||
|
||||
setWindowTitle(tr("OpenTX Companion - FW: %1 - Profile: %2").arg(GetCurrentFirmware()->getName()).arg( g.profile[g.id()].name() ));
|
||||
setWindowTitle(tr("OpenTX Companion 2.0 - FW: %1 - Profile: %2").arg(GetCurrentFirmware()->getName()).arg( g.profile[g.id()].name() ));
|
||||
}
|
||||
|
||||
MdiChild *MainWindow::createMdiChild()
|
||||
|
||||
@@ -82,6 +82,7 @@ class MainWindow : public QMainWindow
|
||||
void closeEvent(QCloseEvent *event);
|
||||
void dragEnterEvent(QDragEnterEvent *event);
|
||||
void dropEvent(QDropEvent *event);
|
||||
QString getBackupPath();
|
||||
|
||||
private slots:
|
||||
void openDocURL();
|
||||
|
||||
@@ -516,17 +516,9 @@ QString MdiChild::strippedName(const QString &fullFileName)
|
||||
|
||||
void MdiChild::writeEeprom() // write to Tx
|
||||
{
|
||||
bool backupEnable=g.enableBackup();
|
||||
QString backupPath=g.backupDir();
|
||||
if (!backupPath.isEmpty()) {
|
||||
if (!QDir(backupPath).exists()) {
|
||||
if (backupEnable) {
|
||||
QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist"));
|
||||
}
|
||||
backupEnable=false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bool backupEnable=true;
|
||||
QString backupPath=((MainWindow *)this->parent())->getBackupPath();
|
||||
if (backupPath.isEmpty()) {
|
||||
backupEnable=false;
|
||||
}
|
||||
QString stickCal=g.profile[g.id()].stickPotCalib();
|
||||
|
||||
@@ -109,19 +109,29 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
|
||||
QGraphicsScene *scene = new QGraphicsScene(ui->curvePreview);
|
||||
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
|
||||
ui->curvePreview->setScene(scene);
|
||||
|
||||
for (int i=0; i<firmware->getCapability(NumCurves); i++) {
|
||||
int numcurves=firmware->getCapability(NumCurves);
|
||||
int limit;
|
||||
if (numcurves>16) {
|
||||
limit=numcurves/2;
|
||||
} else {
|
||||
limit=numcurves;
|
||||
}
|
||||
for (int i=0; i<numcurves; i++) {
|
||||
visibleCurves[i] = false;
|
||||
|
||||
// The reset curve button
|
||||
QPushButton * reset = new QPushButton(this);
|
||||
reset->setProperty("index", i);
|
||||
reset->setMinimumSize(QSize(0, 0));
|
||||
reset->setMaximumSize(QSize(16, 16));
|
||||
reset->setIcon(CompanionIcon("clear.png"));
|
||||
reset->setIconSize(QSize(14, 14));
|
||||
connect(reset, SIGNAL(clicked()), this, SLOT(resetCurve()));
|
||||
ui->curvesLayout->addWidget(reset, i, 0, 1, 1);
|
||||
|
||||
if (i<limit) {
|
||||
ui->curvesLayout->addWidget(reset, i, 0, 1, 1);
|
||||
} else {
|
||||
ui->curvesLayout2->addWidget(reset, i-limit, 2, 1, 1);
|
||||
}
|
||||
// The edit curve button
|
||||
QPushButton * edit = new QPushButton(this);
|
||||
edit->setProperty("index", i);
|
||||
@@ -136,16 +146,31 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
|
||||
edit->setPalette(palette);
|
||||
edit->setText(tr("Curve %1").arg(i+1));
|
||||
connect(edit, SIGNAL(clicked()), this, SLOT(editCurve()));
|
||||
ui->curvesLayout->addWidget(edit, i, 1, 1, 1);
|
||||
|
||||
if (i<limit) {
|
||||
ui->curvesLayout->addWidget(edit, i, 1, 1, 1);
|
||||
} else {
|
||||
ui->curvesLayout2->addWidget(edit, i-limit, 1, 1, 1);
|
||||
}
|
||||
|
||||
// The curve plot checkbox
|
||||
QCheckBox * plot = new QCheckBox(this);
|
||||
plot->setProperty("index", i);
|
||||
plot->setPalette(palette);
|
||||
connect(plot, SIGNAL(toggled(bool)), this, SLOT(plotCurve(bool)));
|
||||
ui->curvesLayout->addWidget(plot, i, 2, 1, 1);
|
||||
if (i<limit) {
|
||||
ui->curvesLayout->addWidget(plot, i, 2, 1, 1);
|
||||
} else {
|
||||
ui->curvesLayout2->addWidget(plot, i-limit, 0, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
QSpacerItem * item = new QSpacerItem(1,1, QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
ui->curvesLayout->addItem(item,limit+1,1,1,1,0);
|
||||
if (limit!=numcurves) {
|
||||
QSpacerItem * item2 = new QSpacerItem(1,1, QSizePolicy::Fixed, QSizePolicy::Expanding);
|
||||
ui->curvesLayout2->addItem(item2,limit+1,1,1,1,0);
|
||||
}
|
||||
|
||||
for (int i=0; i<C9X_MAX_POINTS; i++) {
|
||||
spnx[i] = new QSpinBox(this);
|
||||
spnx[i]->setProperty("index", i);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>718</width>
|
||||
<width>605</width>
|
||||
<height>539</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -125,6 +125,9 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="curvesLayout2"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
@@ -172,38 +175,25 @@
|
||||
<property name="title">
|
||||
<string>Curve Creator</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_76" rowstretch="0,0,0,0,0,0,0,0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="yMidLabel">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="curveTypeLabel_2">
|
||||
<property name="text">
|
||||
<string>Y at X=0</string>
|
||||
<string>Curve type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="3">
|
||||
<widget class="QSpinBox" name="yMax">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QComboBox" name="curveType"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="yMaxLabel">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="curveCoeffLabel">
|
||||
<property name="text">
|
||||
<string>Y at X=100</string>
|
||||
<string>Coefficient</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="3">
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="curveCoeff">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
@@ -219,7 +209,83 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="3">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="yMinLabel">
|
||||
<property name="text">
|
||||
<string>Y at X=-100</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="yMin">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="yMidLabel">
|
||||
<property name="text">
|
||||
<string>Y at X=0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSpinBox" name="yMid">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="yMaxLabel">
|
||||
<property name="text">
|
||||
<string>Y at X=100</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSpinBox" name="yMax">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="curveSideLabel">
|
||||
<property name="text">
|
||||
<string>Side</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="curveSide">
|
||||
<item>
|
||||
<property name="text">
|
||||
@@ -238,77 +304,7 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="3">
|
||||
<widget class="QSpinBox" name="yMin">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="4">
|
||||
<widget class="QPushButton" name="curveApply">
|
||||
<property name="text">
|
||||
<string>Apply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="curveSideLabel">
|
||||
<property name="text">
|
||||
<string>Side</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="3">
|
||||
<widget class="QSpinBox" name="yMid">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-100</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="3">
|
||||
<widget class="QComboBox" name="curveType"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="curveTypeLabel_2">
|
||||
<property name="text">
|
||||
<string>Curve type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="yMinLabel">
|
||||
<property name="text">
|
||||
<string>Y at X=-100</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="curveCoeffLabel">
|
||||
<property name="text">
|
||||
<string>Coefficient</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -321,6 +317,13 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="curveApply">
|
||||
<property name="text">
|
||||
<string>Apply</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -345,7 +348,6 @@
|
||||
<tabstop>curveCustom</tabstop>
|
||||
<tabstop>curveSmooth</tabstop>
|
||||
<tabstop>curveName</tabstop>
|
||||
<tabstop>curveType</tabstop>
|
||||
<tabstop>curveCoeff</tabstop>
|
||||
<tabstop>yMin</tabstop>
|
||||
<tabstop>yMid</tabstop>
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
#include "customfunctions.h"
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QSpinBox>
|
||||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include "helpers.h"
|
||||
#include "appdata.h"
|
||||
|
||||
@@ -142,6 +136,13 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData & model,
|
||||
connect(fswtchParam[i], SIGNAL(editingFinished()), this, SLOT(customFunctionEdited()));
|
||||
paramLayout->addWidget(fswtchParam[i]);
|
||||
|
||||
fswtchParamTime[i] = new QTimeEdit(this);
|
||||
fswtchParamTime[i]->setProperty("index", i);
|
||||
fswtchParamTime[i]->setAccelerated(true);
|
||||
fswtchParamTime[i]->setDisplayFormat("hh:mm:ss");
|
||||
connect(fswtchParamTime[i], SIGNAL(editingFinished()), this, SLOT(customFunctionEdited()));
|
||||
paramLayout->addWidget(fswtchParamTime[i]);
|
||||
|
||||
fswtchParamT[i] = new QComboBox(this);
|
||||
fswtchParamT[i]->setProperty("index", i);
|
||||
paramLayout->addWidget(fswtchParamT[i]);
|
||||
@@ -154,7 +155,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData & model,
|
||||
|
||||
connect(fswtchParamArmT[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited()));
|
||||
connect(fswtchParamArmT[i], SIGNAL(editTextChanged ( const QString)), this, SLOT(customFunctionEdited()));
|
||||
|
||||
|
||||
fswtchBLcolor[i] = new QSlider(this);
|
||||
fswtchBLcolor[i]->setProperty("index", i);
|
||||
fswtchBLcolor[i]->setMinimum(0);
|
||||
@@ -181,7 +182,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData & model,
|
||||
fswtchEnable[i] = new QCheckBox(this);
|
||||
fswtchEnable[i]->setProperty("index", i);
|
||||
fswtchEnable[i]->setText(tr("ON"));
|
||||
fswtchEnable[i]->setFixedWidth( 50 );
|
||||
fswtchEnable[i]->setFixedWidth( 80 );
|
||||
repeatLayout->addWidget(fswtchEnable[i], i+1);
|
||||
connect(fswtchEnable[i], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited()));
|
||||
}
|
||||
@@ -190,7 +191,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData & model,
|
||||
addDoubleSpring(gridLayout, 5, num_fsw+1);
|
||||
|
||||
disableMouseScrolling();
|
||||
|
||||
|
||||
lock = false;
|
||||
}
|
||||
|
||||
@@ -257,6 +258,9 @@ void CustomFunctionsPanel::playMusic()
|
||||
phononCurrent = -1;
|
||||
}
|
||||
else {
|
||||
if (phononCurrent >= 0) {
|
||||
playBT[phononCurrent]->setIcon(CompanionIcon("play.png"));
|
||||
}
|
||||
phononCurrent = index;
|
||||
clickObject->clear();
|
||||
#ifdef __APPLE__
|
||||
@@ -274,12 +278,13 @@ void CustomFunctionsPanel::playMusic()
|
||||
#define CUSTOM_FUNCTION_NUMERIC_PARAM (1<<0)
|
||||
#define CUSTOM_FUNCTION_SOURCE_PARAM (1<<1)
|
||||
#define CUSTOM_FUNCTION_FILE_PARAM (1<<2)
|
||||
#define CUSTOM_FUNCTION_GV_MODE (1<<3)
|
||||
#define CUSTOM_FUNCTION_GV_TOOGLE (1<<4)
|
||||
#define CUSTOM_FUNCTION_ENABLE (1<<5)
|
||||
#define CUSTOM_FUNCTION_REPEAT (1<<6)
|
||||
#define CUSTOM_FUNCTION_PLAY (1<<7)
|
||||
#define CUSTOM_FUNCTION_BL_COLOR (1<<8)
|
||||
#define CUSTOM_FUNCTION_TIME_PARAM (1<<3)
|
||||
#define CUSTOM_FUNCTION_GV_MODE (1<<4)
|
||||
#define CUSTOM_FUNCTION_GV_TOOGLE (1<<5)
|
||||
#define CUSTOM_FUNCTION_ENABLE (1<<6)
|
||||
#define CUSTOM_FUNCTION_REPEAT (1<<7)
|
||||
#define CUSTOM_FUNCTION_PLAY (1<<8)
|
||||
#define CUSTOM_FUNCTION_BL_COLOR (1<<9)
|
||||
|
||||
void CustomFunctionsPanel::customFunctionEdited()
|
||||
{
|
||||
@@ -372,13 +377,11 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE;
|
||||
}
|
||||
else if (index>=FuncSetTimer1 && index<=FuncSetTimer2) {
|
||||
if (modified) model.funcSw[i].param = fswtchParam[i]->value();
|
||||
fswtchParam[i]->setDecimals(0);
|
||||
fswtchParam[i]->setSingleStep(1);
|
||||
fswtchParam[i]->setMinimum(0);
|
||||
fswtchParam[i]->setMaximum(59*60+59);
|
||||
fswtchParam[i]->setValue(model.funcSw[i].param);
|
||||
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_ENABLE;
|
||||
if (modified) model.funcSw[i].param = QTimeS(fswtchParamTime[i]->time()).seconds();
|
||||
fswtchParamTime[i]->setMinimumTime(QTime(0, 0, 0));
|
||||
fswtchParamTime[i]->setMaximumTime(QTime(0, 59, 59));
|
||||
fswtchParamTime[i]->setTime(QTimeS(model.funcSw[i].param));
|
||||
widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM + CUSTOM_FUNCTION_ENABLE;
|
||||
}
|
||||
else if (index==FuncVolume) {
|
||||
if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt();
|
||||
@@ -501,6 +504,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
}
|
||||
|
||||
fswtchParam[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_NUMERIC_PARAM);
|
||||
fswtchParamTime[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_TIME_PARAM);
|
||||
fswtchParamGV[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_TOOGLE);
|
||||
fswtchParamT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SOURCE_PARAM);
|
||||
fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM);
|
||||
@@ -638,7 +642,10 @@ void CustomFunctionsPanel::populateFuncParamArmTCB(QComboBox *b, char * value, c
|
||||
|
||||
bool added = false;
|
||||
QString currentvalue(value);
|
||||
foreach (QString entry, paramsList) {
|
||||
// Convert set into list and sort it alphabetically case insensitive
|
||||
QStringList list = QStringList::fromSet(paramsList);
|
||||
qSort(list.begin(), list.end(), caseInsensitiveLessThan);
|
||||
foreach (QString entry, list) {
|
||||
b->addItem(entry);
|
||||
if (entry==currentvalue) {
|
||||
b->setCurrentIndex(b->count()-1);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <QComboBox>
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QPushButton>
|
||||
#include <QTimeEdit>
|
||||
#ifdef PHONON
|
||||
#include <phonon/audiooutput.h>
|
||||
#include <phonon/mediaobject.h>
|
||||
@@ -70,6 +71,7 @@ class CustomFunctionsPanel : public ModelPanel
|
||||
QComboBox * fswtchFunc[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||
QCheckBox * fswtchParamGV[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||
QDoubleSpinBox * fswtchParam[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||
QTimeEdit * fswtchParamTime[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||
QPushButton * playBT[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||
QComboBox * fswtchParamT[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||
QComboBox * fswtchParamArmT[C9X_MAX_CUSTOM_FUNCTIONS];
|
||||
|
||||
@@ -209,7 +209,9 @@ void FlightModePanel::update()
|
||||
|
||||
if (ui->gvGB->isVisible()) {
|
||||
for (int i=0; i<gvCount; i++) {
|
||||
gvNames[i]->setText(model.gvars_names[i]);
|
||||
if (firmware->getCapability(GvarsName) > 0) {
|
||||
gvNames[i]->setText(model.gvars_names[i]);
|
||||
}
|
||||
gvValues[i]->setDisabled(model.isGVarLinked(phaseIdx, i));
|
||||
gvValues[i]->setValue(model.getGVarValue(phaseIdx, i));
|
||||
if (IS_TARANIS(GetEepromInterface()->getBoard()) && phaseIdx == 0) {
|
||||
|
||||
@@ -261,6 +261,7 @@ void LogicalSwitchesPanel::edited()
|
||||
}
|
||||
emit modified();
|
||||
lock = false;
|
||||
updateLine(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ void ModelEdit::addTab(ModelPanel *panel, QString text)
|
||||
panels << panel;
|
||||
QWidget * widget = new QWidget(ui->tabWidget);
|
||||
QVBoxLayout *baseLayout = new QVBoxLayout(widget);
|
||||
panel->update();
|
||||
VerticalScrollArea * area = new VerticalScrollArea(widget, panel);
|
||||
baseLayout->addWidget(area);
|
||||
ui->tabWidget->addTab(widget, text);
|
||||
|
||||
@@ -355,6 +355,8 @@ SetupPanel::SetupPanel(QWidget *parent, ModelData & model, GeneralSettings & gen
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
||||
ui->name->setValidator(new QRegExpValidator(rx, this));
|
||||
ui->name->setMaxLength(IS_TARANIS(firmware->getBoard()) ? 12 : 10);
|
||||
|
||||
if (firmware->getCapability(ModelImage)) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>850</width>
|
||||
<height>521</height>
|
||||
<width>749</width>
|
||||
<height>424</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -252,7 +252,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QGridLayout" name="gridLayout_66" columnstretch="1,0,0,0">
|
||||
<layout class="QGridLayout" name="gridLayout_66" columnstretch="0,0,0,0">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="VarioLabel_1">
|
||||
<property name="sizePolicy">
|
||||
@@ -277,6 +277,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
@@ -302,6 +305,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
@@ -327,6 +333,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@@ -349,6 +358,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@@ -500,21 +512,50 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0">
|
||||
<layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0,0,0,0" columnstretch="1,0,1,0,1">
|
||||
<property name="horizontalSpacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="3" column="1">
|
||||
<widget class="QUnsignedAutoComboBox" name="frskyVoltCB">
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="frskyProtoCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>FrSky Sensor Hub</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Various</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
@@ -530,49 +571,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QUnsignedAutoComboBox" name="frskyCurrentCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<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>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="current_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Current source</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<item row="5" column="1">
|
||||
<widget class="QDoubleSpinBox" name="bladesCount">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
@@ -580,6 +579,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@@ -594,7 +596,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="blades_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
@@ -622,6 +624,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> mAh</string>
|
||||
</property>
|
||||
@@ -638,6 +643,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> A</string>
|
||||
</property>
|
||||
@@ -675,25 +683,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Various</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
@@ -707,24 +696,43 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="frskyProtoCB">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="current_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Current source</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QUnsignedAutoComboBox" name="frskyVoltCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="QUnsignedAutoComboBox" name="frskyCurrentCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>FrSky Sensor Hub</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
@@ -756,19 +764,20 @@
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="rssiLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RSSI</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="rssiAlarm1Label">
|
||||
<property name="sizePolicy">
|
||||
@@ -832,6 +841,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
@@ -909,6 +921,9 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string/>
|
||||
</property>
|
||||
@@ -926,19 +941,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="rssiLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RSSI</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
@@ -1023,7 +1025,6 @@
|
||||
<tabstop>mahCount_SB</tabstop>
|
||||
<tabstop>mahCount_ChkB</tabstop>
|
||||
<tabstop>frskyVoltCB</tabstop>
|
||||
<tabstop>frskyCurrentCB</tabstop>
|
||||
<tabstop>bladesCount</tabstop>
|
||||
<tabstop>customScreens</tabstop>
|
||||
</tabstops>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>276</width>
|
||||
<height>138</height>
|
||||
<height>106</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -21,252 +21,8 @@
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_11" columnstretch="1,1,1,1" columnminimumwidth="0,0,0,0">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_918">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_Max">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max Value</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="alarm1Label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Alarm 1 </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="alarm1LevelCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>----</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Yellow</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Orange</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Red</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QComboBox" name="alarm1GreaterCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string><</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>></string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="alarm2Label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Alarm 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="alarm2LevelCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>----</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Yellow</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Orange</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Red</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QComboBox" name="alarm2GreaterCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string><</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>></string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="RatioSB">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>255.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QDoubleSpinBox" name="CalibSB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-12.800000000000001</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>12.699999999999999</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QDoubleSpinBox" name="alarm1ValueSB">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>255.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QDoubleSpinBox" name="alarm2ValueSB">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>255.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="CalibLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="3">
|
||||
<layout class="QGridLayout" name="gridLayout_11" columnstretch="0,0,0,0,0">
|
||||
<item row="0" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="UnitCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
@@ -321,6 +77,333 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="alarm2Label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Alarm 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,1">
|
||||
<item>
|
||||
<widget class="QComboBox" name="alarm1LevelCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>----</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Yellow</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Orange</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Red</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="alarm1GreaterCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string><</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>></string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="alarm1ValueSB">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>255.000000000000000</double>
|
||||
</property>
|
||||
</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="1" column="0">
|
||||
<widget class="QLabel" name="label_Max">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max Value</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,0,1">
|
||||
<item>
|
||||
<widget class="QComboBox" name="alarm2LevelCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>----</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Yellow</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Orange</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Red</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="alarm2GreaterCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string><</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>></string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="alarm2ValueSB">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>255.000000000000000</double>
|
||||
</property>
|
||||
</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="2" column="0">
|
||||
<widget class="QLabel" name="alarm1Label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Alarm 1 </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_918">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Unit</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="RatioSB">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>255.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QDoubleSpinBox" name="CalibSB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>70</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-12.800000000000001</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>12.699999999999999</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="CalibLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<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>
|
||||
</layout>
|
||||
@@ -329,12 +412,6 @@
|
||||
<tabstop>UnitCB</tabstop>
|
||||
<tabstop>RatioSB</tabstop>
|
||||
<tabstop>CalibSB</tabstop>
|
||||
<tabstop>alarm1LevelCB</tabstop>
|
||||
<tabstop>alarm1GreaterCB</tabstop>
|
||||
<tabstop>alarm1ValueSB</tabstop>
|
||||
<tabstop>alarm2LevelCB</tabstop>
|
||||
<tabstop>alarm2GreaterCB</tabstop>
|
||||
<tabstop>alarm2ValueSB</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
+106
-75
@@ -113,8 +113,17 @@ void PrintDialog::printSetup()
|
||||
str.append(fv(tr("EEprom Size"), QString("%1").arg(firmware->getEepromInterface()->getSize(*g_model))));
|
||||
str.append(fv(tr("Timer1"), getTimerStr(g_model->timers[0]))); //value, mode, count up/down
|
||||
str.append(fv(tr("Timer2"), getTimerStr(g_model->timers[1]))); //value, mode, count up/down
|
||||
str.append(fv(tr("Protocol"), getProtocol(g_model))); //proto, numch, delay,
|
||||
str.append(fv(tr("Pulse Polarity"), g_model->moduleData[0].polarityToString()));
|
||||
if (firmware->getCapability(NumModules)>1) {
|
||||
str.append("<b>"+(IS_TARANIS(firmware->getBoard()) ? tr("Internal Radio System") : tr("Radio System") )+"</b><br> "); //proto, numch, delay,
|
||||
}
|
||||
str.append(fv(tr("Protocol"), getProtocol(g_model->moduleData[0])));
|
||||
if (firmware->getCapability(NumModules)>1) {
|
||||
str.append("<b>"+(IS_TARANIS(firmware->getBoard()) ? tr("External Radio Module") : tr("Extra Radio System"))+"</b><br> "); //proto, numch, delay,
|
||||
str.append(fv(tr("Protocol"), getProtocol(g_model->moduleData[1])));
|
||||
}
|
||||
if (IS_TARANIS(firmware->getBoard())){
|
||||
str.append(fv(tr("Trainer port mode"), getTrainerMode(g_model->trainerMode, g_model->moduleData[2])));
|
||||
}
|
||||
str.append(fv(tr("Throttle Trim"), g_model->thrTrim ? tr("Enabled") : tr("Disabled")));
|
||||
str.append(fv(tr("Trim Increment"), getTrimInc(g_model)));
|
||||
str.append(fv(tr("Center Beep"), getCenterBeepStr(g_model))); // specify which channels beep
|
||||
@@ -130,7 +139,7 @@ void PrintDialog::printSetup()
|
||||
|
||||
QString PrintDialog::printFlightModes()
|
||||
{
|
||||
QString str="";
|
||||
QString str = "";
|
||||
str.append(QString("<table border=1 cellspacing=0 cellpadding=3 width=\"100%\"><tr><td colspan=%1><h2>").arg(!gvars ? 8+firmware->getCapability(RotaryEncoders) : 8+gvars+firmware->getCapability(RotaryEncoders)));
|
||||
str.append(tr("Flight modes"));
|
||||
str.append("</h2></td></tr><tr><td style=\"border-style:none;\"> </td><td colspan=2 align=center><b>");
|
||||
@@ -147,7 +156,7 @@ QString PrintDialog::printFlightModes()
|
||||
QString labels[] = { tr("Rud"), tr("Ele"), tr("Thr"), tr("Ail") }; // TODO is elsewhere for sure
|
||||
for (int i=0; i<4; i++) {
|
||||
GeneralSettings generalSettings = *g_eeGeneral;
|
||||
str.append(QString("<td align=\"center\" nowrap><b>%1</b></td>").arg(labels[CONVERT_MODE(i+1)-1]));
|
||||
str.append(QString("<td align=\"center\" nowrap><b>%1</b></td>").arg((QString)labels[CONVERT_MODE(i+1)-1]));
|
||||
}
|
||||
for (unsigned int i=0; i<gvars; i++) {
|
||||
str.append(QString("<td align=\"center\" nowrap><b>GV%1</b><br>%2</td>").arg(i+1).arg(g_model->gvars_names[i]));
|
||||
@@ -158,38 +167,46 @@ QString PrintDialog::printFlightModes()
|
||||
str.append("</tr>");
|
||||
for (int i=0; i<firmware->getCapability(FlightModes); i++) {
|
||||
FlightModeData *pd=&g_model->flightModeData[i];
|
||||
str.append("<tr><td><b>"+tr("FM")+QString("%1</b> <font size=+1 face='Courier New' color=green>%2</font></td>").arg(i).arg(pd->name));
|
||||
str.append(QString("<td align=\"right\"><font size=+1 face='Courier New' color=green>%1</font></td>").arg((qreal)pd->fadeIn/firmware->getCapability(SlowScale)));
|
||||
str.append(QString("<td width=\"30\" align=\"right\"><font size=+1 face='Courier New' color=green>%1</font></td>").arg((qreal)pd->fadeOut/firmware->getCapability(SlowScale)));
|
||||
str.append("<tr><td valign=\"middle\"><b>"+tr("FM")+QString("%1</b> <font size=+1 face='Courier New' color=green>%2</font></td>").arg(i).arg(pd->name));
|
||||
str.append(QString("<td valign=\"middle\" align=\"right\"><font size=+1 face='Courier New' color=green>%1</font></td>").arg((qreal)pd->fadeIn/firmware->getCapability(SlowScale)));
|
||||
str.append(QString("<td valign=\"middle\" width=\"30\" align=\"right\"><font size=+1 face='Courier New' color=green>%1</font></td>").arg((qreal)pd->fadeOut/firmware->getCapability(SlowScale)));
|
||||
for (int k=0; k<4; k++) {
|
||||
//TODO trim values
|
||||
if (pd->trimRef[k]==-1) {
|
||||
str.append(QString("<td align=\"right\"><font size=+1 face='Courier New' color=green>%1</font></td>").arg(pd->trim[k]));
|
||||
//Almost done trim values
|
||||
if (pd->trimMode[k]==-1) {
|
||||
str.append(QString("<td valign=\"middle\" align=\"center\"><font size=+1 face='Courier New' color=grey>")+tr("Off")+QString("</font></td>"));
|
||||
} else {
|
||||
str.append("<td align=\"right\" ><font size=+1 face='Courier New' color=green>"+tr("FM")+QString("%1</font></td>").arg(pd->trimRef[k]));
|
||||
if (pd->trimRef[k]==i) {
|
||||
str.append("<td valign=\"middle\" align=\"center\" ><font size=+1 face='Courier New' color=green>"+QString("%1").arg(pd->trim[k])+QString("</font></td>"));
|
||||
} else {
|
||||
if (pd->trimMode[k]==0) {
|
||||
str.append("<td valign=\"middle\" align=\"center\" ><font size=+1 face='Courier New' color=green>"+tr("FM")+QString("%1").arg(pd->trimRef[k])+QString("</font></td>"));
|
||||
} else {
|
||||
str.append("<td valign=\"middle\" align=\"center\" ><font size=+1 face='Courier New' color=green>"+tr("FM")+QString("%1+").arg(pd->trimRef[k])+QString("<br>%1").arg(pd->trim[k])+QString("</font></td>"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned int k=0; k<gvars; k++) {
|
||||
if (pd->gvars[k]<=1024) {
|
||||
str.append(QString("<td align=\"right\"><font size=+1 face='Courier New' color=green>%1").arg(pd->gvars[k])+"</font></td>");
|
||||
str.append(QString("<td align=\"right\" valign=\"middle\"><font size=+1 face='Courier New' color=green>%1").arg(pd->gvars[k])+"</font></td>");
|
||||
}
|
||||
else {
|
||||
int num = pd->gvars[k] - 1025;
|
||||
if (num>=i) num++;
|
||||
str.append("<td align=\"right\" ><font size=+1 face='Courier New' color=green>"+tr("FM")+QString("%1</font></td>").arg(num));
|
||||
str.append("<td align=\"right\" valign=\"middle\"><font size=+1 face='Courier New' color=green>"+tr("FM")+QString("%1</font></td>").arg(num));
|
||||
}
|
||||
}
|
||||
for (int k=0; k<firmware->getCapability(RotaryEncoders); k++) {
|
||||
if (pd->rotaryEncoders[k]<=1024) {
|
||||
str.append(QString("<td align=\"right\"><font size=+1 face='Courier New' color=green>%1").arg(pd->rotaryEncoders[k])+"</font></td>");
|
||||
str.append(QString("<td align=\"right\" valign=\"middle\"><font size=+1 face='Courier New' color=green>%1").arg(pd->rotaryEncoders[k])+"</font></td>");
|
||||
}
|
||||
else {
|
||||
int num = pd->rotaryEncoders[k] - 1025;
|
||||
if (num>=i) num++;
|
||||
str.append(QString("<td align=\"right\"><font size=+1 face='Courier New' color=green>")+tr("FM")+QString("%1</font></td>").arg(num));
|
||||
str.append(QString("<td align=\"right\" valign=\"middle\"><font size=+1 face='Courier New' color=green>")+tr("FM")+QString("%1</font></td>").arg(num));
|
||||
}
|
||||
}
|
||||
str.append(QString("<td align=center><font size=+1 face='Courier New' color=green>%1</font></td>").arg(pd->swtch.toString()));
|
||||
str.append(QString("<td align=center valign=\"middle\"><font size=+1 face='Courier New' color=green>%1</font></td>").arg(pd->swtch.toString()));
|
||||
str.append("</tr>");
|
||||
}
|
||||
str.append("</table>");
|
||||
@@ -464,7 +481,7 @@ void PrintDialog::printLimits()
|
||||
|
||||
void PrintDialog::printCurves()
|
||||
{
|
||||
int i,r,g,b,c,count;
|
||||
int i,r,g,b,c,count,usedcurves=0;
|
||||
char buffer[16];
|
||||
QPen pen(Qt::black, 2, Qt::SolidLine);
|
||||
|
||||
@@ -475,27 +492,38 @@ void PrintDialog::printCurves()
|
||||
if (numcurves==0) {
|
||||
numcurves=16;
|
||||
}
|
||||
{
|
||||
QImage qi(ISIZEW+1,ISIZEW+1,QImage::Format_RGB32);
|
||||
QPainter painter(&qi);
|
||||
painter.setBrush(QBrush("#FFFFFF"));
|
||||
painter.setPen(QColor(0,0,0));
|
||||
painter.drawRect(0,0,ISIZEW,ISIZEW);
|
||||
str.append("<table border=0 cellspacing=0 cellpadding=3 width=\"100%\">"+QString("<tr><td width=\"400\"><img src=\"%1\" border=0></td><td><table border=1 cellspacing=0 cellpadding=3 width=\"100%\">").arg(curvefile5));
|
||||
for(i=0; i<numcurves; i++) {
|
||||
pen.setColor(colors[i]);
|
||||
painter.setPen(pen);
|
||||
colors[i].getRgb(&r,&g,&b);
|
||||
c=r;
|
||||
c*=256;
|
||||
c+=g;
|
||||
c*=256;
|
||||
c+=b;
|
||||
sprintf(buffer,"%06x",c);
|
||||
if(i%2 == 0) str.append("<tr>");
|
||||
str.append(QString("<td width=\"70\"><font color=#%1><b>").arg(buffer)+tr("Curve")+QString(" %1</b></font></td>").arg(i+1));
|
||||
if(i%2) str.append("</tr>");
|
||||
|
||||
QImage qi(ISIZEW+1,ISIZEW+1,QImage::Format_RGB32);
|
||||
QPainter painter(&qi);
|
||||
painter.setBrush(QBrush("#FFFFFF"));
|
||||
painter.setPen(QColor(0,0,0));
|
||||
painter.drawRect(0,0,ISIZEW,ISIZEW);
|
||||
str.append("<table border=0 cellspacing=0 cellpadding=3 width=\"100%\">"+QString("<tr><td width=\"400\"><img src=\"%1\" border=0></td><td><table border=1 cellspacing=0 cellpadding=3 width=\"100%\">").arg(curvefile5));
|
||||
for(i=0; i<numcurves; i++) {
|
||||
pen.setColor(colors[usedcurves]);
|
||||
painter.setPen(pen);
|
||||
colors[usedcurves].getRgb(&r,&g,&b);
|
||||
c=r;
|
||||
c*=256;
|
||||
c+=g;
|
||||
c*=256;
|
||||
c+=b;
|
||||
sprintf(buffer,"%06x",c);
|
||||
int curvepoints=g_model->curves[i].count;
|
||||
count=0;
|
||||
for(int j=0; j<curvepoints; j++) {
|
||||
if (g_model->curves[i].points[j].y!=0)
|
||||
count++;
|
||||
}
|
||||
if ((count>0) || (g_model->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)|| (g_model->curves[i].count !=5)) {
|
||||
if(usedcurves%2 == 0) str.append("<tr>");
|
||||
str.append(QString("<td width=\"70\"><font color=#%1><b>").arg(buffer)+tr("Curve")+QString(" %1</b></font></td>").arg(i+1));
|
||||
if(usedcurves%2) str.append("</tr>");
|
||||
usedcurves++;
|
||||
}
|
||||
}
|
||||
if (!(usedcurves%2)) str.append("</tr>");
|
||||
if (usedcurves!=0) {
|
||||
str.append("</table></td></tr><tr><td colspan=2><table border=1 cellspacing=0 cellpadding=3 width=\"100%\">");
|
||||
str.append("<tr>");
|
||||
str.append(doTC(" "));
|
||||
@@ -509,48 +537,50 @@ void PrintDialog::printCurves()
|
||||
str.append(doTC(tr("pt %1").arg(i+1), "", true));
|
||||
str.append("</tr>");
|
||||
for(i=0; i<numcurves; i++) {
|
||||
pen.setColor(colors[i]);
|
||||
painter.setPen(pen);
|
||||
colors[i].getRgb(&r,&g,&b);
|
||||
c=r;
|
||||
c*=256;
|
||||
c+=g;
|
||||
c*=256;
|
||||
c+=b;
|
||||
sprintf(buffer,"%06x",c);
|
||||
str.append("<tr>");
|
||||
int curvepoints=g_model->curves[i].count;
|
||||
if (g_model->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)
|
||||
str.append(QString("<td width=\"70\" rowspan=2 valign=middle><font color=#%1><b>").arg(buffer)+tr("Curve")+QString(" %1</b></font></td><td width=5>Y</td>").arg(i+1));
|
||||
else
|
||||
str.append(QString("<td width=\"70\"><font color=#%1><b>").arg(buffer)+tr("Curve")+QString(" %1</b></font></td><td width=5>Y</td>").arg(i+1));
|
||||
count=0;
|
||||
for(int j=0; j<curvepoints; j++) {
|
||||
if (g_model->curves[i].points[j].y!=0)
|
||||
count++;
|
||||
}
|
||||
for(int j=0; j<curvepoints; j++) {
|
||||
str.append(doTR(QString::number(g_model->curves[i].points[j].y),"green"));
|
||||
if (j>0 && count!=0) {
|
||||
if (g_model->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)
|
||||
painter.drawLine(ISIZEW/2+(ISIZEW*g_model->curves[i].points[j-1].x)/200,ISIZEW/2-(ISIZEW*g_model->curves[i].points[j-1].y)/200,ISIZEW/2+(ISIZEW*g_model->curves[i].points[j].x)/200,ISIZEW/2-(ISIZEW*g_model->curves[i].points[j].y)/200);
|
||||
else
|
||||
painter.drawLine(ISIZEW*(j-1)/(curvepoints-1),ISIZEW/2-(ISIZEW*g_model->curves[i].points[j-1].y)/200,ISIZEW*(j)/(curvepoints-1),ISIZEW/2-(ISIZEW*g_model->curves[i].points[j].y)/200);
|
||||
}
|
||||
}
|
||||
for(int j=curvepoints; j<numpoint; j++) {
|
||||
str.append(doTR("","green"));
|
||||
}
|
||||
str.append("</tr>");
|
||||
if (g_model->curves[i].type == CurveData::CURVE_TYPE_CUSTOM) {
|
||||
str.append("<tr><td width=5>X</td>");
|
||||
if ((count>0) || (g_model->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)) {
|
||||
pen.setColor(colors[i]);
|
||||
painter.setPen(pen);
|
||||
colors[i].getRgb(&r,&g,&b);
|
||||
c=r;
|
||||
c*=256;
|
||||
c+=g;
|
||||
c*=256;
|
||||
c+=b;
|
||||
sprintf(buffer,"%06x",c);
|
||||
str.append("<tr>");
|
||||
if (g_model->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)
|
||||
str.append(QString("<td width=\"70\" rowspan=2 valign=middle><font color=#%1><b>").arg(buffer)+tr("Curve")+QString(" %1</b></font></td><td width=5>Y</td>").arg(i+1));
|
||||
else
|
||||
str.append(QString("<td width=\"70\"><font color=#%1><b>").arg(buffer)+tr("Curve")+QString(" %1</b></font></td><td width=5>Y</td>").arg(i+1));
|
||||
for(int j=0; j<curvepoints; j++) {
|
||||
str.append(doTR(QString::number(g_model->curves[i].points[j].x),"green"));
|
||||
str.append(doTR(QString::number(g_model->curves[i].points[j].y),"green"));
|
||||
if (j>0 && (count!=0 ||(g_model->curves[i].type == CurveData::CURVE_TYPE_CUSTOM))) {
|
||||
if (g_model->curves[i].type == CurveData::CURVE_TYPE_CUSTOM)
|
||||
painter.drawLine(ISIZEW/2+(ISIZEW*g_model->curves[i].points[j-1].x)/200,ISIZEW/2-(ISIZEW*g_model->curves[i].points[j-1].y)/200,ISIZEW/2+(ISIZEW*g_model->curves[i].points[j].x)/200,ISIZEW/2-(ISIZEW*g_model->curves[i].points[j].y)/200);
|
||||
else
|
||||
painter.drawLine(ISIZEW*(j-1)/(curvepoints-1),ISIZEW/2-(ISIZEW*g_model->curves[i].points[j-1].y)/200,ISIZEW*(j)/(curvepoints-1),ISIZEW/2-(ISIZEW*g_model->curves[i].points[j].y)/200);
|
||||
}
|
||||
}
|
||||
for(int j=curvepoints; j<numpoint; j++) {
|
||||
str.append(doTR("","green"));
|
||||
}
|
||||
str.append("</tr>");
|
||||
str.append("</tr>");
|
||||
if (g_model->curves[i].type == CurveData::CURVE_TYPE_CUSTOM) {
|
||||
str.append("<tr><td width=5>X</td>");
|
||||
for(int j=0; j<curvepoints; j++) {
|
||||
str.append(doTR(QString::number(g_model->curves[i].points[j].x),"green"));
|
||||
}
|
||||
for(int j=curvepoints; j<numpoint; j++) {
|
||||
str.append(doTR("","green"));
|
||||
}
|
||||
str.append("</tr>");
|
||||
}
|
||||
}
|
||||
}
|
||||
str.append("</table></td></tr></table></td></tr></table>");
|
||||
@@ -562,11 +592,9 @@ void PrintDialog::printCurves()
|
||||
painter.drawLine(ISIZEW/2-5,(ISIZEW*i)/(20),ISIZEW/2+5,(ISIZEW*i)/(20));
|
||||
painter.drawLine((ISIZEW*i)/(20),ISIZEW/2-5,(ISIZEW*i)/(20),ISIZEW/2+5);
|
||||
}
|
||||
|
||||
qi.save(curvefile5, "png",100);
|
||||
|
||||
te->append(str);
|
||||
}
|
||||
te->append(str);
|
||||
}
|
||||
|
||||
void PrintDialog::printSwitches()
|
||||
@@ -662,6 +690,10 @@ void PrintDialog::printFrSky()
|
||||
{
|
||||
int tc=0;
|
||||
QString str = "<table border=1 cellspacing=0 cellpadding=3 width=\"100%\">";
|
||||
int analog=2;
|
||||
if (IS_ARM(firmware->getBoard())) {
|
||||
analog=4;
|
||||
}
|
||||
|
||||
if (IS_TARANIS(GetEepromInterface()->getBoard())) {
|
||||
str.append("<tr><td colspan=3><h2>"+tr("Telemetry Settings")+"</h2></td></tr>");
|
||||
@@ -670,9 +702,8 @@ void PrintDialog::printFrSky()
|
||||
str.append(doTC(tr("Range"),"", true));
|
||||
str.append(doTC(tr("Offset"),"", true));
|
||||
str.append("</tr>");
|
||||
|
||||
FrSkyData *fd=&g_model->frsky;
|
||||
for (int i=0; i<2; i++) {
|
||||
for (int i=0; i<analog; i++) {
|
||||
if (fd->channels[i].ratio!=0) {
|
||||
tc++;
|
||||
float ratio=(fd->channels[i].ratio/(fd->channels[i].type==0 ?10.0:1));
|
||||
@@ -722,7 +753,7 @@ void PrintDialog::printFrSky()
|
||||
str.append("<td width=\"40\" align=\"center\"><b>"+tr("Type")+"</b></td><td width=\"40\" align=\"center\"><b>"+tr("Condition")+"</b></td><td width=\"40\" align=\"center\"><b>"+tr("Value")+"</b></td>");
|
||||
str.append("<td width=\"40\" align=\"center\"><b>"+tr("Type")+"</b></td><td width=\"40\" align=\"center\"><b>"+tr("Condition")+"</b></td><td width=\"40\" align=\"center\"><b>"+tr("Value")+"</b></td></tr>");
|
||||
FrSkyData *fd=&g_model->frsky;
|
||||
for (int i=0; i<2; i++) {
|
||||
for (int i=0; i<analog; i++) {
|
||||
if (fd->channels[i].ratio!=0) {
|
||||
tc++;
|
||||
float ratio=(fd->channels[i].ratio/(fd->channels[i].type==0 ?10.0:1));
|
||||
@@ -746,7 +777,7 @@ void PrintDialog::printFrSky()
|
||||
str.append("<td width=\"40\" align=\"center\"><b>"+getFrSkyAlarmType(fd->rssiAlarms[1].level)+"</b></td><td width=\"40\" align=\"center\"><b><</b></td><td width=\"40\" align=\"center\"><b>"+QString::number(fd->rssiAlarms[1].value,10)+"</b></td></tr>");
|
||||
str.append("<tr><td colspan=10 align=\"Left\" height=\"4px\"></td></tr>");
|
||||
str.append("<tr><td colspan=2 align=\"Left\"><b>"+tr("Frsky serial protocol")+"</b></td><td colspan=8 align=\"left\">"+getFrSkyProtocol(fd->usrProto)+"</td></tr>");
|
||||
str.append("<tr><td colspan=2 align=\"Left\"><b>"+tr("Blades")+"</b></td><td colspan=8 align=\"left\">"+fd->blades+"</td></tr>");
|
||||
str.append("<tr><td colspan=2 align=\"Left\"><b>"+tr("Blades")+"</b></td><td colspan=8 align=\"left\">"+QString("%1").arg(fd->blades)+"</td></tr>");
|
||||
str.append("<tr><td colspan=10 align=\"Left\" height=\"4px\"></td></tr></table>");
|
||||
}
|
||||
#if 0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
set(qcustomplot_SRCS
|
||||
qcustomplot.cpp
|
||||
)
|
||||
|
||||
set(qcustomplot_HDRS
|
||||
qcustomplot.h
|
||||
)
|
||||
|
||||
qt4_wrap_cpp(qcustomplot_SRCS ${qcustomplot_HDRS})
|
||||
|
||||
add_library(qcustomplot ${qcustomplot_SRCS})
|
||||
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
@@ -0,0 +1,395 @@
|
||||
#### Version 1.3.0 released on 27.12.14 ####
|
||||
|
||||
Added features:
|
||||
- New plottable class QCPFinancial allows display of candlestick/ohlc data
|
||||
- New class QCPBarsGroup allows horizontal grouping of multiple QCPBars plottables
|
||||
- Added QCPBars feature allowing non-zero base values (see property QCPBars::setBaseValue)
|
||||
- Added QCPBars width type, for more flexible bar widths (see property QCPBars::setWidthType)
|
||||
- New QCPCurve optimization algorithm, fixes bug which caused line flicker at deep zoom into curve segment
|
||||
- Item positions can now have different position types and anchors for their x and y coordinates (QCPItemPosition::setTypeX/Y, setParentAnchorX/Y)
|
||||
- QCPGraph and QCPCurve can now display gaps in their lines, when inserting quiet NaNs as values (std::numeric_limits<double>::quiet_NaN())
|
||||
- QCPAxis now supports placing the tick labels inside the axis rect, for particularly space saving plots (QCPAxis::setTickLabelSide)
|
||||
Added features after beta:
|
||||
- Made code compatible with QT_NO_CAST_FROM_ASCII, QT_NO_CAST_TO_ASCII
|
||||
- Added compatibility with QT_NO_KEYWORDS after sending code files through a simple reg-ex script
|
||||
- Added possibility to inject own QCPAxis(-subclasses) via second, optional QCPAxisRect::addAxis parameter
|
||||
- Added parameter to QCPItemPixmap::setScaled to specify transformation mode
|
||||
|
||||
Bugfixes:
|
||||
- Fixed bug in QCPCurve rendering of very zoomed-in curves (via new optimization algorithm)
|
||||
- Fixed conflict with MSVC-specific keyword "interface" in text-document-integration example
|
||||
- Fixed QCPScatterStyle bug ignoring the specified pen in the custom scatter shape constructor
|
||||
- Fixed bug (possible crash) during QCustomPlot teardown, when a QCPLegend that has no parent layout (i.e. was removed from layout manually) gets deleted
|
||||
Bugfixes after beta:
|
||||
- Fixed bug of QCPColorMap/QCPColorGradient colors being off by one color sampling step (only noticeable in special cases)
|
||||
- Fixed bug of QCPGraph adaptive sampling on vertical key axis, causing staggered look
|
||||
- Fixed low (float) precision in QCPCurve optimization algorithm, by not using QVector2D anymore
|
||||
|
||||
Other:
|
||||
- Qt 5.3 and Qt 5.4 compatibility
|
||||
|
||||
#### Version 1.2.1 released on 07.04.14 ####
|
||||
|
||||
Bugfixes:
|
||||
- Fixed regression which garbled date-time tick labels on axes, if setTickLabelType is ltDateTime and setNumberFormat contains the "b" option
|
||||
|
||||
#### Version 1.2.0 released on 14.03.14 ####
|
||||
|
||||
Added features:
|
||||
- Adaptive Sampling for QCPGraph greatly improves performance for high data densities (see QCPGraph::setAdaptiveSampling)
|
||||
- QCPColorMap plottable with QCPColorScale layout element allows plotting of 2D color maps
|
||||
- QCustomPlot::savePdf now has additional optional parameters pdfCreator and pdfTitle to set according PDF metadata fields
|
||||
- QCustomPlot::replot now allows specifying whether the widget update is immediate (repaint) or queued (update)
|
||||
- QCPRange operators +, -, *, / with double operand for range shifting and scaling, and ==, != for range comparison
|
||||
- Layers now have a visibility property (QCPLayer::setVisible)
|
||||
- static functions QCPAxis::opposite and QCPAxis::orientation now offer more convenience when handling axis types
|
||||
- added notification signals for selectability change (selectableChanged) on all objects that have a selected/selectable property
|
||||
- added notification signal for QCPAxis scaleType property
|
||||
- added notification signal QCPLayerable::layerChanged
|
||||
|
||||
Bugfixes:
|
||||
- Fixed assert halt, when QCPAxis auto tick labels not disabled but nevertheless a custom non-number tick label ending in "e" given
|
||||
- Fixed painting glitches when QCustomPlot resized inside a QMdiArea or under certain conditions inside a QLayout
|
||||
- If changing QCPAxis::scaleType and thus causing range sanitizing and a range modification, rangeChanged wouldn't be emitted
|
||||
- Fixed documentation bug that caused indentation to be lost in code examples
|
||||
Bugfixes after beta:
|
||||
- Fixed bug that caused crash if clicked-on legend item is removed in mousePressEvent.
|
||||
- On some systems, font size defaults to -1, which used to cause a debug output in QCPAxisPainterPrivate::TickLabelDataQCP. Now it's checked before setting values based on the default font size.
|
||||
- When using multiple axes on one side, setting one to invisible didn't properly compress the freed space.
|
||||
- Fixed bug that allowed selection of plottables when clicking in the bottom or top margin of a QCPAxisRect (outside the inner rect)
|
||||
|
||||
Other:
|
||||
- In method QCPAbstractPlottable::getKeyRange/getValueRange, renamed parameter "validRange" to "foundRange", to better reflect its meaning (and contrast it from QCPRange::validRange)
|
||||
- QCPAxis low-level axis painting methods exported to QCPAxisPainterPrivate
|
||||
|
||||
#### Version 1.1.1 released on 09.12.13 ####
|
||||
|
||||
Bugfixes:
|
||||
- Fixed bug causing legends blocking input events from reaching underlying axis rect even if legend is invisible
|
||||
- Added missing Q_PROPERTY for QCPAxis::setDateTimeSpec
|
||||
- Fixed behaviour of QCPAxisRect::setupFullAxesBox (now transfers more properties from bottom/left to top/right axes and sets visibility of bottom/left axes to true)
|
||||
- Made sure PDF export doesn't default to grayscale output on some systems
|
||||
|
||||
Other:
|
||||
- Plotting hint QCP::phForceRepaint is now enabled on all systems (and not only on windows) by default
|
||||
- Documentation improvements
|
||||
|
||||
#### Version 1.1.0 released on 04.11.13 ####
|
||||
|
||||
Added features:
|
||||
- Added QCPRange::expand and QCPRange::expanded
|
||||
- Added QCPAxis::rescale to rescale axis to all associated plottables
|
||||
- Added QCPAxis::setDateTimeSpec/dateTimeSpec to allow axis labels either in UTC or local time
|
||||
- QCPAxis now additionally emits a rangeChanged signal overload that provides the old range as second parameter
|
||||
|
||||
Bugfixes:
|
||||
- Fixed QCustomPlot::rescaleAxes not rescaling properly if first plottable has an empty range
|
||||
- QCPGraph::rescaleAxes/rescaleKeyAxis/rescaleValueAxis are no longer virtual (never were in base class, was a mistake)
|
||||
- Fixed bugs in QCPAxis::items and QCPAxisRect::items not properly returning associated items and potentially stalling
|
||||
|
||||
Other:
|
||||
- Internal change from QWeakPointer to QPointer, thus got rid of deprecated Qt functionality
|
||||
- Qt5.1 and Qt5.2 (beta1) compatibility
|
||||
- Release packages now extract to single subdirectory and don't place multiple files in current working directory
|
||||
|
||||
#### Version 1.0.1 released on 05.09.13 ####
|
||||
|
||||
Bugfixes:
|
||||
- using define flag QCUSTOMPLOT_CHECK_DATA caused debug output when data was correct, instead of invalid (fixed QCP::isInvalidData)
|
||||
- documentation images are now properly shown when viewed with Qt Assistant
|
||||
- fixed various documentation mistakes
|
||||
|
||||
Other:
|
||||
- Adapted documentation style sheet to better match Qt5 documentation
|
||||
|
||||
#### Version 1.0.0 released on 01.08.13 ####
|
||||
|
||||
Quick Summary:
|
||||
- Layout system for multiple axis rects in one plot
|
||||
- Multiple axes per side
|
||||
- Qt5 compatibility
|
||||
- More flexible and consistent scatter configuration with QCPScatterStyle
|
||||
- Various interface cleanups/refactoring
|
||||
- Pixmap-cached axis labels for improved replot performance
|
||||
|
||||
Changes that break backward compatibility:
|
||||
- QCustomPlot::axisRect() changed meaning due to the extensive changes to how axes and axis rects are handled
|
||||
it now returns a pointer to a QCPAxisRect and takes an integer index as parameter.
|
||||
- QCPAxis constructor changed to now take QCPAxisRect* as parent
|
||||
- setAutoMargin, setMarginLeft/Right/Top/Bottom removed due to the axis rect changes (see QCPAxisRect::setMargins/setAutoMargins)
|
||||
- setAxisRect removed due to the axis rect changes
|
||||
- setAxisBackground(-Scaled/-ScaledMode) now moved to QCPAxisRect as setBackground(-Scaled/ScaledMode) (access via QCustomPlot::axisRects())
|
||||
- QCPLegend now is a QCPLayoutElement
|
||||
- QCPAbstractPlottable::drawLegendIcon parameter "rect" changed from QRect to QRectF
|
||||
- QCPAbstractLegendItem::draw second parameter removed (position/size now handled via QCPLayoutElement base class)
|
||||
- removed QCPLegend::setMargin/setMarginLeft/Right/Top/Bottom (now inherits the capability from QCPLayoutElement::setMargins)
|
||||
- removed QCPLegend::setMinimumSize (now inherits the capability from QCPLayoutElement::setMinimumSize)
|
||||
- removed enum QCPLegend::PositionStyle, QCPLegend::positionStyle/setPositionStyle/position/setPosition (replaced by capabilities of QCPLayoutInset)
|
||||
- QCPLegend transformed to work with new layout system (almost everything changed)
|
||||
- removed entire title interface: QCustomPlot::setTitle/setTitleFont/setTitleColor/setTitleSelected/setTitleSelectedFont/setTitleSelectedColor and
|
||||
the QCustomPlot::iSelectTitle interaction flag (all functionality is now given by the layout element "QCPPlotTitle" which can be added to the plot layout)
|
||||
- selectTest functions now take two additional parameters: bool onlySelectable and QVariant *details=0
|
||||
- selectTest functions now ignores visibility of objects and (if parameter onlySelectable is true) does not anymore ignore selectability of the object
|
||||
- moved QCustomPlot::Interaction/Interactions to QCP namespace as QCP::Interaction/Interactions
|
||||
- moved QCustomPlot::setupFullAxesBox() to QCPAxisRect::setupFullAxesBox. Now also accepts parameter to decide whether to connect opposite axis ranges
|
||||
- moved range dragging/zooming interface from QCustomPlot to QCPAxisRect (setRangeDrag, setRangeZoom, setRangeDragAxes, setRangeZoomAxes,...)
|
||||
- rangeDrag/Zoom is now set to Qt::Horizontal|Qt::Vertical instead of 0 by default, on the other hand, iRangeDrag/Zoom is unset in interactions by
|
||||
default (this makes enabling dragging/zooming easier by just adding the interaction flags)
|
||||
- QCPScatterStyle takes over everything related to handling scatters in all plottables
|
||||
- removed setScatterPen/Size on QCPGraph and QCPCurve, removed setOutlierPen/Size on QCPStatisticalBox (now handled via QCPScatterStyle)
|
||||
- modified setScatterStyle on QCPGraph and QCPCurve, and setOutlierStyle on QCPStatisticalBox, to take QCPScatterStyle
|
||||
- axis grid and subgrid are now reachable via the QCPGrid *QCPAxis::grid() method. (e.g. instead of xAxis->setGrid(true), write xAxis->grid()->setVisible(true))
|
||||
|
||||
Added features:
|
||||
- Axis tick labels are now pixmap-cached, thus increasing replot performance (in usual setups by about 24%). See plotting hint phCacheLabels which is set by default
|
||||
- Advanced layout system, including the classes QCPLayoutElement, QCPLayout, QCPLayoutGrid, QCPLayoutInset, QCPAxisRect
|
||||
- QCustomPlot::axisRects() returns all the axis rects in the QCustomPlot.
|
||||
- QCustomPlot::plotLayout() returns the top level layout (initially a QCPLayoutGrid with one QCPAxisRect inside)
|
||||
- QCPAxis now may have an offset to the axis rect (setOffset)
|
||||
- Multiple axes per QCPAxisRect side are now supported (see QCPAxisRect::addAxis)
|
||||
- QCustomPlot::toPixmap renders the plot into a pixmap and returns it
|
||||
- When setting tick label rotation to +90 or -90 degrees on a vertical axis, the labels are now centered vertically on the tick height
|
||||
(This allows space saving vertical tick labels by having the text direction parallel to the axis)
|
||||
- Substantially increased replot performance when using very large manual tick vectors (> 10000 ticks) via QCPAxis::setTickVector
|
||||
- QCPAxis and QCPAxisRect now allow easy access to all plottables(), graphs() and items() that are associated with them
|
||||
- Added QCustomPlot::hasItem method for consistency with plottable interface, hasPlottable
|
||||
- Added QCPAxisRect::setMinimumMargins as replacement for hardcoded minimum axis margin (15 px) when auto margin is enabled
|
||||
- Added Flags type QCPAxis::AxisTypes (from QCPAxis::AxisType), used in QCPAxisRect interface
|
||||
- Automatic margin calculation can now be enabled/disabled on a per-side basis, see QCPAxisRect::setAutoMargins
|
||||
- QCPAxisRect margins of multiple axis rects can be coupled via QCPMarginGroup
|
||||
- Added new default layers "background" and "legend" (QCPAxisRect draws its background on the "background" layer, QCPLegend is on the "legend" layer by default)
|
||||
- Custom scatter style via QCP::ssCustom and respective setCustomScatter functions that take a QPainterPath
|
||||
- Filled scatters via QCPScatterStyle::setBrush
|
||||
Added features after beta:
|
||||
- Added QCustomPlot::toPainter method, to allow rendering with existing painter
|
||||
- QCPItemEllipse now provides a center anchor
|
||||
|
||||
Bugfixes:
|
||||
- Fixed compile error on ARM
|
||||
- Wrong legend icons were displayed if using pixmaps for scatters that are smaller than the legend icon rect
|
||||
- Fixed clipping inaccuracy for rotated tick labels (were hidden too early, because the non-rotated bounding box was used)
|
||||
- Fixed bug that caused wrong clipping of axis ticks and subticks when the ticks were given manually by QCPAxis::setTickVector
|
||||
- Fixed Qt5 crash when dragging graph out of view (iterator out of bounds in QCPGraph::getVisibleDataBounds)
|
||||
- Fixed QCPItemText not scaling properly when using scaled raster export
|
||||
Bugfixes after beta:
|
||||
- Fixed bug that clipped the rightmost pixel column of tick labels when caching activated (only visible on windows for superscript exponents)
|
||||
- Restored compatibility to Qt4.6
|
||||
- Restored support for -no-RTTI compilation
|
||||
- Empty manual tick labels are handled more gracefully (no QPainter qDebug messages anymore)
|
||||
- Fixed type ambiguity in QCPLineEnding::draw causing compile error on ARM
|
||||
- Fixed bug of grid layouts not propagating the minimum size from their child elements to the parent layout correctly
|
||||
- Fixed bug of child elements (e.g. axis rects) of inset layouts not properly receiving mouse events
|
||||
|
||||
Other:
|
||||
- Opened up non-amalgamated project structure to public via git repository
|
||||
|
||||
#### Version released on 09.06.12 ####
|
||||
|
||||
Quick Summary:
|
||||
- Items (arrows, text,...)
|
||||
- Layers (easier control over rendering order)
|
||||
- New antialiasing system (Each objects controls own antialiasing with setAntialiased)
|
||||
- Performance Improvements
|
||||
- improved pixel-precise drawing
|
||||
- easier shared library creation/usage
|
||||
|
||||
Changes that (might) break backward compatibility:
|
||||
- enum QCPGraph::ScatterSymbol was moved to QCP namespace (now QCP::ScatterSymbol).
|
||||
This replace should fix your code: "QCPGraph::ss" -> "QCP::ss"
|
||||
- enum QCustomPlot::AntialiasedElement and flag QCustomPlot::AntialiasedElements was moved to QCP namespace
|
||||
This replace should fix your code: "QCustomPlot::ae" -> "QCP::ae"
|
||||
- the meaning of QCustomPlot::setAntialiasedElements has changed slightly: It is now an override to force elements to be antialiased. If you want to force
|
||||
elements to not be drawn antialiased, use the new setNotAntialiasedElements. If an element is mentioned in neither of those functions, it now controls
|
||||
its antialiasing itself via its "setAntialiased" function(s). (e.g. QCPAxis::setAntialiased(bool), QCPAbstractPlottable::setAntialiased(bool),
|
||||
QCPAbstractPlottable::setAntialiasedScatters(bool), etc.)
|
||||
- QCPAxis::setTickVector and QCPAxis::setTickVectorLabels no longer take a pointer but a const reference of the respective QVector as parameter.
|
||||
(handing over a pointer didn't give any noticeable performance benefits but was inconsistent with the rest of the interface)
|
||||
- Equally QCPAxis::tickVector and QCPAxis::tickVectorLabels don't return by pointer but by value now
|
||||
- QCustomPlot::savePngScaled was removed, its purpose is now included as optional parameter "scale" of savePng.
|
||||
- If you have derived from QCPAbstractPlottable: all selectTest functions now consistently take the argument "const QPointF &pos" which is the test point in pixel coordinates.
|
||||
(the argument there was "double key, double value" in plot coordinates, before).
|
||||
- QCPAbstractPlottable, QCPAxis and QCPLegend now inherit from QCPLayerable
|
||||
- If you have derived from QCPAbstractPlottable: the draw method signature has changed from "draw (..) const" to "draw (..)", i.e. the method
|
||||
is not const anymore. This allows the draw function of your plottable to perform buffering/caching operations, if necessary.
|
||||
|
||||
Added features:
|
||||
- Item system: QCPAbstractItem, QCPItemAnchor, QCPItemPosition, QCPLineEnding. Allows placing of lines, arrows, text, pixmaps etc.
|
||||
- New Items: QCPItemStraightLine, QCPItemLine, QCPItemCurve, QCPItemEllipse, QCPItemRect, QCPItemPixmap, QCPItemText, QCPItemBracket, QCPItemTracer
|
||||
- QCustomPlot::addItem/itemCount/item/removeItem/selectedItems
|
||||
- signals QCustomPlot::itemClicked/itemDoubleClicked
|
||||
- the QCustomPlot interactions property now includes iSelectItems (for selection of QCPAbstractItem)
|
||||
- QCPLineEnding. Represents the different styles a line/curve can end (e.g. different arrows, circle, square, bar, etc.), see e.g. QCPItemCurve::setHead
|
||||
- Layer system: QCPLayerable, QCPLayer. Allows more sophisticated control over drawing order and a kind of grouping.
|
||||
- QCPAbstractPlottable, QCPAbstractItem, QCPAxis, QCPGrid, QCPLegend are layerables and derive from QCPLayerable
|
||||
- QCustomPlot::addLayer/moveLayer/removeLayer/setCurrentLayer/layer/currentLayer/layerCount
|
||||
- Initially there are three layers: "grid", "main", and "axes". The "main" layer is initially empty and set as current layer, so new plottables/items are put there.
|
||||
- QCustomPlot::viewport now makes the previously inaccessible viewport rect read-only-accessible (needed that for item-interface)
|
||||
- PNG export now allows transparent background by calling QCustomPlot::setColor(Qt::transparent) before savePng
|
||||
- QCPStatisticalBox outlier symbols may now be all scatter symbols, not only hardcoded circles.
|
||||
- perfect precision of scatter symbol/error bar drawing and clipping in both antialiased and non-antialiased mode, by introducing QCPPainter
|
||||
that works around some QPainter bugs/inconveniences. Further, more complex symbols like ssCrossSquare used to look crooked, now they look good.
|
||||
- new antialiasing control system: Each drawing element now has its own "setAntialiased" function to control whether it is drawn antialiased.
|
||||
- QCustomPlot::setAntialiasedElements and QCustomPlot::setNotAntialiasedElements can be used to override the individual settings.
|
||||
- Subclasses of QCPAbstractPlottable can now use the convenience functions like applyFillAntialiasingHint or applyScattersAntialiasingHint to
|
||||
easily make their drawing code comply with the overall antialiasing system.
|
||||
- QCustomPlot::setNoAntialiasingOnDrag allows greatly improved performance and responsiveness by temporarily disabling all antialiasing while
|
||||
the user is dragging axis ranges
|
||||
- QCPGraph can now show scatter symbols at data points and hide its line (see QCPGraph::setScatterStyle, setScatterSize, setScatterPixmap, setLineStyle)
|
||||
- Grid drawing code was sourced out from QCPAxis to QCPGrid. QCPGrid is mainly an internal class and every QCPAxis owns one. The grid interface still
|
||||
works through QCPAxis and hasn't changed. The separation allows the grid to be drawn on a different layer as the axes, such that e.g. a graph can
|
||||
be above the grid but below the axes.
|
||||
- QCustomPlot::hasPlottable(plottable), returns whether the QCustomPlot contains the plottable
|
||||
- QCustomPlot::setPlottingHint/setPlottingHints, plotting hints control details about the plotting quality/speed
|
||||
- export to jpg and bmp added (QCustomPlot::saveJpg/saveBmp), as well as control over compression quality for png and jpg
|
||||
- multi-select-modifier may now be specified with QCustomPlot::setMultiSelectModifier and is not fixed to Ctrl anymore
|
||||
|
||||
Bugfixes:
|
||||
- fixed QCustomPlot ignores replot after it had size (0,0) even if size becomes valid again
|
||||
- on Windows, a repaint used to be delayed during dragging/zooming of a complex plot, until the drag operation was done.
|
||||
This was fixed, i.e. repaints are forced after a replot() call. See QCP::phForceRepaint and setPlottingHints.
|
||||
- when using the raster paintengine and exporting to scaled PNG, pen widths are now scaled correctly (QPainter bug workaround via QCPPainter)
|
||||
- PDF export now respects QCustomPlot background color (QCustomPlot::setColor), also Qt::transparent
|
||||
- fixed a bug on QCPBars and QCPStatisticalBox where auto-rescaling of axis would fail when all data is very small (< 1e-11)
|
||||
- fixed mouse event propagation bug that prevented range dragging from working on KDE (GNU/Linux)
|
||||
- fixed a compiler warning on 64-bit systems due to pointer cast to int instead of quintptr in a qDebug output
|
||||
|
||||
Other:
|
||||
- Added support for easier shared library creation (including examples for compiling and using QCustomPlot as shared library)
|
||||
- QCustomPlot now has the Qt::WA_OpaquePaintEvent widget attribute (gives slightly improved performance).
|
||||
- QCP::aeGraphs (enum QCP::AntialiasedElement, previously QCustomPlot::aeGraphs) has been marked deprecated since version 02.02.12 and
|
||||
was now removed. Use QCP::aePlottables instead.
|
||||
- optional performance-quality-tradeoff for solid graph lines (see QCustomPlot::setPlottingHints).
|
||||
- marked data classes and QCPRange as Q_MOVABLE_TYPE
|
||||
- replaced usage of own macro FUNCNAME with Qt macro Q_FUNC_INFO
|
||||
- QCustomPlot now returns a minimum size hint of 50*50
|
||||
|
||||
#### Version released on 31.03.12 ####
|
||||
|
||||
Changes that (might) break backward compatibility:
|
||||
- QCPAbstractLegendItem now inherits from QObject
|
||||
- mousePress, mouseMove and mouseRelease signals are now emitted before and not after any QCustomPlot processing (range dragging, selecting, etc.)
|
||||
|
||||
Added features:
|
||||
- Interaction system: now allows selecting of objects like plottables, axes, legend and plot title, see QCustomPlot::setInteractions documentation
|
||||
- Interaction system for plottables:
|
||||
- setSelectable, setSelected, setSelectedPen, setSelectedBrush, selectTest on QCPAbstractPlottable and all derived plottables
|
||||
- setSelectionTolerance on QCustomPlot
|
||||
- selectedPlottables and selectedGraphs on QCustomPlot (returns the list of currently selected plottables/graphs)
|
||||
- Interaction system for axes:
|
||||
- setSelectable, setSelected, setSelectedBasePen, setSelectedTickPen, setSelectedSubTickPen, setSelectedLabelFont, setSelectedTickLabelFont,
|
||||
setSelectedLabelColor, setSelectedTickLabelColor, selectTest on QCPAxis
|
||||
- selectedAxes on QCustomPlot (returns a list of the axes that currently have selected parts)
|
||||
- Interaction system for legend:
|
||||
- setSelectable, setSelected, setSelectedBorderPen, setSelectedIconBorderPen, setSelectedBrush, setSelectedFont, setSelectedTextColor, selectedItems on QCPLegend
|
||||
- setSelectedFont, setSelectedTextColor, setSelectable, setSelected on QCPAbstractLegendItem
|
||||
- selectedLegends on QCustomPlot
|
||||
- Interaction system for title:
|
||||
- setSelectedTitleFont, setSelectedTitleColor, setTitleSelected on QCustomPlot
|
||||
- new signals in accordance with the interaction system:
|
||||
- selectionChangedByUser on QCustomPlot
|
||||
- selectionChanged on QCPAbstractPlottable
|
||||
- selectionChanged on QCPAxis
|
||||
- selectionChanged on QCPLegend and QCPAbstractLegendItem
|
||||
- plottableClick, legendClick, axisClick, titleClick, plottableDoubleClick, legendDoubleClick, axisDoubleClick, titleDoubleClick on QCustomPlot
|
||||
- QCustomPlot::deselectAll (deselects everything, i.e. axes and plottables)
|
||||
- QCPAbstractPlottable::pixelsToCoords (inverse function to the already existing coordsToPixels function)
|
||||
- QCPRange::contains(double value)
|
||||
- QCPAxis::setLabelColor and setTickLabelColor
|
||||
- QCustomPlot::setTitleColor
|
||||
- QCustomPlot now emits beforeReplot and afterReplot signals. Note that it is safe to make two customPlots mutually call eachothers replot functions
|
||||
in one of these slots, it will not cause an infinite loop. (usefull for synchronizing axes ranges between two customPlots, because setRange alone doesn't replot)
|
||||
- If the Qt version is 4.7 or greater, the tick label strings in date-time-mode now support sub-second accuracy (e.g. with format like "hh:mm:ss.zzz").
|
||||
|
||||
Bugfixes:
|
||||
- tick labels/margins should no longer oscillate by one pixel when dragging range or replotting repeatedly while changing e.g. data. This
|
||||
was caused by a bug in Qt's QFontMetrics::boundingRect function when the font has an integer point size (probably some rounding problem).
|
||||
The fix hence consists of creating a temporary font (only for bounding-box calculation) which is 0.05pt larger and thus avoiding the
|
||||
jittering rounding outcome.
|
||||
- tick label, axis label and plot title colors used to be undefined. This was fixed by providing explicit color properties.
|
||||
|
||||
Other:
|
||||
- fixed some glitches in the documentation
|
||||
- QCustomPlot::replot and QCustomPlot::rescaleAxes are now slots
|
||||
|
||||
#### Version released on 02.02.12 ####
|
||||
|
||||
Changes that break backward compatibility:
|
||||
- renamed all secondary classes from QCustomPlot[...] to QCP[...]:
|
||||
QCustomPlotAxis -> QCPAxis
|
||||
QCustomPlotGraph -> QCPGraph
|
||||
QCustomPlotRange -> QCPRange
|
||||
QCustomPlotData -> QCPData
|
||||
QCustomPlotDataMap -> QCPDataMap
|
||||
QCustomPlotLegend -> QCPLegend
|
||||
QCustomPlotDataMapIterator -> QCPDataMapIterator
|
||||
QCustomPlotDataMutableMapIterator -> QCPDataMutableMapIterator
|
||||
A simple search and replace on all code files should make your code run again, e.g. consider the regex "QCustomPlot(?=[AGRDL])" -> "QCP".
|
||||
Make sure not to just replace "QCustomPlot" with "QCP" because the main class QCustomPlot hasn't changed to QCP.
|
||||
This change was necessary because class names became unhandy, pardon my bad naming decision in the beginning.
|
||||
- QCPAxis::tickLength() and QCPAxis::subTickLength() now each split into two functions for inward and outward ticks (tickLengthIn/tickLengthOut).
|
||||
- QCPLegend now uses QCPAbstractLegendItem to carry item data (before, the legend was passed QCPGraphs directly)
|
||||
- QCustomPlot::addGraph() now doesn't return the index of the created graph anymore, but a pointer to the created QCPGraph.
|
||||
- QCustomPlot::setAutoAddGraphToLegend is replaced by setAutoAddPlottableToLegend
|
||||
|
||||
Added features:
|
||||
- Reversed axis range with QCPAxis::setRangeReversed(bool)
|
||||
- Tick labels are now only drawn if not clipped by the viewport (widget border) on the sides (e.g. left and right on a horizontal axis).
|
||||
- Zerolines. Like grid lines only with a separate pen (QCPAxis::setZeroLinePen), at tick position zero.
|
||||
- Outward ticks. QCPAxis::setTickLength/setSubTickLength now accepts two arguments for inward and outward tick length. This doesn't break
|
||||
backward compatibility because the second argument (outward) has default value zero and thereby a call with one argument hasn't changed its meaning.
|
||||
- QCPGraph now inherits from QCPAbstractPlottable
|
||||
- QCustomPlot::addPlottable/plottable/removePlottable/clearPlottables added to interface with the new QCPAbstractPlottable-based system. The simpler interface
|
||||
which only acts on QCPGraphs (addGraph, graph, removeGraph, etc.) was adapted internally and is kept for backward compatibility and ease of use.
|
||||
- QCPLegend items for plottables (e.g. graphs) can automatically wrap their texts to fit the widths, see QCPLegend::setMinimumSize and QCPPlottableLegendItem::setTextWrap.
|
||||
- QCustomPlot::rescaleAxes. Adapts axis ranges to show all plottables/graphs, by calling QCPAbstractPlottable::rescaleAxes on all plottables in the plot.
|
||||
- QCPCurve. For plotting of parametric curves.
|
||||
- QCPBars. For plotting of bar charts.
|
||||
- QCPStatisticalBox. For statistical box plots.
|
||||
|
||||
Bugfixes:
|
||||
- Fixed QCustomPlot::removeGraph(int) not being able to remove graph index 0
|
||||
- made QCustomPlot::replot() abort painting when painter initialization fails (e.g. because width/height of QCustomPlot is zero)
|
||||
- The distance of the axis label from the axis ignored the tick label padding, this could have caused overlapping axis labels and tick labels
|
||||
- fixed memory leak in QCustomPlot (dtor didn't delete legend)
|
||||
- fixed bug that prevented QCPAxis::setRangeLower/Upper from setting the value to exactly 0.
|
||||
|
||||
Other:
|
||||
- Changed default error bar handle size (QCustomPlotGraph::setErrorBarSize) from 4 to 6.
|
||||
- Removed QCustomPlotDataFetcher. Was deprecated and not used class.
|
||||
- Extended documentation, especially class descriptions.
|
||||
|
||||
#### Version released on 15.01.12 ####
|
||||
|
||||
Changes that (might) break backward compatibility:
|
||||
- QCustomPlotGraph now inherits from QObject
|
||||
|
||||
Added features:
|
||||
- Added axis background pixmap (QCustomPlot::setAxisBackground, setAxisBackgroundScaled, setAxisBackgroundScaledMode)
|
||||
- Added width and height parameter on PDF export function QCustomPlot::savePdf(). This now allows PDF export to
|
||||
have arbitrary dimensions, independent of the current geometry of the QCustomPlot.
|
||||
- Added overload of QCustomPlot::removeGraph that takes QCustomPlotGraph* as parameter, instead the index of the graph
|
||||
- Added all enums to the Qt meta system via Q_ENUMS(). The enums can now be transformed
|
||||
to QString values easily with the Qt meta system, which makes saving state e.g. as XML
|
||||
significantly nicer.
|
||||
- added typedef QMapIterator<double,QCustomPlotData> QCustomPlotDataMapIterator
|
||||
and typedef QMutableMapIterator<double,QCustomPlotData> QCustomPlotDataMutableMapIterator
|
||||
for improved information hiding, when using iterators outside QCustomPlot code
|
||||
|
||||
Bugfixes:
|
||||
- Fixed savePngScaled. Axis/label drawing functions used to reset the painter transform
|
||||
and thereby break savePngScaled. Now they buffer the current transform and restore it afterwards.
|
||||
- Fixed some glitches in the doxygen comments (affects documentation only)
|
||||
|
||||
Other:
|
||||
- Changed the default tickLabelPadding of top axis from 3 to 6 pixels. Looks better.
|
||||
- Changed the default QCustomPlot::setAntialiasedElements setting: Graph fills are now antialiased
|
||||
by default. That's a bit slower, but makes fill borders look better.
|
||||
|
||||
#### Version released on 19.11.11 ####
|
||||
|
||||
Changes that break backward compatibility:
|
||||
- QCustomPlotAxis: tickFont and setTickFont renamed to tickLabelFont and setTickLabelFont (for naming consistency)
|
||||
|
||||
Other:
|
||||
- QCustomPlotAxis: Added rotated tick labels, see setTickLabelRotation
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,13 +3,13 @@
|
||||
Joystick::Joystick(QObject *parent, int joystickEventTimeout, bool doAutoRepeat, int repeatDelay)
|
||||
: QObject(parent)
|
||||
{
|
||||
if ( SDL_Init(SDL_INIT_JOYSTICK) == 0 ) {
|
||||
if ( SDL_WasInit(SDL_INIT_JOYSTICK) ) {
|
||||
int i;
|
||||
for (i = 0; i < SDL_NumJoysticks(); i++)
|
||||
joystickNames.append(SDL_JoystickName(i));
|
||||
connect(&joystickTimer, SIGNAL(timeout()), this, SLOT(processEvents()));
|
||||
} else {
|
||||
fprintf(stderr, "ERROR: couldn't initialize SDL joystick support");
|
||||
fprintf(stderr, "ERROR: couldn't initialize SDL joystick support\n");
|
||||
}
|
||||
|
||||
joystick = NULL;
|
||||
@@ -23,8 +23,6 @@ Joystick::~Joystick()
|
||||
{
|
||||
if ( isOpen() )
|
||||
close();
|
||||
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
bool Joystick::open(int stick)
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef MYQDIAL_H
|
||||
#define MYQDIAL_H
|
||||
|
||||
|
||||
class myQDial : public QDial
|
||||
{
|
||||
public:
|
||||
explicit myQDial(QWidget *parent = 0) : QDial(parent) {}
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::RightButton && event->type() == QEvent::MouseButtonDblClick) {
|
||||
setValue(0);
|
||||
event->accept();
|
||||
}
|
||||
QDial::mousePressEvent(event);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -974,8 +974,8 @@ QPushButton:checked {
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9" stretch="0,1,0,0,1,0,0,1,0,0,1">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QFrame" name="beep_frame">
|
||||
<property name="autoFillBackground">
|
||||
<bool>true</bool>
|
||||
@@ -1006,7 +1006,7 @@ QPushButton:checked {
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -1019,8 +1019,8 @@ QPushButton:checked {
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDial" name="dialP_1">
|
||||
<item row="2" column="0">
|
||||
<widget class="myQDial" name="dialP_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -1053,7 +1053,7 @@ QPushButton:checked {
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="dialP_1value">
|
||||
<property name="text">
|
||||
<string notr="true">0 %</string>
|
||||
@@ -1063,7 +1063,7 @@ QPushButton:checked {
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="4" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -1076,8 +1076,8 @@ QPushButton:checked {
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDial" name="dialP_2">
|
||||
<item row="5" column="0">
|
||||
<widget class="myQDial" name="dialP_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -1113,7 +1113,7 @@ QPushButton:checked {
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="dialP_2value">
|
||||
<property name="text">
|
||||
<string notr="true">0 %</string>
|
||||
@@ -1123,7 +1123,7 @@ QPushButton:checked {
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="7" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -1136,8 +1136,8 @@ QPushButton:checked {
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDial" name="dialP_3">
|
||||
<item row="8" column="0">
|
||||
<widget class="myQDial" name="dialP_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -1170,7 +1170,7 @@ QPushButton:checked {
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="dialP_3value">
|
||||
<property name="text">
|
||||
<string notr="true">0 %</string>
|
||||
@@ -1180,7 +1180,7 @@ QPushButton:checked {
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="10" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -1232,7 +1232,7 @@ QPushButton:checked {
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="simu">
|
||||
<attribute name="title">
|
||||
@@ -1457,17 +1457,11 @@ QPushButton:checked {
|
||||
<attribute name="title">
|
||||
<string>Gvars</string>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="gridLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>711</width>
|
||||
<height>211</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gvarsLayout"/>
|
||||
</widget>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gvarsLayout"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -1497,6 +1491,11 @@ QPushButton:checked {
|
||||
<header>menuwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>myQDial</class>
|
||||
<extends>QDial</extends>
|
||||
<header location="global">myqdial.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../companion.qrc"/>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>726</width>
|
||||
<height>688</height>
|
||||
<height>653</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -70,7 +70,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="simu">
|
||||
<attribute name="title">
|
||||
@@ -257,17 +257,11 @@
|
||||
<attribute name="title">
|
||||
<string>Gvars</string>
|
||||
</attribute>
|
||||
<widget class="QWidget" name="gridLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>10</y>
|
||||
<width>691</width>
|
||||
<height>231</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gvarsLayout"/>
|
||||
</widget>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gvarsLayout"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -576,7 +570,7 @@ QPushButton:checked {
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="10">
|
||||
<widget class="QDial" name="dialP_1">
|
||||
<widget class="myQDial" name="dialP_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -832,7 +826,7 @@ QPushButton:checked {
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QDial" name="dialP_3">
|
||||
<widget class="myQDial" name="dialP_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -1071,7 +1065,7 @@ QPushButton:checked {
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDial" name="dialP_2">
|
||||
<widget class="myQDial" name="dialP_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -1436,7 +1430,7 @@ QPushButton:checked {
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="8">
|
||||
<widget class="QDial" name="dialP_4">
|
||||
<widget class="myQDial" name="dialP_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
@@ -1693,6 +1687,11 @@ QPushButton:checked {
|
||||
<header>xmenuwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>myQDial</class>
|
||||
<extends>QDial</extends>
|
||||
<header location="global">myqdial.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>tabWidget</tabstop>
|
||||
|
||||
@@ -522,14 +522,24 @@ void SimulatorDialog::initUi(T * ui)
|
||||
for (int fm=0; fm<fmodes; fm++) {
|
||||
QLabel * label = new QLabel(tabWidget);
|
||||
label->setText(QString("FM%1").arg(fm));
|
||||
label->setAlignment(Qt::AlignCenter);
|
||||
ui->gvarsLayout->addWidget(label, 0, fm+1);
|
||||
}
|
||||
for (int i=0; i<gvars; i++) {
|
||||
QLabel * label = new QLabel(tabWidget);
|
||||
label->setText(QString("GV%1").arg(i+1));
|
||||
label->setAutoFillBackground(true);
|
||||
if ((i % 2) ==0 ) {
|
||||
label->setStyleSheet("QLabel { background-color: rgb(220, 220, 220) }");
|
||||
}
|
||||
ui->gvarsLayout->addWidget(label, i+1, 0);
|
||||
for (int fm=0; fm<fmodes; fm++) {
|
||||
QLabel * value = new QLabel(tabWidget);
|
||||
value->setAutoFillBackground(true);
|
||||
value->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
if ((i % 2) ==0 ) {
|
||||
value->setStyleSheet("QLabel { background-color: rgb(220, 220, 220) }");
|
||||
}
|
||||
gvarValues << value;
|
||||
ui->gvarsLayout->addWidget(value, i+1, fm+1);
|
||||
}
|
||||
|
||||
@@ -100,6 +100,6 @@ return main_thread_error;
|
||||
#ifdef SETTRAINER_IMPORT
|
||||
#undef SETTRAINER_IMPORT
|
||||
ppmInValid = 100;
|
||||
g_ppmIns[inputNumber] = LIMIT<int16_t>(-512, value, 512);
|
||||
g_ppmIns[inputNumber] = LIMIT< ::int16_t>(-512, value, 512);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -60,11 +60,14 @@ void generateSportPacket(uint8_t * packet, uint8_t dataId, uint8_t prim, uint16_
|
||||
void TelemetrySimulator::generateTelemetryFrame()
|
||||
{
|
||||
static int item = 0;
|
||||
bool ok = true;
|
||||
uint8_t buffer[FRSKY_SPORT_PACKET_SIZE];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
switch(item++) {
|
||||
case 0:
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, RSSI_ID, LIMIT<uint32_t>(0, ui->Rssi->text().toInt(), 0xFF));
|
||||
if (ui->Rssi->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, RSSI_ID, LIMIT<uint32_t>(0, ui->Rssi->text().toInt(&ok, 0), 0xFF));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
@@ -72,20 +75,127 @@ void TelemetrySimulator::generateTelemetryFrame()
|
||||
break;
|
||||
|
||||
case 2:
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, SWR_ID, LIMIT<uint32_t>(0, ui->Swr->text().toInt(), 0xFF));
|
||||
if (ui->Swr->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, SWR_ID, LIMIT<uint32_t>(0, ui->Swr->text().toInt(&ok, 0), 0xFFFF));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, ADC1_ID, LIMIT<uint32_t>(0, ui->A1->text().toInt(), 0xFF));
|
||||
if (ui->A1->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, ADC1_ID, LIMIT<uint32_t>(0, ui->A1->text().toInt(&ok, 0), 0xFF));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, ADC2_ID, LIMIT<uint32_t>(0, ui->A2->text().toInt(), 0xFF));
|
||||
if (ui->A2->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, ADC2_ID, LIMIT<uint32_t>(0, ui->A2->text().toInt(&ok, 0), 0xFF));
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (ui->A3->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, A3_FIRST_ID, LIMIT<uint32_t>(0, ui->A3->text().toInt(&ok, 0), 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (ui->A4->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, A4_FIRST_ID, LIMIT<uint32_t>(0, ui->A4->text().toInt(&ok, 0), 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
case 7:
|
||||
if (ui->T1->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, T1_FIRST_ID, LIMIT<int32_t>(-0x7FFFFFFF, ui->T1->text().toInt(&ok, 0), 0x7FFFFFFF));
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (ui->T2->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, T2_FIRST_ID, LIMIT<int32_t>(-0x7FFFFFFF, ui->T2->text().toInt(&ok, 0), 0x7FFFFFFF));
|
||||
break;
|
||||
|
||||
case 9:
|
||||
if (ui->rpm->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, RPM_FIRST_ID, LIMIT<uint32_t>(0, ui->rpm->text().toInt(&ok, 0), 0xFFFF));
|
||||
break;
|
||||
|
||||
case 10:
|
||||
if (ui->fuel->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, FUEL_FIRST_ID, LIMIT<uint32_t>(0, ui->fuel->text().toInt(&ok, 0), 0xFFFF));
|
||||
break;
|
||||
|
||||
case 11:
|
||||
if (ui->aspeed->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, AIR_SPEED_FIRST_ID, LIMIT<uint32_t>(0, ui->aspeed->text().toInt(&ok, 0), 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
case 12:
|
||||
if (ui->vspeed->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, VARIO_FIRST_ID, LIMIT<int32_t>(-0x7FFFFFFF, ui->vspeed->text().toInt(&ok, 0), 0x7FFFFFFF));
|
||||
break;
|
||||
|
||||
case 13:
|
||||
if (ui->valt->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, ALT_FIRST_ID, LIMIT<int32_t>(-0x7FFFFFFF, ui->valt->text().toInt(&ok, 0), 0x7FFFFFFF));
|
||||
break;
|
||||
|
||||
case 14:
|
||||
if (ui->accx->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, ACCX_FIRST_ID, LIMIT<int32_t>(-0x7FFFFFFF, ui->accx->text().toInt(&ok, 0), 0x7FFFFFFF));
|
||||
break;
|
||||
|
||||
case 15:
|
||||
if (ui->accy->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, ACCY_FIRST_ID, LIMIT<int32_t>(-0x7FFFFFFF, ui->accy->text().toInt(&ok, 0), 0x7FFFFFFF));
|
||||
break;
|
||||
|
||||
case 16:
|
||||
if (ui->accz->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, ACCZ_FIRST_ID, LIMIT<int32_t>(-0x7FFFFFFF, ui->accz->text().toInt(&ok, 0), 0x7FFFFFFF));
|
||||
break;
|
||||
|
||||
case 17:
|
||||
if (ui->vfas->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, VFAS_FIRST_ID, LIMIT<uint32_t>(0, ui->vfas->text().toInt(&ok, 0), 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
case 18:
|
||||
if (ui->curr->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, CURR_FIRST_ID, LIMIT<uint32_t>(0, ui->curr->text().toInt(&ok, 0), 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
case 19:
|
||||
if (ui->cells->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, CELLS_FIRST_ID, LIMIT<uint32_t>(0, ui->cells->text().toInt(&ok, 0), 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
case 20:
|
||||
if (ui->gps_alt->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, GPS_ALT_FIRST_ID, LIMIT<int32_t>(-0x7FFFFFFF, ui->gps_alt->text().toInt(&ok, 0), 0x7FFFFFFF));
|
||||
break;
|
||||
|
||||
case 21:
|
||||
if (ui->gps_speed->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, GPS_SPEED_FIRST_ID, LIMIT<uint32_t>(0, ui->gps_speed->text().toInt(&ok, 0), 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
case 22:
|
||||
if (ui->gps_course->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, GPS_COURS_FIRST_ID, LIMIT<uint32_t>(0, ui->gps_course->text().toInt(&ok, 0), 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
case 23:
|
||||
if (ui->gps_time->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, GPS_TIME_DATE_FIRST_ID, LIMIT<uint32_t>(0, ui->gps_time->text().toInt(&ok, 0), 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
case 24:
|
||||
if (ui->gps_latlon->text().length())
|
||||
generateSportPacket(buffer, 1, DATA_FRAME, GPS_LONG_LATI_FIRST_ID, LIMIT<uint32_t>(0, ui->gps_latlon->text().toInt(&ok, 0), 0xFFFFFFFF));
|
||||
break;
|
||||
|
||||
default:
|
||||
item = 0;
|
||||
return;
|
||||
}
|
||||
simulator->sendTelemetry(buffer, 9);
|
||||
}
|
||||
|
||||
if (ok && buffer[0])
|
||||
simulator->sendTelemetry(buffer, FRSKY_SPORT_PACKET_SIZE);
|
||||
else
|
||||
onTimerEvent();
|
||||
}
|
||||
|
||||
@@ -6,67 +6,342 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>184</width>
|
||||
<height>165</height>
|
||||
<width>278</width>
|
||||
<height>384</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Telemetry Simulator</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="3" column="0">
|
||||
<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 row="1" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="toolTip">
|
||||
<string>Vario Altitude</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">V-ALT</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="toolTip">
|
||||
<string>Vario Vertical Speed</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">V-VSPD</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QLineEdit" name="valt"/>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QLineEdit" name="vspeed"/>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QLineEdit" name="gps_alt"/>
|
||||
</item>
|
||||
<item row="12" column="2">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string notr="true">ACCZ</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="label_23">
|
||||
<property name="toolTip">
|
||||
<string>GPS Time</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">GPS-T</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="3">
|
||||
<widget class="QLineEdit" name="gps_time"/>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string notr="true">ACCX</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="3">
|
||||
<widget class="QLineEdit" name="accx"/>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QLineEdit" name="Swr"/>
|
||||
<widget class="QLineEdit" name="cells"/>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QLineEdit" name="A1"/>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLineEdit" name="curr"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<item row="6" column="3">
|
||||
<widget class="QLineEdit" name="gps_speed"/>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<widget class="QLabel" name="label_24">
|
||||
<property name="toolTip">
|
||||
<string>GPS Lat/Lon</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">GPS-LL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="toolTip">
|
||||
<string>VFAS</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">FAS-V</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QLabel" name="label_21">
|
||||
<property name="toolTip">
|
||||
<string>GPS Speed</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">GPS-S</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="label_19">
|
||||
<property name="text">
|
||||
<string notr="true">CELLS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="3">
|
||||
<widget class="QLineEdit" name="accy"/>
|
||||
</item>
|
||||
<item row="7" column="3">
|
||||
<widget class="QLineEdit" name="gps_course"/>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLineEdit" name="vfas"/>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string notr="true">ACCY</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QLabel" name="label_22">
|
||||
<property name="toolTip">
|
||||
<string>GPS Course</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">GPS-C</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="3">
|
||||
<widget class="QLineEdit" name="gps_latlon"/>
|
||||
</item>
|
||||
<item row="12" column="3">
|
||||
<widget class="QLineEdit" name="accz"/>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="label_20">
|
||||
<property name="toolTip">
|
||||
<string>GPS Altitude</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">GPS-A</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="toolTip">
|
||||
<string>Current</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">FAS-C</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="Swr">
|
||||
<property name="text">
|
||||
<string notr="true">30</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>RSSI</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLineEdit" name="Rssi"/>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="Rssi">
|
||||
<property name="text">
|
||||
<string>A1</string>
|
||||
<string notr="true">75</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>SWR</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="toolTip">
|
||||
<string>Airspeed</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">ASPD</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QLineEdit" name="aspeed"/>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="A1"/>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="A2"/>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="A3"/>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="A4"/>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="T1"/>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="T2"/>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLineEdit" name="rpm"/>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="fuel"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string notr="true">A1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string notr="true">A2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string notr="true">A3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string notr="true">A4</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="toolTip">
|
||||
<string>Temperature 1</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">T1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="toolTip">
|
||||
<string>Temperature 2</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">T2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string notr="true">RPM</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string notr="true">FUEL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="Simulate">
|
||||
<property name="toolTip">
|
||||
<string>When enabled, sends any non-blank values as simulated telemetry data.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>simulate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>A2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QLineEdit" name="A2"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_25">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>Start with <span style=" font-style:italic;">0x</span> for hex, <span style=" font-style:italic;">0</span> for octal, otherwise decimal.<br/>Numeric entry only. Blank values are not sent.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>Simulate</tabstop>
|
||||
<tabstop>Rssi</tabstop>
|
||||
<tabstop>Swr</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
#include <QSplashScreen>
|
||||
#include <QThread>
|
||||
#include <iostream>
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
#include "simulatordialog.h"
|
||||
#include "eeprominterface.h"
|
||||
|
||||
@@ -98,6 +101,17 @@ int main(int argc, char *argv[])
|
||||
|
||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
uint32_t sdlFlags = 0;
|
||||
#ifdef JOYSTICKS
|
||||
sdlFlags |= SDL_INIT_JOYSTICK;
|
||||
#endif
|
||||
#ifdef SIMU_AUDIO
|
||||
sdlFlags |= SDL_INIT_AUDIO;
|
||||
#endif
|
||||
SDL_Init(sdlFlags);
|
||||
#endif
|
||||
|
||||
RegisterEepromInterfaces();
|
||||
registerOpenTxFirmwares();
|
||||
|
||||
@@ -172,5 +186,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
delete dialog;
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
SDL_Quit();
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+1985
-1416
File diff suppressed because it is too large
Load Diff
+2400
-1806
File diff suppressed because it is too large
Load Diff
+2428
-1818
File diff suppressed because it is too large
Load Diff
+1633
-1388
File diff suppressed because it is too large
Load Diff
+2472
-2063
File diff suppressed because it is too large
Load Diff
+2473
-1817
File diff suppressed because it is too large
Load Diff
+2431
-2022
File diff suppressed because it is too large
Load Diff
+2728
-1890
File diff suppressed because it is too large
Load Diff
+2453
-1993
File diff suppressed because it is too large
Load Diff
+2486
-2054
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -69,12 +69,12 @@ void WizMix::addMix(ModelData &model, Input input, int weight, int channel, int
|
||||
else if (input==FLAPS_INPUT){
|
||||
// There ought to be some kind of constants for switches somewhere...
|
||||
maxMixSwitch((char *)"Flaps Up", model.mixData[mixIndex++], channel+1, isTaranis ? SWITCH_SA0 :-SWITCH_ELE , weight); //Taranis SA-UP, 9X ELE-UP
|
||||
maxMixSwitch((char *)"Flaps Down", model.mixData[mixIndex++], channel+1, isTaranis ? SWITCH_SA2 : SWITCH_ELE , -weight); //Taranis SA-DOWN, 9X ELE-DOWN
|
||||
maxMixSwitch((char *)"Flaps Dn", model.mixData[mixIndex++], channel+1, isTaranis ? SWITCH_SA2 : SWITCH_ELE , -weight); //Taranis SA-DOWN, 9X ELE-DOWN
|
||||
|
||||
}
|
||||
else if (input==AIRBRAKES_INPUT){
|
||||
maxMixSwitch((char *)"Airbrk Off", model.mixData[mixIndex++], channel+1, isTaranis ? SWITCH_SE0 :-SWITCH_RUD , -weight); //Taranis SE-UP, 9X RUD-UP
|
||||
maxMixSwitch((char *)"Airbrk On", model.mixData[mixIndex++], channel+1, isTaranis ? SWITCH_SE2 : SWITCH_RUD , weight); //Tatanis SE-DOWN, 9X RUD-DOWN
|
||||
maxMixSwitch((char *)"AirbkOff", model.mixData[mixIndex++], channel+1, isTaranis ? SWITCH_SE0 :-SWITCH_RUD , -weight); //Taranis SE-UP, 9X RUD-UP
|
||||
maxMixSwitch((char *)"AirbkOn", model.mixData[mixIndex++], channel+1, isTaranis ? SWITCH_SE2 : SWITCH_RUD , weight); //Tatanis SE-DOWN, 9X RUD-DOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Kjell Kernen
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
@@ -181,6 +181,18 @@ int StandardPage::nextFreeChannel(int channel)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int StandardPage::totalChannelsAvailable()
|
||||
{
|
||||
int c = 0;
|
||||
for(int i=0; i<WIZ_MAX_CHANNELS; i++) {
|
||||
if (wizDlg->mix.channel[i].page == Page_None) {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void StandardPage::populateCB(QComboBox *cb, int preferred)
|
||||
{
|
||||
cb->clear();
|
||||
@@ -214,7 +226,7 @@ bool StandardPage::bookChannel(QComboBox * cb, Input input1, int weight1, Input
|
||||
{
|
||||
int channel = cb->itemData(cb->currentIndex()).toInt();
|
||||
if (channel<0 || channel>=WIZ_MAX_CHANNELS)
|
||||
return false;
|
||||
return false;
|
||||
if (wizDlg->mix.channel[channel].page != Page_None)
|
||||
return false;
|
||||
|
||||
@@ -231,7 +243,7 @@ void StandardPage::releaseBookings()
|
||||
{
|
||||
for (int i=0; i<WIZ_MAX_CHANNELS; i++) {
|
||||
if (wizDlg->mix.channel[i].page == pageCurrent) {
|
||||
wizDlg->mix.channel[i].clear();
|
||||
wizDlg->mix.channel[i].clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -298,7 +310,7 @@ bool ModelSelectionPage::validatePage()
|
||||
return true;
|
||||
}
|
||||
|
||||
int ModelSelectionPage::nextId() const
|
||||
int ModelSelectionPage::nextId() const
|
||||
{
|
||||
if (helicopterRB->isChecked())
|
||||
return Page_Cyclic;
|
||||
@@ -432,7 +444,7 @@ AileronsPage::AileronsPage(WizardDialog *dlg, QString image, QString title, QStr
|
||||
l->addWidget(aileron1CB);
|
||||
l->addWidget(new QLabel(tr("Second Aileron Channel:")));
|
||||
l->addWidget(aileron2CB);
|
||||
|
||||
|
||||
connect(noAileronsRB, SIGNAL(toggled(bool)), this, SLOT(noAileronChannel()));
|
||||
connect(oneAileronRB, SIGNAL(toggled(bool)), this, SLOT(oneAileronChannel()));
|
||||
connect(twoAileronsRB, SIGNAL(toggled(bool)), this, SLOT(twoAileronChannels()));
|
||||
@@ -448,10 +460,10 @@ void AileronsPage::initializePage()
|
||||
bool AileronsPage::validatePage()
|
||||
{
|
||||
releaseBookings();
|
||||
if (noAileronsRB->isChecked()) {
|
||||
if (noAileronsRB->isChecked()) {
|
||||
return true;
|
||||
}
|
||||
if (oneAileronRB->isChecked()) {
|
||||
if (oneAileronRB->isChecked()) {
|
||||
return (bookChannel(aileron1CB, AILERONS_INPUT, 100 ));
|
||||
}
|
||||
return( bookChannel(aileron1CB, AILERONS_INPUT, 100 ) &&
|
||||
@@ -497,7 +509,7 @@ FlapsPage::FlapsPage(WizardDialog *dlg, QString image, QString title, QString te
|
||||
l->addWidget(flap1CB);
|
||||
l->addWidget(new QLabel(tr("Second Flap Channel:")));
|
||||
l->addWidget(flap2CB);
|
||||
|
||||
|
||||
connect(noFlapsRB, SIGNAL(toggled(bool)), this, SLOT(noFlapChannel()));
|
||||
connect(oneFlapRB, SIGNAL(toggled(bool)), this, SLOT(oneFlapChannel()));
|
||||
connect(twoFlapsRB, SIGNAL(toggled(bool)), this, SLOT(twoFlapChannels()));
|
||||
@@ -512,10 +524,10 @@ void FlapsPage::initializePage()
|
||||
|
||||
bool FlapsPage::validatePage() {
|
||||
releaseBookings();
|
||||
if (noFlapsRB->isChecked()) {
|
||||
if (noFlapsRB->isChecked()) {
|
||||
return true;
|
||||
}
|
||||
if (oneFlapRB->isChecked()) {
|
||||
if (oneFlapRB->isChecked()) {
|
||||
return (bookChannel(flap1CB, FLAPS_INPUT, 100 ));
|
||||
}
|
||||
return( bookChannel(flap1CB, FLAPS_INPUT, 100 ) &&
|
||||
@@ -561,7 +573,7 @@ AirbrakesPage::AirbrakesPage(WizardDialog *dlg, QString image, QString title, QS
|
||||
l->addWidget(airbrake1CB);
|
||||
l->addWidget(new QLabel(tr("Second Airbrake Channel:")));
|
||||
l->addWidget(airbrake2CB);
|
||||
|
||||
|
||||
connect(noAirbrakesRB, SIGNAL(toggled(bool)), this, SLOT(noAirbrakeChannel()));
|
||||
connect(oneAirbrakeRB, SIGNAL(toggled(bool)), this, SLOT(oneAirbrakeChannel()));
|
||||
connect(twoAirbrakesRB, SIGNAL(toggled(bool)), this, SLOT(twoAirbrakeChannels()));
|
||||
@@ -577,10 +589,10 @@ void AirbrakesPage::initializePage()
|
||||
bool AirbrakesPage::validatePage()
|
||||
{
|
||||
releaseBookings();
|
||||
if (noAirbrakesRB->isChecked()) {
|
||||
if (noAirbrakesRB->isChecked()) {
|
||||
return true;
|
||||
}
|
||||
if (oneAirbrakeRB->isChecked()) {
|
||||
if (oneAirbrakeRB->isChecked()) {
|
||||
return (bookChannel(airbrake1CB, AIRBRAKES_INPUT, 100 ));
|
||||
}
|
||||
return( bookChannel(airbrake1CB, AIRBRAKES_INPUT, 100 ) &&
|
||||
@@ -708,11 +720,13 @@ TailPage::TailPage(WizardDialog *dlg, QString image, QString title, QString text
|
||||
elevatorCB = new QComboBox();
|
||||
rudderCB = new QComboBox();
|
||||
|
||||
QLayout *l = layout();
|
||||
l = layout();
|
||||
l->addWidget(new QLabel(tr("Rudder Channel:")));
|
||||
l->addWidget(rudderCB);
|
||||
l->addWidget(new QLabel(tr("Elevator Channel:")));
|
||||
l->addWidget(elevatorCB);
|
||||
|
||||
errorMessage = NULL;
|
||||
}
|
||||
|
||||
void TailPage::initializePage()
|
||||
@@ -720,6 +734,13 @@ void TailPage::initializePage()
|
||||
populateCB(elevatorCB, getDefaultChannel(ELEVATOR_INPUT));
|
||||
populateCB(rudderCB, getDefaultChannel(RUDDER_INPUT));
|
||||
StandardPage::initializePage();
|
||||
|
||||
if (totalChannelsAvailable() < 2) {
|
||||
errorMessage = new QLabel(tr("Only one channel still available!<br>"
|
||||
"You probably should configure your model without using the wizard."));
|
||||
errorMessage->setStyleSheet("QLabel { color : red; }");
|
||||
l->addWidget(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
bool TailPage::validatePage()
|
||||
@@ -729,9 +750,20 @@ bool TailPage::validatePage()
|
||||
bookChannel(rudderCB, RUDDER_INPUT, 100));
|
||||
}
|
||||
|
||||
void TailPage::cleanupPage()
|
||||
{
|
||||
if (errorMessage)
|
||||
{
|
||||
l->removeWidget(errorMessage);
|
||||
delete errorMessage;
|
||||
errorMessage = NULL;
|
||||
}
|
||||
StandardPage::cleanupPage();
|
||||
}
|
||||
|
||||
SimpleTailPage::SimpleTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage)
|
||||
: StandardPage(Page_Simpletail, dlg, image, title, text, nextPage)
|
||||
{
|
||||
{
|
||||
elevatorCB = new QComboBox();
|
||||
|
||||
QLayout *l = layout();
|
||||
@@ -1001,7 +1033,7 @@ WizardPrinter::WizardPrinter(WizMix *wizMix)
|
||||
{
|
||||
mix = wizMix;
|
||||
}
|
||||
|
||||
|
||||
QString WizardPrinter::printChannel( Input input1, int weight1, Input input2, int weight2 )
|
||||
{
|
||||
QString str;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author - Kjell Kernen
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
@@ -15,7 +15,7 @@
|
||||
#ifndef WIZARDDIALOG_H
|
||||
#define WIZARDDIALOG_H
|
||||
#include <QWizard>
|
||||
#include "wizarddata.h"
|
||||
#include "wizarddata.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QCheckBox;
|
||||
@@ -46,7 +46,7 @@ class StandardPage: public QWizardPage
|
||||
StandardPage(WizardPage curPage, WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
WizardDialog *wizDlg;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
void releaseBookings();
|
||||
void releasePreBookings();
|
||||
void initializePage();
|
||||
@@ -55,6 +55,7 @@ class StandardPage: public QWizardPage
|
||||
int nextFreeChannel(int channel = 0);
|
||||
void populateCB(QComboBox * cb, int preferred=-1);
|
||||
bool bookChannel(QComboBox * cb, Input input1, int weight1, Input input2=NO_INPUT, int weight2=0);
|
||||
int totalChannelsAvailable();
|
||||
|
||||
private:
|
||||
QLabel *topLabel;
|
||||
@@ -67,48 +68,48 @@ class ModelSelectionPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ModelSelectionPage(WizardDialog *dlg, QString image, QString title, QString text);
|
||||
ModelSelectionPage(WizardDialog *dlg, QString image, QString title, QString text);
|
||||
private:
|
||||
QLineEdit *nameLineEdit;
|
||||
QRadioButton *planeRB;
|
||||
QRadioButton *multirotorRB;
|
||||
QRadioButton *helicopterRB;
|
||||
bool validatePage();
|
||||
int nextId() const;
|
||||
int nextId() const;
|
||||
};
|
||||
|
||||
class WingtypeSelectionPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WingtypeSelectionPage(WizardDialog *dlg, QString image, QString title, QString text);
|
||||
WingtypeSelectionPage(WizardDialog *dlg, QString image, QString title, QString text);
|
||||
private:
|
||||
QRadioButton *deltaWingRB;
|
||||
QRadioButton *standardWingRB;
|
||||
int nextId() const;
|
||||
int nextId() const;
|
||||
};
|
||||
|
||||
class TailSelectionPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TailSelectionPage(WizardDialog *dlg, QString image, QString title, QString text);
|
||||
TailSelectionPage(WizardDialog *dlg, QString image, QString title, QString text);
|
||||
private:
|
||||
QRadioButton *vTailRB;
|
||||
QRadioButton *standardTailRB;
|
||||
QRadioButton *simpleTailRB;
|
||||
int nextId() const;
|
||||
int nextId() const;
|
||||
};
|
||||
|
||||
class FlybarSelectionPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FlybarSelectionPage(WizardDialog *dlg, QString image, QString title, QString text);
|
||||
FlybarSelectionPage(WizardDialog *dlg, QString image, QString title, QString text);
|
||||
private:
|
||||
QRadioButton *flybarRB;
|
||||
QRadioButton *noFlybarRB;
|
||||
int nextId() const;
|
||||
int nextId() const;
|
||||
};
|
||||
|
||||
class ThrottlePage: public StandardPage
|
||||
@@ -133,10 +134,10 @@ class AileronsPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AileronsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
AileronsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
|
||||
|
||||
protected slots:
|
||||
void noAileronChannel();
|
||||
void oneAileronChannel();
|
||||
@@ -154,7 +155,7 @@ class FlapsPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FlapsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
FlapsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
|
||||
@@ -175,7 +176,7 @@ class AirbrakesPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AirbrakesPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
AirbrakesPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
|
||||
@@ -229,19 +230,22 @@ class TailPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
TailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
void cleanupPage();
|
||||
bool validatePage();
|
||||
private:
|
||||
QComboBox *elevatorCB;
|
||||
QComboBox *rudderCB;
|
||||
QLayout *l;
|
||||
QLabel *errorMessage;
|
||||
};
|
||||
|
||||
class VTailPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
VTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
VTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
private:
|
||||
@@ -253,7 +257,7 @@ class SimpleTailPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SimpleTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
SimpleTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
private:
|
||||
@@ -264,7 +268,7 @@ class CyclicPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CyclicPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
CyclicPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
private:
|
||||
@@ -278,7 +282,7 @@ class GyroPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
GyroPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
GyroPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
private:
|
||||
@@ -291,7 +295,7 @@ class FblPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FblPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
FblPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
private:
|
||||
@@ -305,7 +309,7 @@ class HeliPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HeliPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
HeliPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
private:
|
||||
@@ -319,7 +323,7 @@ class MultirotorPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MultirotorPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
MultirotorPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
private:
|
||||
@@ -333,7 +337,7 @@ class OptionsPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OptionsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
OptionsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
private:
|
||||
@@ -346,7 +350,7 @@ class ConclusionPage: public StandardPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ConclusionPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
ConclusionPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1);
|
||||
void initializePage();
|
||||
bool validatePage();
|
||||
private:
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
;General
|
||||
|
||||
;Name and file
|
||||
Name "OpenTX Companion"
|
||||
Name "OpenTX Companion 2.0"
|
||||
OutFile "companionInstall_@C9X_VERSION@.exe"
|
||||
|
||||
;Default installation folder
|
||||
InstallDir "$PROGRAMFILES\OpenTX"
|
||||
InstallDir "$PROGRAMFILES\OpenTX\Companion 2.0"
|
||||
|
||||
;Get installation folder from registry if available
|
||||
InstallDirRegKey HKCU "Software\OpenTX" ""
|
||||
InstallDirRegKey HKCU "Software\OpenTX\Companion 2.0" ""
|
||||
|
||||
;Compressor options
|
||||
SetCompressor /FINAL /SOLID lzma
|
||||
@@ -37,6 +37,7 @@
|
||||
;Interface Settings
|
||||
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_CUSTOMFUNCTION_GUIINIT removeOld
|
||||
|
||||
;--------------------------------
|
||||
;File Exists Macro
|
||||
@@ -66,7 +67,7 @@
|
||||
|
||||
;Start Menu Folder Page Configuration
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\OpenTX"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\OpenTX\Companion 2.0"
|
||||
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
|
||||
|
||||
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
|
||||
@@ -77,7 +78,7 @@
|
||||
!define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||
!define MUI_FINISHPAGE_RUN
|
||||
!define MUI_FINISHPAGE_RUN_CHECKED
|
||||
!define MUI_FINISHPAGE_RUN_TEXT "Launch OpenTX Companion"
|
||||
!define MUI_FINISHPAGE_RUN_TEXT "Launch OpenTX Companion 2.0"
|
||||
!define MUI_FINISHPAGE_RUN_FUNCTION "LaunchLink"
|
||||
# !define MUI_FINISHPAGE_SHOWREADME_NOTCHECKED
|
||||
# !define MUI_FINISHPAGE_SHOWREADME $INSTDIR\readme.txt
|
||||
@@ -133,7 +134,7 @@ Section "OpenTX Companion" SecDummy
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
;Store installation folder
|
||||
WriteRegStr HKCU "Software\OpenTX" "" $INSTDIR
|
||||
WriteRegStr HKCU "Software\OpenTX\Companion 2.0" "" $INSTDIR
|
||||
|
||||
;Associate with extentions ,bin and .hex
|
||||
${registerExtension} "$INSTDIR\companion.exe" ".bin" "BIN_File"
|
||||
@@ -146,19 +147,20 @@ Section "OpenTX Companion" SecDummy
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
||||
;Registry information for add/remove programs
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX" "DisplayName" "OpenTX Companion"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX" "DisplayIcon" "$\"$INSTDIR\companion.exe$\""
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX" "Publisher" "OpenTX"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX" "URLInfoAbout" "http://www.open-tx.org"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\ImageMaker" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion 2.0" "DisplayName" "OpenTX Companion 2.0"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion 2.0" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion 2.0" "DisplayIcon" "$\"$INSTDIR\companion.exe$\""
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion 2.0" "Publisher" "OpenTX"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion 2.0" "URLInfoAbout" "http://www.open-tx.org"
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion 2.0" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S"
|
||||
|
||||
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
|
||||
|
||||
;Create shortcuts
|
||||
CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
|
||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\companion.lnk" "$INSTDIR\companion.exe"
|
||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
|
||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Companion 2.0.lnk" "$INSTDIR\companion.exe"
|
||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Firmware Simulator 2.0.lnk" "$INSTDIR\simulator.exe"
|
||||
CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Uninstall Companion 2.0.lnk" "$INSTDIR\Uninstall.exe"
|
||||
|
||||
!insertmacro MUI_STARTMENU_WRITE_END
|
||||
|
||||
@@ -170,6 +172,10 @@ SectionEnd
|
||||
;Language strings
|
||||
LangString DESC_SecDummy ${LANG_ENGLISH} "Models and settings editor for OpenTX"
|
||||
LangString DESC_SecDummy ${LANG_FRENCH} "Editeur de r�glages et mod�les pour OpenTX"
|
||||
LangString removeMessage ${LANG_ENGLISH} "An older version of OpenTX Companion is already installed and needs to be removed. \
|
||||
$\n$\nClick `OK` to remove the previous version or `Cancel` to cancel this upgrade."
|
||||
LangString removeMessage ${LANG_FRENCH} "Une ancienne version d'OpenTX Companion est installee et doit etre supprimee. \
|
||||
$\n$\nCliquer `OK` pour supprimer l'ancienne version ou `Annuler` pour annuler l'installation."
|
||||
|
||||
;Assign language strings to sections
|
||||
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||
@@ -204,8 +210,10 @@ Section "Uninstall"
|
||||
Delete "$INSTDIR\Uninstall.exe"
|
||||
|
||||
Delete "$INSTDIR\lang\*.*"
|
||||
Delete "$INSTDIR\phonon_backend\*.*"
|
||||
|
||||
RMDir "$INSTDIR\lang"
|
||||
RMDir "$INSTDIR\phonon_backend"
|
||||
RMDir "$INSTDIR"
|
||||
|
||||
${unregisterExtension} ".bin" "BIN File"
|
||||
@@ -215,15 +223,58 @@ Section "Uninstall"
|
||||
|
||||
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder
|
||||
|
||||
Delete "$SMPROGRAMS\$StartMenuFolder\companion.lnk"
|
||||
Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk"
|
||||
Delete "$SMPROGRAMS\$StartMenuFolder\Companion 2.0.lnk"
|
||||
Delete "$SMPROGRAMS\$StartMenuFolder\Firmware Simulator 2.0.lnk"
|
||||
Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall Companion 2.0.lnk"
|
||||
RMDir "$SMPROGRAMS\$StartMenuFolder"
|
||||
|
||||
DeleteRegKey /ifempty HKCU "Software\OpenTX"
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX"
|
||||
DeleteRegKey /ifempty HKCU "Software\OpenTX Companion 2.0"
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX Companion 2.0"
|
||||
|
||||
SectionEnd
|
||||
|
||||
Function LaunchLink
|
||||
ExecShell "" "$INSTDIR\companion.exe"
|
||||
FunctionEnd
|
||||
|
||||
Function removeOld
|
||||
ReadRegStr $R0 HKLM \
|
||||
"Software\Microsoft\Windows\CurrentVersion\Uninstall\OpenTX" \
|
||||
"UninstallString"
|
||||
StrCmp $R0 "" done
|
||||
|
||||
ReadRegStr $R1 HKCU \
|
||||
"Software\OpenTX" \
|
||||
""
|
||||
|
||||
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
|
||||
"$(removeMessage)" \
|
||||
IDOK uninst
|
||||
Abort
|
||||
|
||||
;Run the uninstaller
|
||||
uninst:
|
||||
ClearErrors
|
||||
ExecWait '$R0 _?=$R1' ;Prevent concurrent execution
|
||||
|
||||
IfErrors no_remove_uninstaller uninstalled
|
||||
Delete $R0
|
||||
;You can either use Delete /REBOOTOK in the uninstaller or add some code
|
||||
;here to remove the uninstaller. Use a registry key to check
|
||||
;whether the user has chosen to uninstall. If you are using an uninstaller
|
||||
;components page, make sure all sections are uninstalled.
|
||||
no_remove_uninstaller:
|
||||
Quit
|
||||
|
||||
uninstalled:
|
||||
; Cleanup leftover mess from previous uninstaller
|
||||
Delete "$R1\phonon_backend\*.*"
|
||||
RMDir "$R1\phonon_backend"
|
||||
Delete "$R1\Uninstall.exe"
|
||||
RMDir "$R1"
|
||||
DeleteRegValue HKCU "Software\OpenTX" ""
|
||||
DeleteRegValue HKCU "Software\OpenTX" "Start Menu Folder"
|
||||
|
||||
done:
|
||||
|
||||
FunctionEnd
|
||||
|
||||
+30
-2
@@ -1,4 +1,32 @@
|
||||
<h2>Version 2.0.14 / todo</h2>
|
||||
<h2>Version 2.0.16 / 2015-05-03</h2>
|
||||
|
||||
[Taranis]
|
||||
<ul>
|
||||
<li>Fixed reverse polarity on external PPM output. <b>Users with external module in PPM mode should check and update PPM polarity setting.</b></li>
|
||||
<li>File deletion in SD manager did not free used clusters (all radios with SD card)</li>
|
||||
<li>Fixed Lua <i>lcd.drawLine()</i> problem with slanted lines</li>
|
||||
<li>Fixed bad SWR after flight or telemetry reset (<a href=https://github.com/opentx/opentx/issues/2015>#2015</a>)</li>
|
||||
<li>Fixed missing timer voice minute call when triggered by THt (<a href=https://github.com/opentx/opentx/issues/2009>#2009</a>)</li>
|
||||
<li>Lua model.insertInput() could not add a line to an empty input or at the end of the existing input lines (<a href=https://github.com/opentx/opentx/issues/2084>#2084</a>)</li>
|
||||
<li>Fixed radio slowdown when SD card was full (<a href=https://github.com/opentx/opentx/issues/2007>#2007</a>)</li>
|
||||
<li>Added Mixers Monitor screen (<a href=https://github.com/opentx/opentx/issues/1945>#1945</a>)</li>
|
||||
<li>Fixed Lua <i>lcd.drawPixmap()</i> that could write outside the LCD buffer (<a href=https://github.com/opentx/opentx/issues/2123>#2123</a>)</li>
|
||||
<li>Gps positon display fixed: fractional seconds lacked leading zeros (<a href=https://github.com/opentx/opentx/issues/2144>#2144</a>)</li>
|
||||
<li>More memory available for Lua scripts (<a href=https://github.com/opentx/opentx/issues/2050>#2050</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
<li>Telemetry bars title fix (<a href=https://github.com/opentx/opentx/issues/2203>#2203</a>)</li>
|
||||
</ul>
|
||||
|
||||
[Bootloader]
|
||||
<li>Fixed USB access problem with SD cards larger than 4GB (<a href=https://github.com/opentx/opentx/issues/2154>#2154</a>)</li>
|
||||
|
||||
|
||||
<h2>Version 2.0.15 / 2015-01-13</h2>
|
||||
|
||||
Nothing new (only Companion fixes)
|
||||
|
||||
|
||||
<h2>Version 2.0.14 / 2015-01-12</h2>
|
||||
|
||||
[Taranis]
|
||||
<ul>
|
||||
@@ -10,7 +38,7 @@
|
||||
<li>Added switch auto detection in Timer source</li>
|
||||
<li>Totally removed splash screen display if duration is set to ---</li>
|
||||
<li>Back-light turned on sooner at startup (Taranis +)</li>
|
||||
<li>Fixed reverse polarity on external CPPM output</li>
|
||||
<li><strike>Fixed reverse polarity on external CPPM output</strike> (update: this was not fixed in 2.0.14)</li>
|
||||
<li>Suppressed center beep for non-existing pots</li>
|
||||
<li>Fixed THt persistent timer running after model load (with Throttle at -100%)</li>
|
||||
<li>Fixed buffer overflow for automatic flight mode change audio announcements (if very long model and flight mode names were used)</li>
|
||||
|
||||
+20
-15
@@ -163,8 +163,11 @@
|
||||
|
||||
|
||||
/* Timestamp feature */
|
||||
#if _FS_NORTC
|
||||
#define GET_FATTIME() ((DWORD)_NORTC_YEAR << 25 | (DWORD)_NORTC_MON << 21 | (DWORD)_NORTC_MDAY << 16)
|
||||
#if _FS_NORTC == 1
|
||||
#if _NORTC_YEAR < 1980 || _NORTC_YEAR > 2107 || _NORTC_MON < 1 || _NORTC_MON > 12 || _NORTC_MDAY < 1 || _NORTC_MDAY > 31
|
||||
#error Invalid _FS_NORTC settings
|
||||
#endif
|
||||
#define GET_FATTIME() ((DWORD)(_NORTC_YEAR - 1980) << 25 | (DWORD)_NORTC_MON << 21 | (DWORD)_NORTC_MDAY << 16)
|
||||
#else
|
||||
#define GET_FATTIME() get_fattime()
|
||||
#endif
|
||||
@@ -3486,22 +3489,24 @@ FRESULT f_unlink (
|
||||
if (dir[DIR_Attr] & AM_RDO)
|
||||
res = FR_DENIED; /* Cannot remove R/O object */
|
||||
}
|
||||
if (res == FR_OK && (dir[DIR_Attr] & AM_DIR)) { /* Is it a sub-dir? */
|
||||
if (res == FR_OK) {
|
||||
dclst = ld_clust(dj.fs, dir);
|
||||
if (!dclst) {
|
||||
res = FR_INT_ERR;
|
||||
} else { /* Make sure the sub-directory is empty */
|
||||
mem_cpy(&sdj, &dj, sizeof (DIR));
|
||||
sdj.sclust = dclst;
|
||||
res = dir_sdi(&sdj, 2); /* Exclude dot entries */
|
||||
if (res == FR_OK) {
|
||||
res = dir_read(&sdj, 0); /* Read an item */
|
||||
if (res == FR_OK /* Not empty directory */
|
||||
if (dir[DIR_Attr] & AM_DIR) { /* Is it a sub-dir? */
|
||||
if (!dclst) {
|
||||
res = FR_INT_ERR;
|
||||
} else { /* Make sure the sub-directory is empty */
|
||||
mem_cpy(&sdj, &dj, sizeof (DIR));
|
||||
sdj.sclust = dclst;
|
||||
res = dir_sdi(&sdj, 2); /* Exclude dot entries */
|
||||
if (res == FR_OK) {
|
||||
res = dir_read(&sdj, 0); /* Read an item */
|
||||
if (res == FR_OK /* Not empty directory */
|
||||
#if _FS_RPATH
|
||||
|| dclst == dj.fs->cdir /* or current directory */
|
||||
|| dclst == dj.fs->cdir /* or current directory */
|
||||
#endif
|
||||
) res = FR_DENIED;
|
||||
if (res == FR_NO_FILE) res = FR_OK; /* It is empty */
|
||||
) res = FR_DENIED;
|
||||
if (res == FR_NO_FILE) res = FR_OK; /* It is empty */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+51
-15
@@ -286,16 +286,16 @@ MENUS_LOCK = NO
|
||||
# MASSSTORAGE: The TX will appear as a drive
|
||||
USB = JOYSTICK
|
||||
|
||||
# Channel monitor display behavior
|
||||
# Mixers monitor view added to Channels monitor one
|
||||
# Values = NO, YES
|
||||
# YES - hide the fact that channel is inverted in limits tab
|
||||
# and show inverted channel value with opposite sign
|
||||
# NO - normal behavior, show real channel values
|
||||
CHANNELS_MONITOR_INV_HIDE = NO
|
||||
# YES - Adds mixers output view to Channels monitor screen,
|
||||
# pressing [ENT] switches between views.
|
||||
# NO - classic Channels monitor
|
||||
MIXERS_MONITOR = NO
|
||||
|
||||
# Use newlib-nano
|
||||
# Values = NO, YES
|
||||
NANO = YES
|
||||
NANO = NO
|
||||
|
||||
# Enable trace of events into Trace Buffer for debugging purposes
|
||||
# Activating any of these options also activates DEBUG and DEBUG_TRACE_BUFFER
|
||||
@@ -307,6 +307,23 @@ TRACE_SD_CARD = NO
|
||||
TRACE_FATFS = NO
|
||||
TRACE_AUDIO = NO
|
||||
|
||||
# Enable internal module PPM mode for Taranis
|
||||
# Notice: enabling this only enable code in the driver,
|
||||
# the menu selection is still not possible.
|
||||
# Values = NO, YES
|
||||
TARANIS_INTERNAL_PPM = NO
|
||||
|
||||
# Enable disk IO simulation in simulator
|
||||
# Simulator will use FatFs module and simulated IO layer that
|
||||
# uses "./sdcard.image" file as image of SD card.
|
||||
# This file must contain whole SD card from first to last sector
|
||||
# Values = NO, YES
|
||||
SIMU_DISKIO = NO
|
||||
|
||||
# Enable audio in simulator
|
||||
# Values = NO, YES
|
||||
SIMU_AUDIO = NO
|
||||
|
||||
#------- END BUILD OPTIONS ---------------------------
|
||||
|
||||
# Define programs and commands.
|
||||
@@ -314,7 +331,7 @@ SHELL = sh
|
||||
IMG2LBM = -python ../util/img2lbm.py
|
||||
BIN2LBM = -python ../util/bin2lbm.py
|
||||
TRANSLATE = -python ../util/translate.py
|
||||
VERSION = 2.0.14
|
||||
VERSION = 2.0.16
|
||||
|
||||
SRC =
|
||||
CPPSRC =
|
||||
@@ -550,7 +567,7 @@ ifeq ($(PCB), GRUVIN9X)
|
||||
|
||||
ifeq ($(SDCARD), YES)
|
||||
CPPDEFS += -DRTCLOCK
|
||||
CPPSRC += rtc.cpp targets/gruvin9x/rtc_driver.cpp
|
||||
CPPSRC += rtc.cpp targets/gruvin9x/rtc_driver.cpp sdcard.cpp
|
||||
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/gruvin9x/diskio.cpp
|
||||
endif
|
||||
|
||||
@@ -589,9 +606,9 @@ ifeq ($(PCB), MEGA2560)
|
||||
CPPSRC += audio_avr.cpp debug.cpp
|
||||
|
||||
ifeq ($(SDCARD), YES)
|
||||
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/gruvin9x/diskio.cpp
|
||||
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/gruvin9x/diskio.cpp
|
||||
CPPDEFS += -DRTCLOCK
|
||||
CPPSRC += rtc.cpp targets/mega2560/rtc_driver.cpp
|
||||
CPPSRC += rtc.cpp targets/mega2560/rtc_driver.cpp sdcard.cpp
|
||||
endif
|
||||
|
||||
# Enable extra rotary encoders (Gruvin9x board only)
|
||||
@@ -657,6 +674,7 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO))
|
||||
CPPDEFS += -DVOICE
|
||||
INCDIRS += FatFs FatFs/option
|
||||
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/sky9x/diskio.cpp
|
||||
CPPSRC += sdcard.cpp
|
||||
endif
|
||||
ifeq ($(BUZZER), YES)
|
||||
CPPDEFS += -DBUZZER
|
||||
@@ -713,6 +731,9 @@ ifeq ($(PCB), TARANIS)
|
||||
ifeq ($(DEBUG_TRACE_BUFFER), YES)
|
||||
CPPDEFS += -DDEBUG_TRACE_BUFFER
|
||||
endif
|
||||
ifeq ($(TARANIS_INTERNAL_PPM), YES)
|
||||
CPPDEFS += -DTARANIS_INTERNAL_PPM
|
||||
endif
|
||||
LDSCRIPT = targets/taranis/stm32_flash_bl.ld
|
||||
TRGT = arm-none-eabi-
|
||||
MCU = cortex-m3
|
||||
@@ -792,7 +813,8 @@ ifeq ($(PCB), TARANIS)
|
||||
LUADEP = lua_exports.cpp
|
||||
endif
|
||||
ifeq ($(SDCARD), YES)
|
||||
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/taranis/diskio.cpp
|
||||
EXTRABOARDSRC += FatFs/ff.c FatFs/fattime.c FatFs/option/ccsbcs.c targets/taranis/diskio.cpp
|
||||
CPPSRC += sdcard.cpp
|
||||
CPPDEFS += -DVOICE
|
||||
INCDIRS += FatFs FatFs/option
|
||||
endif
|
||||
@@ -813,8 +835,8 @@ ifeq ($(PCB), TARANIS)
|
||||
CPPSRC += haptic.cpp
|
||||
CPPSRC += targets/taranis/haptic_driver.cpp
|
||||
endif
|
||||
ifeq ($(CHANNELS_MONITOR_INV_HIDE), YES)
|
||||
CPPDEFS += -DCHANNELS_MONITOR_INV_HIDE
|
||||
ifeq ($(MIXERS_MONITOR), YES)
|
||||
CPPDEFS += -DMIXERS_MONITOR
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -848,7 +870,9 @@ else
|
||||
TTS_SRC = $(shell sh -c "if test -f $(STD_TTS_SRC); then echo $(STD_TTS_SRC); else echo translations/tts_en.cpp; fi")
|
||||
endif
|
||||
|
||||
CPPSRC += opentx.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp gui/menus.cpp gui/menu_model.cpp gui/menu_general.cpp gui/view_main.cpp gui/view_statistics.cpp $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC)
|
||||
CPPSRC += opentx.cpp strhelpers.cpp stamp.cpp translations.cpp fonts.cpp $(TTS_SRC)
|
||||
CPPSRC += switches.cpp curves.cpp mixer.cpp timers.cpp $(PULSESSRC) $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp
|
||||
CPPSRC += gui/menus.cpp gui/menu_model.cpp gui/menu_general.cpp gui/view_main.cpp gui/view_statistics.cpp
|
||||
|
||||
# Debugging format.
|
||||
# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
|
||||
@@ -1379,8 +1403,20 @@ FOXLIB=-L/usr/local/lib \
|
||||
-lFOX-1.6 \
|
||||
-Wl,-rpath,$(FOXPATH)/src/.libs
|
||||
|
||||
SIMUDEFS = -DSIMU -DLUA_USE_APICHECK
|
||||
ifeq ($(SIMU_AUDIO), YES)
|
||||
AUDIOLIB = -L/usr/lib/x86_64-linux-gnu/ -lSDLmain -lSDL
|
||||
AUDIOINC = -I/usr/include/SDL
|
||||
SIMUDEFS += -DSIMU_AUDIO
|
||||
endif
|
||||
|
||||
ifeq ($(SIMU_DISKIO), YES)
|
||||
CPPSRC += FatFs/ff.c FatFs/option/ccsbcs.c
|
||||
SIMUDEFS += -DSIMU_DISKIO
|
||||
endif
|
||||
|
||||
simu: $(LUADEP) stamp_header $(BOARDSRC) $(CPPSRC) Makefile simu.cpp targets/simu/simpgmspace.cpp *.h tra lbm eeprom.bin
|
||||
g++ $(CPPFLAGS) $(INCFLAGS) simu.cpp $(BOARDSRC) $(CPPSRC) $(LUASRC) targets/simu/simpgmspace.cpp -MD -DSIMU -DLUA_USE_APICHECK -O0 -o simu $(FOXINC) $(FOXLIB) -pthread -fexceptions
|
||||
g++ $(CPPFLAGS) $(INCFLAGS) simu.cpp $(BOARDSRC) $(CPPSRC) $(LUASRC) targets/simu/simpgmspace.cpp -MD $(SIMUDEFS) -O0 -o simu $(FOXINC) $(FOXLIB) $(AUDIOINC) $(AUDIOLIB) -pthread -fexceptions
|
||||
|
||||
eeprom.bin:
|
||||
dd if=/dev/zero of=$@ bs=1 count=2048
|
||||
|
||||
+30
-3
@@ -360,14 +360,17 @@ void referenceModelAudioFiles()
|
||||
|
||||
// Eliminates directories / non wav files
|
||||
if (len < 5 || strcasecmp(fn+len-4, SOUNDS_EXT) || (fno.fattrib & AM_DIR)) continue;
|
||||
TRACE("referenceModelAudioFiles(): using file: %s", fn);
|
||||
|
||||
// Phases Audio Files <phasename>-[on|off].wav
|
||||
for (int i=0; i<MAX_FLIGHT_MODES && !found; i++) {
|
||||
for (int event=0; event<2; event++) {
|
||||
getPhaseAudioFile(path, i, event);
|
||||
// TRACE("referenceModelAudioFiles(): searching for %s in %s", filename, fn);
|
||||
if (!strcasecmp(filename, fn)) {
|
||||
sdAvailablePhaseAudioFiles |= MASK_PHASE_AUDIO_FILE(i, event);
|
||||
found = true;
|
||||
TRACE("\tfound: %s", filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -376,9 +379,11 @@ void referenceModelAudioFiles()
|
||||
// Switches Audio Files <switchname>-[up|mid|down].wav
|
||||
for (int i=0; i<SWSRC_LAST_SWITCH+NUM_XPOTS*XPOTS_MULTIPOS_COUNT && !found; i++) {
|
||||
getSwitchAudioFile(path, i);
|
||||
// TRACE("referenceModelAudioFiles(): searching for %s in %s", filename, fn);
|
||||
if (!strcasecmp(filename, fn)) {
|
||||
sdAvailableSwitchAudioFiles |= MASK_SWITCH_AUDIO_FILE(i);
|
||||
found = true;
|
||||
TRACE("\tfound: %s", filename);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,9 +391,11 @@ void referenceModelAudioFiles()
|
||||
for (int i=0; i<NUM_LOGICAL_SWITCH && !found; i++) {
|
||||
for (int event=0; event<2; event++) {
|
||||
getLogicalSwitchAudioFile(path, i, event);
|
||||
// TRACE("referenceModelAudioFiles(): searching for %s in %s", filename, fn);
|
||||
if (!strcasecmp(filename, fn)) {
|
||||
sdAvailableLogicalSwitchAudioFiles |= MASK_LOGICAL_SWITCH_AUDIO_FILE(i, event);
|
||||
found = true;
|
||||
TRACE("\tfound: %s", filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -496,10 +503,14 @@ void audioTask(void* pdata)
|
||||
|
||||
void mixSample(uint16_t * result, int sample, unsigned int fade)
|
||||
{
|
||||
#if defined(SIMU)
|
||||
*result = limit(0, *result + ((sample >> fade) ), 0xFFFF);
|
||||
#else
|
||||
*result = limit(0, *result + ((sample >> fade) >> 4), 4095);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(SDCARD) && !defined(SIMU)
|
||||
#if defined(SDCARD)
|
||||
|
||||
#define RIFF_CHUNK_SIZE 12
|
||||
uint8_t wavBuffer[AUDIO_BUFFER_SIZE*2];
|
||||
@@ -692,7 +703,11 @@ void AudioQueue::wakeup()
|
||||
|
||||
// write silence in the buffer
|
||||
for (uint32_t i=0; i<AUDIO_BUFFER_SIZE; i++) {
|
||||
#if defined(SIMU)
|
||||
buffer->data[i] = 0x8000; /* silence */
|
||||
#else
|
||||
buffer->data[i] = 0x8000 >> 4; /* silence */
|
||||
#endif
|
||||
}
|
||||
|
||||
// mix the priority context (only tones)
|
||||
@@ -748,6 +763,7 @@ void AudioQueue::wakeup()
|
||||
// push the buffer if needed
|
||||
if (size > 0) {
|
||||
__disable_irq();
|
||||
// TRACE("pushing buffer %d\n", bufferWIdx);
|
||||
bufferWIdx = nextBufferIdx(bufferWIdx);
|
||||
buffer->size = size;
|
||||
buffer->state = dacQueue(buffer) ? AUDIO_BUFFER_PLAYING : AUDIO_BUFFER_FILLED;
|
||||
@@ -790,6 +806,10 @@ bool AudioQueue::isPlaying(uint8_t id)
|
||||
|
||||
void AudioQueue::playTone(uint16_t freq, uint16_t len, uint16_t pause, uint8_t flags, int8_t freqIncr)
|
||||
{
|
||||
#if defined(SIMU) && !defined(SIMU_AUDIO)
|
||||
return;
|
||||
#endif
|
||||
|
||||
CoEnterMutexSection(audioMutex);
|
||||
|
||||
if (freq && freq < BEEP_MIN_FREQ) {
|
||||
@@ -844,7 +864,11 @@ void AudioQueue::playFile(const char *filename, uint8_t flags, uint8_t id)
|
||||
{
|
||||
#if defined(SIMU)
|
||||
TRACE("playFile(\"%s\", flags=%x, id=%d)", filename, flags, id);
|
||||
#else
|
||||
#endif
|
||||
|
||||
#if defined(SIMU) && !defined(SIMU_AUDIO)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!sdMounted())
|
||||
return;
|
||||
@@ -880,7 +904,6 @@ void AudioQueue::playFile(const char *filename, uint8_t flags, uint8_t id)
|
||||
}
|
||||
|
||||
CoLeaveMutexSection(audioMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioQueue::stopPlay(uint8_t id)
|
||||
@@ -889,6 +912,10 @@ void AudioQueue::stopPlay(uint8_t id)
|
||||
TRACE("stopPlay(id=%d)", id);
|
||||
#endif
|
||||
|
||||
#if defined(SIMU) && !defined(SIMU_AUDIO)
|
||||
return;
|
||||
#endif
|
||||
|
||||
// For the moment it's only needed to stop the background music
|
||||
if (backgroundContext.fragment.id == id) {
|
||||
backgroundContext.fragment.type = FRAGMENT_EMPTY;
|
||||
|
||||
+22
-3
@@ -45,7 +45,11 @@
|
||||
#define AUDIO_SAMPLE_RATE (32000)
|
||||
#define AUDIO_BUFFER_DURATION (10)
|
||||
#define AUDIO_BUFFER_SIZE (AUDIO_SAMPLE_RATE*AUDIO_BUFFER_DURATION/1000)
|
||||
#define AUDIO_BUFFER_COUNT (3)
|
||||
#if defined(SIMU)
|
||||
#define AUDIO_BUFFER_COUNT (10) // simulator needs more buffers for smooth audio
|
||||
#else
|
||||
#define AUDIO_BUFFER_COUNT (3)
|
||||
#endif
|
||||
|
||||
#define BEEP_MIN_FREQ (150)
|
||||
#define BEEP_DEFAULT_FREQ (2250)
|
||||
@@ -154,6 +158,9 @@ bool dacQueue(AudioBuffer *buffer);
|
||||
class AudioQueue {
|
||||
|
||||
friend void audioTask(void* pdata);
|
||||
#if defined(SIMU)
|
||||
friend void *audio_thread(void *);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@@ -195,7 +202,7 @@ class AudioQueue {
|
||||
}
|
||||
|
||||
uint8_t idx = bufferRIdx;
|
||||
while (idx != bufferWIdx) {
|
||||
do {
|
||||
AudioBuffer * buffer = &buffers[idx];
|
||||
if (buffer->state == AUDIO_BUFFER_FILLED) {
|
||||
buffer->state = AUDIO_BUFFER_PLAYING;
|
||||
@@ -203,11 +210,23 @@ class AudioQueue {
|
||||
return buffer;
|
||||
}
|
||||
idx = nextBufferIdx(idx);
|
||||
}
|
||||
} while (idx != bufferWIdx); //this fixes a bug if all buffers are filled
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool filledAtleast(int noBuffers) {
|
||||
int count = 0;
|
||||
for(int n= 0; n<AUDIO_BUFFER_COUNT; ++n) {
|
||||
if (buffers[n].state == AUDIO_BUFFER_FILLED) {
|
||||
if (++count >= noBuffers) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void wakeup();
|
||||
|
||||
+1
-1
@@ -278,7 +278,7 @@ const struct TraceElement * getTraceElement(uint16_t idx)
|
||||
|
||||
void dumpTraceBuffer()
|
||||
{
|
||||
TRACE("Dump of Trace Buffer ("VERS_STR " " DATE_STR " " TIME_STR "):");
|
||||
TRACE("Dump of Trace Buffer (" VERS_STR " " DATE_STR " " TIME_STR "):");
|
||||
TRACE("# Time Event Data");
|
||||
for(int n = 0; n < TRACE_BUFFER_LEN; ++n) {
|
||||
struct gtm tp;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "opentx.h"
|
||||
#include "inttypes.h"
|
||||
#include "string.h"
|
||||
#include "timers.h"
|
||||
|
||||
volatile uint32_t Spi_complete; // TODO in the driver ?
|
||||
|
||||
@@ -398,11 +399,7 @@ void eeLoadModel(uint8_t id)
|
||||
activeFunctions = 0;
|
||||
memclear(lastFunctionTime, sizeof(lastFunctionTime));
|
||||
|
||||
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
||||
if (g_model.timers[i].persistent) {
|
||||
timersStates[i].val = g_model.timers[i].value;
|
||||
}
|
||||
}
|
||||
restoreTimers();
|
||||
|
||||
resumeMixerCalculations();
|
||||
// TODO pulses should be started after mixer calculations ...
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "opentx.h"
|
||||
#include "inttypes.h"
|
||||
#include "string.h"
|
||||
#include "timers.h"
|
||||
|
||||
uint8_t s_write_err = 0; // error reasons
|
||||
RlcFile theFile; //used for any file operation
|
||||
@@ -985,13 +986,7 @@ void eeLoadModel(uint8_t id)
|
||||
activeFunctions = 0;
|
||||
memclear(lastFunctionTime, sizeof(lastFunctionTime));
|
||||
|
||||
#if !defined(PCBSTD)
|
||||
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
||||
if (g_model.timers[i].persistent) {
|
||||
timersStates[i].val = g_model.timers[i].value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
restoreTimers();
|
||||
|
||||
#if defined(CPUARM)
|
||||
if (g_model.frsky.mAhPersistent) {
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
/*/*.lbm
|
||||
/font_*.png
|
||||
/font_*.specs
|
||||
|
||||
@@ -693,11 +693,17 @@ void menuGeneralSdManagerInfo(uint8_t event)
|
||||
lcd_puts(10*FW, 2*FH, SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD);
|
||||
|
||||
lcd_putsLeft(3*FH, STR_SD_SIZE);
|
||||
lcd_outdezAtt(10*FW, 3*FH, SD_GET_SIZE_MB(), LEFT);
|
||||
lcd_outdezAtt(10*FW, 3*FH, sdGetSize(), LEFT);
|
||||
lcd_putc(lcdLastPos, 3*FH, 'M');
|
||||
|
||||
lcd_putsLeft(4*FH, STR_SD_SECTORS);
|
||||
lcd_outdezAtt(10*FW, 4*FH, SD_GET_BLOCKNR()/1000, LEFT);
|
||||
#if defined(SD_GET_FREE_BLOCKNR)
|
||||
lcd_outdezAtt(10*FW, 4*FH, SD_GET_FREE_BLOCKNR()/1000, LEFT);
|
||||
lcd_putc(lcdLastPos, 4*FH, '/');
|
||||
lcd_outdezAtt(lcdLastPos+FW, 4*FH, sdGetNoSectors()/1000, LEFT);
|
||||
#else
|
||||
lcd_outdezAtt(10*FW, 4*FH, sdGetNoSectors()/1000, LEFT);
|
||||
#endif
|
||||
lcd_putc(lcdLastPos, 4*FH, 'k');
|
||||
|
||||
lcd_putsLeft(5*FH, STR_SD_SPEED);
|
||||
@@ -933,7 +939,7 @@ void menuGeneralSdManager(uint8_t _event)
|
||||
case EVT_KEY_LONG(KEY_MENU):
|
||||
if (!READ_ONLY()) {
|
||||
killEvents(_event);
|
||||
// MENU_ADD_ITEM(STR_SD_INFO); TODO: Implement
|
||||
MENU_ADD_ITEM(STR_SD_INFO);
|
||||
MENU_ADD_ITEM(STR_SD_FORMAT);
|
||||
menuHandler = onSdManagerMenu;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
*/
|
||||
|
||||
#include "../opentx.h"
|
||||
#include "../timers.h"
|
||||
#ifdef MAVLINK
|
||||
#include "gui/view_mavlink.h"
|
||||
#endif
|
||||
|
||||
@@ -41,6 +41,10 @@ void menuChannelsView(uint8_t event)
|
||||
static bool longNames = false;
|
||||
bool newLongNames = false;
|
||||
static bool secondPage = false;
|
||||
#ifdef MIXERS_MONITOR
|
||||
static bool mixersView = false;
|
||||
#endif
|
||||
|
||||
uint8_t ch;
|
||||
|
||||
switch(event)
|
||||
@@ -52,14 +56,25 @@ void menuChannelsView(uint8_t event)
|
||||
case EVT_KEY_FIRST(KEY_LEFT):
|
||||
secondPage = !secondPage;
|
||||
break;
|
||||
#ifdef MIXERS_MONITOR
|
||||
case EVT_KEY_FIRST(KEY_ENTER):
|
||||
mixersView = !mixersView;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (secondPage)
|
||||
ch = 16;
|
||||
else
|
||||
ch = 0;
|
||||
|
||||
lcd_putsCenter(0*FH, CHANNELS_MONITOR);
|
||||
#ifdef MIXERS_MONITOR
|
||||
if (mixersView)
|
||||
lcd_putsCenter(0*FH, MIXERS_MONITOR);
|
||||
else
|
||||
#endif
|
||||
lcd_putsCenter(0*FH, CHANNELS_MONITOR);
|
||||
|
||||
lcd_invert_line(0);
|
||||
|
||||
// Column separator
|
||||
@@ -72,13 +87,12 @@ void menuChannelsView(uint8_t event)
|
||||
// Channels
|
||||
for (uint8_t line=0; line<8; line++) {
|
||||
uint8_t y = 9+line*7;
|
||||
#ifdef MIXERS_MONITOR
|
||||
int32_t val = (mixersView) ? ex_chans[ch] : channelOutputs[ch];
|
||||
#else
|
||||
int32_t val = channelOutputs[ch];
|
||||
uint8_t ofs = (col ? 0 : 1);
|
||||
|
||||
#if defined(CHANNELS_MONITOR_INV_HIDE)
|
||||
//if channel output is inverted, show it with oposite sign
|
||||
if (g_model.limitData[ch].revert) val = -val;
|
||||
#endif
|
||||
uint8_t ofs = (col ? 0 : 1);
|
||||
|
||||
// Channel name if present, number if not
|
||||
uint8_t lenLabel = ZLEN(g_model.limitData[ch].name);
|
||||
@@ -105,7 +119,11 @@ void menuChannelsView(uint8_t event)
|
||||
|
||||
// Gauge
|
||||
lcd_rect(x+LCD_W/2-3-wbar-ofs, y, wbar+1, 6);
|
||||
#ifdef MIXERS_MONITOR
|
||||
uint16_t lim = mixersView ? 512*2*2 : (g_model.extendedLimits ? 640*2 : 512*2);
|
||||
#else
|
||||
uint16_t lim = g_model.extendedLimits ? 640*2 : 512*2;
|
||||
#endif
|
||||
uint8_t len = limit((uint8_t)1, uint8_t((abs(val) * wbar/2 + lim/2) / lim), uint8_t(wbar/2));
|
||||
uint8_t x0 = (val>0) ? x+LCD_W/2-ofs-3-wbar/2 : x+LCD_W/2-ofs-2-wbar/2-len;
|
||||
lcd_hline(x0, y+1, len);
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "../opentx.h"
|
||||
#include "../timers.h"
|
||||
|
||||
#if LCD_W >= 212
|
||||
#define BIGSIZE MIDSIZE
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "../opentx.h"
|
||||
#include "../timers.h"
|
||||
|
||||
void menuStatisticsView(uint8_t event)
|
||||
{
|
||||
|
||||
@@ -50,8 +50,8 @@ bar_threshold_t barsThresholds[THLD_MAX];
|
||||
uint8_t s_frsky_view = 0;
|
||||
|
||||
#if LCD_W >= 212
|
||||
#define BAR_LEFT 26
|
||||
#define BAR_WIDTH 157
|
||||
#define BAR_LEFT 30
|
||||
#define BAR_WIDTH 153
|
||||
#else
|
||||
#define BAR_LEFT 25
|
||||
#define BAR_WIDTH 100
|
||||
@@ -118,9 +118,9 @@ void displayGpsCoord(uint8_t y, char direction, int16_t bp, int16_t ap)
|
||||
lcd_outdezNAtt(lcdLastPos+FW+FW+1, y, mn, LEFT|LEADING0, 2); // mm before '.'
|
||||
lcd_vline(lcdLastPos, y, 2);
|
||||
uint16_t ss = ap * 6;
|
||||
lcd_outdezAtt(lcdLastPos+3, y, ss / 1000, LEFT); // ''
|
||||
lcd_outdezNAtt(lcdLastPos+3, y, ss / 1000, LEFT|LEADING0, 2); // ''
|
||||
lcd_plot(lcdLastPos, y+FH-2, 0); // small decimal point
|
||||
lcd_outdezAtt(lcdLastPos+2, y, ss % 1000, LEFT); // ''
|
||||
lcd_outdezNAtt(lcdLastPos+2, y, ss % 1000, LEFT|LEADING0, 3); // ''
|
||||
lcd_vline(lcdLastPos, y, 2);
|
||||
lcd_vline(lcdLastPos+2, y, 2);
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "timers.h"
|
||||
|
||||
uint8_t displayBuf[DISPLAY_BUF_SIZE];
|
||||
|
||||
@@ -510,28 +511,28 @@ void lcd_line(xcoord_t x1, int8_t y1, xcoord_t x2, int8_t y2, uint8_t pat, LcdFl
|
||||
if (dxabs >= dyabs) {
|
||||
/* the line is more horizontal than vertical */
|
||||
for (int i=0; i<=dxabs; i++) {
|
||||
if ((1<<(px%8)) & pat) {
|
||||
lcd_plot(px, py, att);
|
||||
}
|
||||
y += dyabs;
|
||||
if (y>=dxabs) {
|
||||
y -= dxabs;
|
||||
py += sdy;
|
||||
}
|
||||
if ((1<<(px%8)) & pat) {
|
||||
lcd_plot(px, py, att);
|
||||
}
|
||||
px += sdx;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* the line is more vertical than horizontal */
|
||||
for (int i=0; i<=dyabs; i++) {
|
||||
if ((1<<(py%8)) & pat) {
|
||||
lcd_plot(px, py, att);
|
||||
}
|
||||
x += dxabs;
|
||||
if (x >= dyabs) {
|
||||
x -= dyabs;
|
||||
px += sdx;
|
||||
}
|
||||
if ((1<<(py%8)) & pat) {
|
||||
lcd_plot(px, py, att);
|
||||
}
|
||||
py += sdy;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
|
||||
void lcd_mask(uint8_t *p, uint8_t mask, LcdFlags att)
|
||||
{
|
||||
// ASSERT_IN_DISPLAY(p);
|
||||
if ((p) >= DISPLAY_END) {
|
||||
return;
|
||||
}
|
||||
@@ -66,9 +65,7 @@ void lcd_plot(xcoord_t x, uint8_t y, LcdFlags att)
|
||||
{
|
||||
uint8_t *p = &displayBuf[ y / 2 * LCD_W + x ];
|
||||
uint8_t mask = PIXEL_GREY_MASK(y, att);
|
||||
if (p<DISPLAY_END) {
|
||||
lcd_mask(p, mask, att);
|
||||
}
|
||||
lcd_mask(p, mask, att);
|
||||
}
|
||||
|
||||
void lcd_hlineStip(xcoord_t x, uint8_t y, xcoord_t w, uint8_t pat, LcdFlags att)
|
||||
@@ -168,13 +165,15 @@ void lcd_bmp(xcoord_t x, uint8_t y, const pm_uchar * img, uint8_t offset, uint8_
|
||||
q = img + 2 + row*w + offset;
|
||||
uint8_t *p = &displayBuf[(row + (y/2)) * LCD_W + x];
|
||||
for (xcoord_t i=0; i<width; i++) {
|
||||
if ((p) >= DISPLAY_END) {
|
||||
if (p >= DISPLAY_END) {
|
||||
return;
|
||||
}
|
||||
uint8_t b = pgm_read_byte(q++);
|
||||
if (y & 1) {
|
||||
*p = (*p & 0x0f) + ((b & 0x0f) << 4);
|
||||
*(p+LCD_W) = (*(p+LCD_W) & 0xf0) + ((b & 0xf0) >> 4);
|
||||
if ((p+LCD_W) < DISPLAY_END) {
|
||||
*(p+LCD_W) = (*(p+LCD_W) & 0xf0) + ((b & 0xf0) >> 4);
|
||||
}
|
||||
}
|
||||
else {
|
||||
*p = b;
|
||||
|
||||
+3
-1
@@ -59,6 +59,9 @@ const pm_char * openLogs()
|
||||
if (!sdMounted())
|
||||
return STR_NO_SDCARD;
|
||||
|
||||
if (sdGetFreeSectors() == 0)
|
||||
return STR_SDCARD_FULL;
|
||||
|
||||
strcpy_P(filename, STR_LOGS_PATH);
|
||||
|
||||
result = f_opendir(&folder, filename);
|
||||
@@ -172,7 +175,6 @@ getvalue_t getConvertedTelemetryValue(getvalue_t val, uint8_t unit)
|
||||
return val;
|
||||
}
|
||||
|
||||
// TODO test when disk full
|
||||
void writeLogs()
|
||||
{
|
||||
static const pm_char * error_displayed = NULL;
|
||||
|
||||
+33
-38
@@ -38,6 +38,7 @@
|
||||
#include <stdio.h>
|
||||
#include "opentx.h"
|
||||
#include "stamp-opentx.h"
|
||||
#include "timers.h"
|
||||
|
||||
#if !defined(SIMU)
|
||||
extern "C" {
|
||||
@@ -624,35 +625,31 @@ static int luaModelResetTimer(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getFirstInput(int chn)
|
||||
static unsigned int getFirstInput(unsigned int chn)
|
||||
{
|
||||
for (int i=0; i<MAX_INPUTS; i++) {
|
||||
for (unsigned int i=0; i<MAX_INPUTS; i++) {
|
||||
ExpoData * expo = expoAddress(i);
|
||||
if (!expo->srcRaw || expo->chn>chn) break;
|
||||
if (expo->chn == chn) {
|
||||
if (!expo->srcRaw || expo->chn >= chn) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int getInputsCountFromFirst(int chn, int first)
|
||||
static unsigned int getInputsCountFromFirst(unsigned int chn, unsigned int first)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
if (first >= 0) {
|
||||
for (int i=first; i<MAX_INPUTS; i++) {
|
||||
ExpoData * expo = expoAddress(i);
|
||||
if (!expo->srcRaw || expo->chn!=chn) break;
|
||||
count++;
|
||||
}
|
||||
for (unsigned int i=first; i<MAX_INPUTS; i++) {
|
||||
ExpoData * expo = expoAddress(i);
|
||||
if (!expo->srcRaw || expo->chn!=chn) break;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static unsigned int getInputsCount(int chn)
|
||||
static unsigned int getInputsCount(unsigned int chn)
|
||||
{
|
||||
int first = getFirstInput(chn);
|
||||
return getInputsCountFromFirst(chn, first);
|
||||
return getInputsCountFromFirst(chn, getFirstInput(chn));
|
||||
}
|
||||
|
||||
static int luaModelGetInputsCount(lua_State *L)
|
||||
@@ -667,15 +664,16 @@ static int luaModelGetInput(lua_State *L)
|
||||
{
|
||||
unsigned int chn = luaL_checkunsigned(L, 1);
|
||||
unsigned int idx = luaL_checkunsigned(L, 2);
|
||||
int first = getFirstInput(chn);
|
||||
unsigned int first = getFirstInput(chn);
|
||||
unsigned int count = getInputsCountFromFirst(chn, first);
|
||||
if (first>=0 && idx<count) {
|
||||
if (idx < count) {
|
||||
ExpoData * expo = expoAddress(first+idx);
|
||||
lua_newtable(L);
|
||||
lua_pushtablezstring(L, "name", expo->name);
|
||||
lua_pushtableinteger(L, "source", expo->srcRaw);
|
||||
lua_pushtableinteger(L, "weight", expo->weight);
|
||||
lua_pushtableinteger(L, "offset", expo->offset);
|
||||
lua_pushtableinteger(L, "switch", expo->swtch);
|
||||
}
|
||||
else {
|
||||
lua_pushnil(L);
|
||||
@@ -688,12 +686,12 @@ static int luaModelInsertInput(lua_State *L)
|
||||
unsigned int chn = luaL_checkunsigned(L, 1);
|
||||
unsigned int idx = luaL_checkunsigned(L, 2);
|
||||
|
||||
int first = getFirstInput(chn);
|
||||
unsigned int first = getFirstInput(chn);
|
||||
unsigned int count = getInputsCountFromFirst(chn, first);
|
||||
|
||||
if (chn<MAX_INPUTS && getExpoMixCount(1)<MAX_INPUTS && idx<=count) {
|
||||
idx = first+idx;
|
||||
s_currCh = chn+1;
|
||||
idx = first + idx;
|
||||
s_currCh = chn + 1;
|
||||
insertExpoMix(1, idx);
|
||||
ExpoData * expo = expoAddress(idx);
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
@@ -730,7 +728,7 @@ static int luaModelDeleteInput(lua_State *L)
|
||||
int first = getFirstInput(chn);
|
||||
unsigned int count = getInputsCountFromFirst(chn, first);
|
||||
|
||||
if (first>=0 && idx<count) {
|
||||
if (idx < count) {
|
||||
deleteExpoMix(1, first+idx);
|
||||
}
|
||||
|
||||
@@ -749,9 +747,9 @@ static int luaModelDefaultInputs(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getFirstMix(int chn)
|
||||
static unsigned int getFirstMix(unsigned int chn)
|
||||
{
|
||||
for (int i=0; i<MAX_MIXERS; i++) {
|
||||
for (unsigned int i=0; i<MAX_MIXERS; i++) {
|
||||
MixData * mix = mixAddress(i);
|
||||
if (!mix->srcRaw || mix->destCh>=chn) {
|
||||
return i;
|
||||
@@ -760,29 +758,26 @@ static int getFirstMix(int chn)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getMixesCountFromFirst(int chn, int first)
|
||||
static unsigned int getMixesCountFromFirst(unsigned int chn, unsigned int first)
|
||||
{
|
||||
int count = 0;
|
||||
if (first >= 0) {
|
||||
for (int i=first; i<MAX_MIXERS; i++) {
|
||||
MixData * mix = mixAddress(i);
|
||||
if (!mix->srcRaw || mix->destCh!=chn) break;
|
||||
count++;
|
||||
}
|
||||
unsigned int count = 0;
|
||||
for (unsigned int i=first; i<MAX_MIXERS; i++) {
|
||||
MixData * mix = mixAddress(i);
|
||||
if (!mix->srcRaw || mix->destCh!=chn) break;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static int getMixesCount(int chn)
|
||||
static unsigned int getMixesCount(unsigned int chn)
|
||||
{
|
||||
int first = getFirstMix(chn);
|
||||
return getMixesCountFromFirst(chn, first);
|
||||
return getMixesCountFromFirst(chn, getFirstMix(chn));
|
||||
}
|
||||
|
||||
static int luaModelGetMixesCount(lua_State *L)
|
||||
{
|
||||
unsigned int chn = luaL_checkunsigned(L, 1);
|
||||
int count = getMixesCount(chn);
|
||||
unsigned int count = getMixesCount(chn);
|
||||
lua_pushinteger(L, count);
|
||||
return 1;
|
||||
}
|
||||
@@ -791,7 +786,7 @@ static int luaModelGetMix(lua_State *L)
|
||||
{
|
||||
unsigned int chn = luaL_checkunsigned(L, 1);
|
||||
unsigned int idx = luaL_checkunsigned(L, 2);
|
||||
int first = getFirstMix(chn);
|
||||
unsigned int first = getFirstMix(chn);
|
||||
unsigned int count = getMixesCountFromFirst(chn, first);
|
||||
if (idx < count) {
|
||||
MixData * mix = mixAddress(first+idx);
|
||||
@@ -823,7 +818,7 @@ static int luaModelInsertMix(lua_State *L)
|
||||
unsigned int chn = luaL_checkunsigned(L, 1);
|
||||
unsigned int idx = luaL_checkunsigned(L, 2);
|
||||
|
||||
int first = getFirstMix(chn);
|
||||
unsigned int first = getFirstMix(chn);
|
||||
unsigned int count = getMixesCountFromFirst(chn, first);
|
||||
|
||||
if (chn<NUM_CHNOUT && getExpoMixCount(0)<MAX_MIXERS && idx<=count) {
|
||||
@@ -892,7 +887,7 @@ static int luaModelDeleteMix(lua_State *L)
|
||||
unsigned int chn = luaL_checkunsigned(L, 1);
|
||||
unsigned int idx = luaL_checkunsigned(L, 2);
|
||||
|
||||
int first = getFirstMix(chn);
|
||||
unsigned int first = getFirstMix(chn);
|
||||
unsigned int count = getMixesCountFromFirst(chn, first);
|
||||
|
||||
if (idx < count) {
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "timers.h"
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
int8_t virtualInputsTrims[NUM_INPUTS];
|
||||
|
||||
+3
-135
@@ -35,6 +35,7 @@
|
||||
*/
|
||||
|
||||
#include "opentx.h"
|
||||
#include "timers.h"
|
||||
|
||||
#if defined(CPUARM)
|
||||
#define MENUS_STACK_SIZE 2000
|
||||
@@ -1646,14 +1647,6 @@ uint16_t s_timeCum16ThrP; // THR% in 1/16 sec
|
||||
|
||||
uint8_t trimsCheckTimer = 0;
|
||||
|
||||
void timerReset(uint8_t idx)
|
||||
{
|
||||
TimerState & timerState = timersStates[idx];
|
||||
timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
|
||||
timerState.val = g_model.timers[idx].start;
|
||||
timerState.val_10ms = 0 ;
|
||||
}
|
||||
|
||||
void flightReset()
|
||||
{
|
||||
// we don't reset the whole audio here (the tada.wav would be cut, if a prompt is queued before FlightReset, it should be played)
|
||||
@@ -1678,8 +1671,6 @@ void flightReset()
|
||||
RESET_THR_TRACE();
|
||||
}
|
||||
|
||||
TimerState timersStates[MAX_TIMERS] = { { 0 }, { 0 } };
|
||||
|
||||
#if defined(THRTRACE)
|
||||
uint8_t s_traceBuf[MAXTRACE];
|
||||
uint8_t s_traceWr;
|
||||
@@ -2003,13 +1994,8 @@ void evalFunctions()
|
||||
|
||||
#if defined(CPUARM)
|
||||
case FUNC_SET_TIMER:
|
||||
{
|
||||
TimerState & timerState = timersStates[CFN_TIMER_INDEX(sd)];
|
||||
timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
|
||||
timerState.val = CFN_PARAM(sd);
|
||||
timerState.val_10ms = 0 ;
|
||||
timerSet(CFN_TIMER_INDEX(sd), CFN_PARAM(sd));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GVARS)
|
||||
@@ -2249,13 +2235,6 @@ void doMixerCalculations()
|
||||
|
||||
if (tick10ms) {
|
||||
|
||||
#if !defined(CPUM64) && !defined(ACCURAT_THROTTLE_TIMER)
|
||||
// code cost is about 16 bytes for higher throttle accuracy for timer
|
||||
// would not be noticable anyway, because all version up to this change had only 16 steps;
|
||||
// now it has already 32 steps; this define would increase to 128 steps
|
||||
#define ACCURAT_THROTTLE_TIMER
|
||||
#endif
|
||||
|
||||
/* Throttle trace */
|
||||
int16_t val;
|
||||
|
||||
@@ -2309,95 +2288,7 @@ void doMixerCalculations()
|
||||
val >>= (RESX_SHIFT-4); // calibrate it
|
||||
#endif
|
||||
|
||||
// Timers start
|
||||
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
||||
int8_t tm = g_model.timers[i].mode;
|
||||
uint16_t tv = g_model.timers[i].start;
|
||||
TimerState * timerState = &timersStates[i];
|
||||
|
||||
if (tm) {
|
||||
if (timerState->state == TMR_OFF) {
|
||||
timerState->state = TMR_RUNNING;
|
||||
timerState->cnt = 0;
|
||||
timerState->sum = 0;
|
||||
}
|
||||
|
||||
if (tm == TMRMODE_THR_REL) {
|
||||
timerState->cnt++;
|
||||
timerState->sum+=val;
|
||||
}
|
||||
|
||||
if ((timerState->val_10ms += tick10ms) >= 100) {
|
||||
timerState->val_10ms -= 100 ;
|
||||
int16_t newTimerVal = timerState->val;
|
||||
if (tv) newTimerVal = tv - newTimerVal;
|
||||
|
||||
if (tm == TMRMODE_ABS) {
|
||||
newTimerVal++;
|
||||
}
|
||||
else if (tm == TMRMODE_THR) {
|
||||
if (val) newTimerVal++;
|
||||
}
|
||||
else if (tm == TMRMODE_THR_REL) {
|
||||
// @@@ open.20.fsguruh: why so complicated? we have already a s_sum field; use it for the half seconds (not showable) as well
|
||||
// check for s_cnt[i]==0 is not needed because we are shure it is at least 1
|
||||
#if defined(ACCURAT_THROTTLE_TIMER)
|
||||
if ((timerState->sum/timerState->cnt) >= 128) { // throttle was normalized to 0 to 128 value (throttle/64*2 (because - range is added as well)
|
||||
newTimerVal++; // add second used of throttle
|
||||
timerState->sum -= 128*timerState->cnt;
|
||||
}
|
||||
#else
|
||||
if ((timerState->sum/timerState->cnt) >= 32) { // throttle was normalized to 0 to 32 value (throttle/16*2 (because - range is added as well)
|
||||
newTimerVal++; // add second used of throttle
|
||||
timerState->sum -= 32*timerState->cnt;
|
||||
}
|
||||
#endif
|
||||
timerState->cnt=0;
|
||||
}
|
||||
else if (tm == TMRMODE_THR_TRG) {
|
||||
if (val) {
|
||||
timerState->state = TMR_TRIGGED;
|
||||
}
|
||||
if (timerState->state == TMR_TRIGGED) {
|
||||
newTimerVal++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tm > 0) tm -= (TMRMODE_COUNT-1);
|
||||
if (getSwitch(tm))
|
||||
newTimerVal++;
|
||||
}
|
||||
|
||||
switch (timerState->state) {
|
||||
case TMR_RUNNING:
|
||||
if (tv && newTimerVal>=(int16_t)tv) {
|
||||
AUDIO_TIMER_00(g_model.timers[i].countdownBeep);
|
||||
timerState->state = TMR_NEGATIVE;
|
||||
}
|
||||
break;
|
||||
case TMR_NEGATIVE:
|
||||
if (newTimerVal >= (int16_t)tv + MAX_ALERT_TIME) timerState->state = TMR_STOPPED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tv) newTimerVal = tv - newTimerVal; // if counting backwards - display backwards
|
||||
|
||||
if (newTimerVal != timerState->val) {
|
||||
timerState->val = newTimerVal;
|
||||
if (timerState->state == TMR_RUNNING) {
|
||||
if (g_model.timers[i].countdownBeep && g_model.timers[i].start) {
|
||||
if (newTimerVal==30) AUDIO_TIMER_30();
|
||||
if (newTimerVal==20) AUDIO_TIMER_20();
|
||||
if (newTimerVal<=10) AUDIO_TIMER_LT10(g_model.timers[i].countdownBeep, newTimerVal);
|
||||
}
|
||||
if (g_model.timers[i].minuteBeep && (newTimerVal % 60)==0) {
|
||||
AUDIO_TIMER_MINUTE(newTimerVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} //endfor timer loop (only two)
|
||||
evalTimers(val, tick10ms);
|
||||
|
||||
static uint8_t s_cnt_100ms;
|
||||
static uint8_t s_cnt_1s;
|
||||
@@ -3289,29 +3180,6 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
|
||||
AUDIO_WARNING2();
|
||||
}
|
||||
|
||||
#if defined(CPUARM) || defined(CPUM2560)
|
||||
void saveTimers()
|
||||
{
|
||||
for (uint8_t i=0; i<MAX_TIMERS; i++) {
|
||||
if (g_model.timers[i].persistent) {
|
||||
TimerState *timerState = &timersStates[i];
|
||||
if (g_model.timers[i].value != (uint16_t)timerState->val) {
|
||||
g_model.timers[i].value = timerState->val;
|
||||
eeDirty(EE_MODEL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CPUARM) && !defined(REVA)
|
||||
if (sessionTimer > 0) {
|
||||
g_eeGeneral.globalTimer += sessionTimer;
|
||||
eeDirty(EE_GENERAL);
|
||||
sessionTimer = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ROTARY_ENCODERS)
|
||||
volatile rotenc_t g_rotenc[ROTARY_ENCODERS] = {0};
|
||||
#elif defined(ROTARY_ENCODER_NAVIGATION)
|
||||
|
||||
+9
-22
@@ -258,6 +258,15 @@
|
||||
#define convertSimuPath(x) (x)
|
||||
#endif
|
||||
|
||||
#if !defined(CPUM64) && !defined(ACCURAT_THROTTLE_TIMER)
|
||||
// code cost is about 16 bytes for higher throttle accuracy for timer
|
||||
// would not be noticable anyway, because all version up to this change had only 16 steps;
|
||||
// now it has already 32 steps; this define would increase to 128 steps
|
||||
#if !defined(ACCURAT_THROTTLE_TIMER)
|
||||
#define ACCURAT_THROTTLE_TIMER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// RESX range is used for internal calculation; The menu says -100.0 to 100.0; internally it is -1024 to 1024 to allow some optimizations
|
||||
#define RESX_SHIFT 10
|
||||
#define RESX 1024
|
||||
@@ -849,16 +858,6 @@ extern uint16_t sessionTimer;
|
||||
extern uint16_t s_timeCumThr;
|
||||
extern uint16_t s_timeCum16ThrP;
|
||||
|
||||
struct TimerState {
|
||||
uint16_t cnt;
|
||||
uint16_t sum;
|
||||
uint8_t state;
|
||||
int16_t val;
|
||||
uint8_t val_10ms;
|
||||
};
|
||||
|
||||
extern TimerState timersStates[MAX_TIMERS];
|
||||
|
||||
#if defined(OVERRIDE_CHANNEL_FUNCTION)
|
||||
#if defined(CPUARM)
|
||||
typedef int16_t safetych_t;
|
||||
@@ -872,12 +871,6 @@ extern safetych_t safetyCh[NUM_CHNOUT];
|
||||
|
||||
extern uint8_t trimsCheckTimer;
|
||||
|
||||
#define TMR_OFF 0
|
||||
#define TMR_RUNNING 1
|
||||
#define TMR_NEGATIVE 2
|
||||
#define TMR_STOPPED 3
|
||||
#define TMR_TRIGGED 4
|
||||
void timerReset(uint8_t idx);
|
||||
void flightReset();
|
||||
|
||||
extern uint8_t unexpectedShutdown;
|
||||
@@ -1043,12 +1036,6 @@ inline void resumeMixerCalculations()
|
||||
#define resumeMixerCalculations()
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM) || defined(CPUM2560)
|
||||
void saveTimers();
|
||||
#else
|
||||
#define saveTimers()
|
||||
#endif
|
||||
|
||||
void generalDefault();
|
||||
void modelDefault(uint8_t id);
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ void setupPulsesPPM(unsigned int port) // Don't enable interru
|
||||
uint32_t lastCh = min<unsigned int>(NUM_CHNOUT, firstCh + 8 + g_model.moduleData[port].channelsCount);
|
||||
|
||||
#if defined(PCBSKY9X)
|
||||
// TODO move register stuff to driver
|
||||
register Pwm *pwmptr = PWM;
|
||||
uint32_t pwmCh = (port == EXTERNAL_MODULE ? 3 : 1);
|
||||
pwmptr->PWM_CH_NUM[pwmCh].PWM_CDTYUPD = (g_model.moduleData[port].ppmDelay * 50 + 300) * 2; //Stoplen *2
|
||||
@@ -78,25 +79,19 @@ void setupPulsesPPM(unsigned int port) // Don't enable interru
|
||||
*(ptr + 1) = 0;
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
rest -= 1000;
|
||||
uint32_t ppmDelay = (g_model.moduleData[port].ppmDelay * 50 + 300) * 2;
|
||||
// set idle time, ppm delay and ppm polarity
|
||||
if (port == TRAINER_MODULE) {
|
||||
TIM3->CCR2 = rest - 1000 ; // Update time
|
||||
TIM3->CCR4 = (g_model.moduleData[port].ppmDelay*50+300)*2;
|
||||
if (!g_model.moduleData[TRAINER_MODULE].ppmPulsePol)
|
||||
TIM3->CCER |= TIM_CCER_CC4P;
|
||||
else
|
||||
TIM3->CCER &= ~TIM_CCER_CC4P;
|
||||
set_trainer_ppm_parameters(rest, ppmDelay, !g_model.moduleData[TRAINER_MODULE].ppmPulsePol); // ppmPulsePol: 0 - positive, 1 - negative
|
||||
}
|
||||
else if (port == EXTERNAL_MODULE) {
|
||||
TIM8->CCR2 = rest - 1000; // Update time
|
||||
TIM8->CCR1 = (g_model.moduleData[port].ppmDelay*50+300)*2;
|
||||
if(!g_model.moduleData[EXTERNAL_MODULE].ppmPulsePol)
|
||||
TIM8->CCER |= TIM_CCER_CC1NP;
|
||||
else
|
||||
TIM8->CCER &= ~TIM_CCER_CC1NP;
|
||||
set_external_ppm_parameters(rest, ppmDelay, !g_model.moduleData[EXTERNAL_MODULE].ppmPulsePol);
|
||||
}
|
||||
else {
|
||||
TIM1->CCR2 = rest - 1000; // Update time
|
||||
TIM1->CCR3 = (g_model.moduleData[port].ppmDelay*50+300)*2;
|
||||
#if defined(TARANIS_INTERNAL_PPM)
|
||||
else if (port == INTERNAL_MODULE) {
|
||||
set_internal_ppm_parameters(rest, ppmDelay, !g_model.moduleData[INTERNAL_MODULE].ppmPulsePol);
|
||||
}
|
||||
#endif // #if defined(TARANIS_INTERNAL_PPM)
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Authors (alphabetical order)
|
||||
* - Andre Bernet <bernet.andre@gmail.com>
|
||||
* - Andreas Weitl
|
||||
* - Bertrand Songis <bsongis@gmail.com>
|
||||
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
|
||||
* - Cameron Weeks <th9xer@gmail.com>
|
||||
* - Erez Raviv
|
||||
* - Gabriel Birkus
|
||||
* - Jean-Pierre Parisy
|
||||
* - Karl Szmutny
|
||||
* - Michael Blandford
|
||||
* - Michal Hlavinka
|
||||
* - Pat Mackenzie
|
||||
* - Philip Moss
|
||||
* - Rob Thomson
|
||||
* - Romolo Manfredini <romolo.manfredini@gmail.com>
|
||||
* - Thomas Husterer
|
||||
*
|
||||
* opentx is based on code named
|
||||
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
|
||||
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
|
||||
* and the original (and ongoing) project by
|
||||
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include "../../FatFs/diskio.h"
|
||||
#include "../../FatFs/ff.h"
|
||||
|
||||
|
||||
#if !defined(SIMU) || defined(SIMU_DISKIO)
|
||||
uint32_t sdGetNoSectors()
|
||||
{
|
||||
static DWORD noSectors = 0;
|
||||
if (noSectors == 0 ) {
|
||||
disk_ioctl(0, GET_SECTOR_COUNT, &noSectors);
|
||||
}
|
||||
return noSectors;
|
||||
}
|
||||
|
||||
uint32_t sdGetSize()
|
||||
{
|
||||
return (sdGetNoSectors() * 512) / 1000000;
|
||||
}
|
||||
|
||||
uint32_t sdGetFreeSectors()
|
||||
{
|
||||
DWORD nofree;
|
||||
FATFS * fat;
|
||||
if (f_getfree("", &nofree, &fat) != FR_OK) {
|
||||
return 0;
|
||||
}
|
||||
return nofree * fat->csize;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
uint32_t sdGetNoSectors()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t sdGetSize()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t sdGetFreeSectors()
|
||||
{
|
||||
return 10;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user