Compare commits
510 Commits
2.2.0-RC16
...
2.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
| cca7180834 | |||
| 104ab8c7f3 | |||
| e4d273aa0e | |||
| df61a1ab4e | |||
| 1dcd8cc419 | |||
| b55b68f191 | |||
| 2c2339e229 | |||
| d7645252bb | |||
| dc89bb1dfc | |||
| 47383fd053 | |||
| f80406c7cb | |||
| 75b382e619 | |||
| 566c616abb | |||
| 59d2ef8aa1 | |||
| 977262232a | |||
| fa5895de39 | |||
| f2fb788eac | |||
| c8c3b79f2d | |||
| 1c7012726a | |||
| e3bbbdcecf | |||
| 4e8867c819 | |||
| cffb5e767f | |||
| 204711d313 | |||
| e43807540e | |||
| eb79d4f774 | |||
| e80b63f66f | |||
| ada0712e1a | |||
| 0a7aece40f | |||
| 63bcb4693d | |||
| dec630efa0 | |||
| 2a0984408f | |||
| 8e5027dcb2 | |||
| f489742c9e | |||
| bcc6e3c67d | |||
| 12ad7b0d9c | |||
| a6044a684d | |||
| 9c27947345 | |||
| c96a30aea0 | |||
| 934578118b | |||
| 81dbebb663 | |||
| afd3103506 | |||
| 8b34c96a2d | |||
| ec2c4302cb | |||
| 23eeccec9c | |||
| 421f16d0dd | |||
| cb73261c60 | |||
| 6bc02fd838 | |||
| a7e4b0b062 | |||
| 4b75c42218 | |||
| 4a187699fa | |||
| b4710f0f0c | |||
| 99c4c4a0ef | |||
| adb9a55719 | |||
| 078748243d | |||
| eaa5c7a7b0 | |||
| 8dafd4680b | |||
| 6c6fc2d7db | |||
| 3eccbc2963 | |||
| d90ac05d6e | |||
| bdf0983642 | |||
| 16f219d6d3 | |||
| ba1073ace6 | |||
| 1d5c06ccd6 | |||
| afeba0d07e | |||
| 4ad2bbdf2c | |||
| 0faee13bc3 | |||
| e74349e36c | |||
| 2c2bbdd912 | |||
| d772cd39ea | |||
| 13f364d96a | |||
| 779b39e237 | |||
| 0f34bf3850 | |||
| f085f11ea8 | |||
| 1c1624b8a6 | |||
| caa9cd3060 | |||
| b8042c9da1 | |||
| 478411bf82 | |||
| 49a63d43b3 | |||
| 5b4dc4ee08 | |||
| 2cf2603155 | |||
| 462e5f05e6 | |||
| 3caf83e920 | |||
| 58df785d70 | |||
| 4c0526ce0c | |||
| 6c2de17229 | |||
| d649420212 | |||
| 7f53f340ad | |||
| c4c5516315 | |||
| 8662de39f5 | |||
| f2cf444a64 | |||
| 1634d81e4a | |||
| 9c74cc215c | |||
| 659f506e5f | |||
| 7df776e7ed | |||
| 5762fd61e9 | |||
| 39ea315c97 | |||
| 6fc40cb7cb | |||
| 0658b2a2c4 | |||
| 6064d3222b | |||
| d13fb8918f | |||
| d11618eb3f | |||
| 3b4f5e0882 | |||
| 01f5c65eb9 | |||
| 94bdeb6929 | |||
| f36615f1e2 | |||
| ab4b159d06 | |||
| 90e58e4a5f | |||
| 7759403f3e | |||
| 18aa849cc7 | |||
| a9c25d1935 | |||
| 7f4daf3f5b | |||
| f7828ad4a3 | |||
| 2631ad00bd | |||
| d4a00dec3b | |||
| 46e8474e77 | |||
| c8dfccc365 | |||
| 2e14773f1a | |||
| 968fbd4c60 | |||
| 37b7b25208 | |||
| a2c6d60782 | |||
| 808e44388a | |||
| f8ff44c78f | |||
| 7e29932072 | |||
| c1b0e9fea3 | |||
| df91e93034 | |||
| fd265eccbb | |||
| 57d53abd6e | |||
| c62e0cc7d1 | |||
| e5b2b8ef64 | |||
| e6542a78d0 | |||
| 084680b5fd | |||
| bdfcc5d181 | |||
| 2d6962d937 | |||
| d8210b832f | |||
| ac22e33cec | |||
| 7f05df2627 | |||
| 9d7dab724b | |||
| b8b67ba864 | |||
| f6309138f6 | |||
| 7ca3f60999 | |||
| f0f3e35bf6 | |||
| c30ff28f85 | |||
| 5a121bfcb8 | |||
| 613b2edf49 | |||
| 8e9d370770 | |||
| 69afa9d0f8 | |||
| 955d5775cb | |||
| 6c7e4b5597 | |||
| ff8f4a3a92 | |||
| 2e248e7bc0 | |||
| f9d5201b0c | |||
| baa3938f06 | |||
| 12a0d6d5bc | |||
| 0f8c868d6b | |||
| 761b0e0cfa | |||
| 5bb759a0e7 | |||
| 1ef1109b5f | |||
| 36789bff3f | |||
| d8f1ad3a82 | |||
| f197aa52ac | |||
| fdec738485 | |||
| e2858dbb03 | |||
| 8d75f9c991 | |||
| 8c6b5717f7 | |||
| 63536b9819 | |||
| 8780339c72 | |||
| 90542b189c | |||
| 83766bc3f6 | |||
| 6a61a911de | |||
| 7b074305af | |||
| 973716fbfa | |||
| b153cdec93 | |||
| c63ad89a8c | |||
| 9a95b47c96 | |||
| b4cf7315a5 | |||
| d775a09095 | |||
| 318d77e863 | |||
| 1962336316 | |||
| 3fed1aa157 | |||
| 176845047d | |||
| 62662159e1 | |||
| c932090ed5 | |||
| 24b8ead576 | |||
| cb2e9be6cd | |||
| 6ff301bf27 | |||
| fe3a7babcc | |||
| f611942f61 | |||
| 979e93c7be | |||
| 83383df4dd | |||
| a54c0a435e | |||
| 3d8f1c4780 | |||
| 64a4f10ec7 | |||
| 380adaad3b | |||
| 69118a96be | |||
| 6a14fe728e | |||
| b58be017f4 | |||
| 408a44110f | |||
| aa527fc6bd | |||
| cbd824eb10 | |||
| a1c0aafc16 | |||
| fd782538d8 | |||
| 710e6ddc4c | |||
| 3ce754137d | |||
| f4ea92d1fc | |||
| 24917a9952 | |||
| f60ea00fb8 | |||
| 851da15bc7 | |||
| f6e7b4e291 | |||
| a502a99768 | |||
| 39386676d8 | |||
| f48d6bba35 | |||
| fcbb23af92 | |||
| 7f7dfeab12 | |||
| 450ba42558 | |||
| 76f27ae452 | |||
| 6bb7ba3795 | |||
| 509df44c4f | |||
| 9cb4b782e1 | |||
| 6f3577c9a5 | |||
| 06f5e408ee | |||
| 0402c37a07 | |||
| 7ae9bfef0f | |||
| 1bfcdb5dfa | |||
| 2983cfc531 | |||
| d80861db37 | |||
| 23ceb830b3 | |||
| 4c5f0ca83c | |||
| 1b370076b6 | |||
| 9415b3086d | |||
| e7fcc71d8e | |||
| 7e21e13ec9 | |||
| 360a521f11 | |||
| 53d4547918 | |||
| 2d0c14c3c0 | |||
| b9fd1b01d1 | |||
| 45213124dd | |||
| 76371d6087 | |||
| 37c0589a27 | |||
| da71f4cbbc | |||
| 093034f9e7 | |||
| a7b9b30108 | |||
| 6a2a730cdc | |||
| 97b777ae4f | |||
| 09f257026e | |||
| e59afb6ec1 | |||
| b7acee5723 | |||
| 2910488a30 | |||
| 67817918f4 | |||
| 390342af78 | |||
| 653273f82e | |||
| b33a88a69f | |||
| 7cd7869d6a | |||
| 9ae429e03b | |||
| 0053412f87 | |||
| 63baa76cba | |||
| bd6bd4deeb | |||
| 5b5c88fb4e | |||
| fdacf83ad0 | |||
| 8e04a6e2e4 | |||
| 5791645877 | |||
| 6cc40c65b2 | |||
| 1bb8aab866 | |||
| 13b566746d | |||
| 4b5bd10aa2 | |||
| 251e83b1a4 | |||
| d4f108a849 | |||
| 19219bf8f8 | |||
| 74db7dafa7 | |||
| 9bc8fc493d | |||
| abe857225a | |||
| 9c46b9afa0 | |||
| a41d2af10d | |||
| 42cbc56880 | |||
| 9ba843d82f | |||
| 81589d22f8 | |||
| 576be96935 | |||
| f487cdd581 | |||
| bf177d6cce | |||
| e16b48db30 | |||
| 8e84724c62 | |||
| 2f7694dee7 | |||
| 019e2aee1b | |||
| 8cb7031cf6 | |||
| a167e9f751 | |||
| 824f39330f | |||
| bf600140d3 | |||
| 871302a1b1 | |||
| 5a8a074f0c | |||
| 0e139fd0d6 | |||
| de00d223c4 | |||
| 8d8fef23c9 | |||
| 51be7b000e | |||
| 87295776ff | |||
| b3e9d8d97d | |||
| 96f1a16744 | |||
| 7d386e7821 | |||
| ee258b8ec8 | |||
| 0641adc5f4 | |||
| 045294d53b | |||
| 169df7130b | |||
| 49e252337e | |||
| 7906107d6c | |||
| e3d881be76 | |||
| bd968bd60f | |||
| 541aa459cf | |||
| c82c7ee5db | |||
| 76e72c8a86 | |||
| 6304f0daf6 | |||
| e00efb1566 | |||
| 258347fbd1 | |||
| 7434e330c8 | |||
| b55070f939 | |||
| a7524ba74d | |||
| 3436273fdf | |||
| 4dcd49a516 | |||
| 2f4ed3b35f | |||
| b814f997f8 | |||
| e37872398e | |||
| 3b7c3fb217 | |||
| e04aa4b3cc | |||
| 1bb6a82cf3 | |||
| 022f7121b4 | |||
| cc19c8027a | |||
| 7dfb5b6a28 | |||
| 397b78fe06 | |||
| 1e2f4d6c0c | |||
| 387cd98efe | |||
| 7eddd662e7 | |||
| 21f61fe498 | |||
| 0437314ae3 | |||
| 21e8551787 | |||
| 129bbe2198 | |||
| cfcac8c51d | |||
| eaeb90dc07 | |||
| ae68dea923 | |||
| 1ae8e40a3f | |||
| 779aecfbee | |||
| 1c62b19f9f | |||
| c00775b2d1 | |||
| b7b7c48d8e | |||
| 76ffd4fcb4 | |||
| 9ad5094909 | |||
| 0fd23d3e61 | |||
| a587f8b825 | |||
| fb1098c16e | |||
| 97ef444648 | |||
| c672d2544b | |||
| 72ca1b021a | |||
| 044b3a706c | |||
| 4c40aec8b3 | |||
| 4226e9cc45 | |||
| f659e98a52 | |||
| 97b2aa804d | |||
| 8e07f9b0f4 | |||
| 656daa75fa | |||
| 547606b44e | |||
| 15a29f3a43 | |||
| ab81838d87 | |||
| 854ce93c07 | |||
| 08ae9ddedb | |||
| 3f5a3995cc | |||
| 2a86918508 | |||
| f50ee3fb39 | |||
| bae44d2812 | |||
| 2e4775b19a | |||
| 655e2f9010 | |||
| a4008a2550 | |||
| 9e39dfa9d7 | |||
| 94ee3c65b3 | |||
| d609d37798 | |||
| d0a57d4c47 | |||
| 726b989f6c | |||
| 5f76e61240 | |||
| 42d66bb2c1 | |||
| e4135a9adb | |||
| fe1146b62c | |||
| 7956bd6bab | |||
| 32142e25ea | |||
| 85bb6ea3a7 | |||
| d5e42992d2 | |||
| fbdcef3733 | |||
| a13c857b53 | |||
| 85863358fb | |||
| b397af1bac | |||
| 0906bdc6d7 | |||
| 77925f6abc | |||
| 0a0893e6cc | |||
| 3d17023bc9 | |||
| fd16151850 | |||
| 2ae0472f76 | |||
| cd23fedb56 | |||
| 1cb0156cd0 | |||
| 4880c029b7 | |||
| c79994d812 | |||
| f462af1b0e | |||
| 8729bbc41b | |||
| 0fc1681d5c | |||
| 69576cb17d | |||
| 1a85956dcb | |||
| 01150497bb | |||
| 0ed7f5a5ad | |||
| ce83cf00e0 | |||
| 8eea072cd1 | |||
| 4d23292ad3 | |||
| 618832974e | |||
| c80fbf2de7 | |||
| 5b69ceff0d | |||
| 3cc3687dcb | |||
| eb7c73668f | |||
| d35d3b5e22 | |||
| 935518f6dd | |||
| 20dcee3a5c | |||
| 5825a2ec2c | |||
| 355f4b5f92 | |||
| 9437d98df9 | |||
| 7a8ca1c675 | |||
| 79d9359e56 | |||
| 006166a25c | |||
| 33cc0861a6 | |||
| d48ab63497 | |||
| bd62281144 | |||
| 50397d0052 | |||
| 460e6aab96 | |||
| 95b0a21cfc | |||
| f7b6d95910 | |||
| 6e0bec9db4 | |||
| 83132ef041 | |||
| c1586b72bb | |||
| ca25696d1a | |||
| 11579d9118 | |||
| 32714fb841 | |||
| 2bc2030f86 | |||
| 93dbdf8680 | |||
| 301e33a271 | |||
| 53bb8bc6c3 | |||
| e2502772cb | |||
| 24de312a30 | |||
| efe53eb034 | |||
| 96ccb4cb3f | |||
| 3f06037e1b | |||
| 38d8f6a326 | |||
| 2bec60517a | |||
| d3b8133ee2 | |||
| 4b2b5a9d37 | |||
| 6edc3b61ff | |||
| f525b1762b | |||
| 4f5f241669 | |||
| 0b25332171 | |||
| 054c87c91e | |||
| e053abfc3e | |||
| 6abd36d628 | |||
| 582546f8ed | |||
| c1e7235375 | |||
| 975023bdc7 | |||
| 4df32f8247 | |||
| 630dec62f5 | |||
| a58a541bb6 | |||
| 0cff67e032 | |||
| 72b1ad085f | |||
| 04bcc70422 | |||
| d5eec9b8dc | |||
| 36afe4127c | |||
| 572463bb0d | |||
| 6f066253f0 | |||
| f3cbc37067 | |||
| 37b0dab9da | |||
| c6d15c6f37 | |||
| 73f4b8f172 | |||
| 3aceed62c9 | |||
| f10bad7abe | |||
| c15922a942 | |||
| c2a6a20fc1 | |||
| 37155363ff | |||
| b0183efaf1 | |||
| 6dd8524ea5 | |||
| 50cb102a34 | |||
| be20e90630 | |||
| c15a86dc19 | |||
| b790a844f1 | |||
| faacf7f9c5 | |||
| f9b7f567c3 | |||
| 591522c25a | |||
| 9193604aff | |||
| 1ad8769fff | |||
| fbc3bac6d3 | |||
| ea5401084c | |||
| 902473fe6f | |||
| bc6ed93b0f | |||
| b5f5e64d95 | |||
| fa951acf40 | |||
| 189b65b724 | |||
| 6e427bca74 | |||
| 0c260ce12d | |||
| 9a93d85ef6 | |||
| 46f0384828 | |||
| 54c1f22312 | |||
| 2b41ba94ff | |||
| 471c38628f | |||
| b0b270963c | |||
| a719c391a1 | |||
| 13e6ae1d08 | |||
| c6148c109c | |||
| 95bc595f50 | |||
| 1d6f2acbc2 | |||
| 5d5c915ea9 | |||
| f795528d21 | |||
| 1d4ec6f73e | |||
| 723b5df4f1 | |||
| b8e0f26a22 | |||
| 22217e8e22 |
@@ -1 +1,112 @@
|
||||
# Handle line endings automatically for files detected as text
|
||||
# and leave all files detected as binary untouched.
|
||||
* text=auto
|
||||
|
||||
#
|
||||
# The above will handle all files NOT found below
|
||||
#
|
||||
# These files are text and should be normalized (Convert crlf => lf)
|
||||
|
||||
# Source files
|
||||
*.c text
|
||||
*.cc text
|
||||
*.cxx text
|
||||
*.cpp text
|
||||
*.c++ text
|
||||
*.hpp text
|
||||
*.h text
|
||||
*.h++ text
|
||||
*.hh text
|
||||
*.lua text
|
||||
*.pxd text
|
||||
*.py text
|
||||
*.py3 text
|
||||
*.pyw text
|
||||
*.pyx text
|
||||
*.pl text
|
||||
*.pm text
|
||||
*.sln text eol=crlf
|
||||
*.csproj text eol=crlf
|
||||
*.vbproj text eol=crlf
|
||||
*.vcxproj text eol=crlf
|
||||
*.vcproj text eol=crlf
|
||||
*.dbproj text eol=crlf
|
||||
*.fsproj text eol=crlf
|
||||
*.lsproj text eol=crlf
|
||||
*.wixproj text eol=crlf
|
||||
*.modelproj text eol=crlf
|
||||
*.sqlproj text eol=crlf
|
||||
*.wmaproj text eol=crlf
|
||||
*.xproj text eol=crlf
|
||||
*.props text eol=crlf
|
||||
*.filters text eol=crlf
|
||||
*.vcxitems text eol=crlf
|
||||
*.sh eol=lf
|
||||
|
||||
# Compiled Object files
|
||||
*.slo binary
|
||||
*.lo binary
|
||||
*.o binary
|
||||
*.obj binary
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch binary
|
||||
*.pch binary
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so binary
|
||||
*.dylib binary
|
||||
*.dll binary
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai binary
|
||||
*.la binary
|
||||
*.a binary
|
||||
*.lib binary
|
||||
|
||||
# Executables
|
||||
*.exe binary
|
||||
*.out binary
|
||||
*.app binary
|
||||
|
||||
# Binary files
|
||||
*.db binary
|
||||
*.p binary
|
||||
*.pkl binary
|
||||
*.pyc binary
|
||||
*.pyd binary
|
||||
*.pyo binary
|
||||
|
||||
# Documents
|
||||
*.doc diff=astextplain
|
||||
*.DOC diff=astextplain
|
||||
*.docx diff=astextplain
|
||||
*.DOCX diff=astextplain
|
||||
*.dot diff=astextplain
|
||||
*.DOT diff=astextplain
|
||||
*.pdf diff=astextplain
|
||||
*.PDF diff=astextplain
|
||||
*.rtf diff=astextplain
|
||||
*.RTF diff=astextplain
|
||||
*.md text
|
||||
*.adoc text
|
||||
*.textile text
|
||||
*.mustache text
|
||||
*.csv text
|
||||
*.tab text
|
||||
*.tsv text
|
||||
*.sql text
|
||||
|
||||
# Graphics
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.gif binary
|
||||
*.tif binary
|
||||
*.tiff binary
|
||||
*.ico binary
|
||||
# SVG treated as an asset (binary) by default. If you want to treat it as text,
|
||||
# comment-out the following line and uncomment the line after.
|
||||
*.svg binary
|
||||
#*.svg text
|
||||
*.eps binary
|
||||
|
||||
@@ -18,6 +18,7 @@ env:
|
||||
# - QT_BASE=57
|
||||
#- GCC_ARM=/opt/gcc-arm-none-eabi/bin
|
||||
- AVR_FLAVORS="AVR9X 9X GRUVIN9X MEGA2560"
|
||||
- PYTHONPATH=${PYTHONPATH}:/usr/lib/python3/dist-packages
|
||||
matrix:
|
||||
#
|
||||
# ALL will build every individual board & DEFAULT, sequentially.
|
||||
@@ -72,5 +73,21 @@ install:
|
||||
fi
|
||||
- sudo apt-get install --yes --force-yes -qq qt${QT_BASE}base qt${QT_BASE}multimedia qt${QT_BASE}svg qt${QT_BASE}tools; source /opt/qt${QT_BASE}/bin/qt${QT_BASE}-env.sh
|
||||
|
||||
addons:
|
||||
sonarcloud:
|
||||
organization: "opentx-github"
|
||||
token:
|
||||
secure: "BuQrGRijNpL2V/IQNcOxvjChj8PScfCdiv403EE73Nqb4+sB8YL92Fnzrnw9bC8wF7BVSDJVpYF0gbdaTzuCmaeZfM8NJK0TOJAbH6+B8bhIrU/V1SBuVjHQnndV/wysieruKnK/KxYJZqItgSlnPo+PmiFxtXJNlas0Kstb2O4="
|
||||
# github_token:
|
||||
# secure: "Qkmp4VrQJtKgZ/pz65SNnCDiF4slgFfQS/3whyLXLcDbFb1Hv1oj7Hqz9EVDUSO2eEhgQGaOKkRc0CfAAOBwW6OvhE0xh7P1CJEjzOp6+3gI/LyZUNsqa+awVRZTsfm1YZaOPaPWJ7cI0uz3/OoSUeIecs4PDWPrQMGRlsrq7Q8="
|
||||
branches:
|
||||
- "2.2"
|
||||
|
||||
script:
|
||||
- ./tools/commit-tests.sh
|
||||
- build-wrapper-linux-x86-64 --out-dir bw_output ./tools/commit-tests.sh
|
||||
- sonar-scanner
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- '$HOME/.sonar/cache'
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@ project(OpenTX)
|
||||
|
||||
set(VERSION_MAJOR "2")
|
||||
set(VERSION_MINOR "2")
|
||||
set(VERSION_REVISION "0")
|
||||
set(VERSION_REVISION "1")
|
||||
set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX})
|
||||
set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR})
|
||||
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX})
|
||||
set(SDCARD_REVISION "0009")
|
||||
set(SDCARD_REVISION "0013")
|
||||
set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION})
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
@@ -62,6 +62,16 @@ if(WIN32)
|
||||
list(APPEND CMAKE_PREFIX_PATH "${WIN_EXTRA_LIBS_PATH}" "${WIN_EXTRA_LIBS_PATH}/SDL") # hints for FindSDL
|
||||
endif()
|
||||
|
||||
# Python check
|
||||
find_package("PythonInterp")
|
||||
if(PYTHONINTERP_FOUND)
|
||||
message(STATUS "Python found, version: ${PYTHON_VERSION_STRING}")
|
||||
get_filename_component(PYTHON_DIRECTORY ${PYTHON_EXECUTABLE} DIRECTORY)
|
||||
else()
|
||||
message(WARNING "Python not found! Most firmware and simu flavors not buildable.")
|
||||
set(LUA NO)
|
||||
endif()
|
||||
|
||||
find_package(Qt5Core)
|
||||
find_package(Qt5Widgets)
|
||||
find_package(Qt5Xml)
|
||||
@@ -133,6 +143,9 @@ if(Qt5Core_FOUND OR FOX_FOUND)
|
||||
find_package("SDL")
|
||||
if(SDL_FOUND)
|
||||
message(STATUS "SDL Lib: ${SDL_LIBRARY}; Headers: ${SDL_INCLUDE_DIR}; Version: ${SDL_VERSION_STRING}")
|
||||
if (NOT ${SDL_VERSION_STRING} VERSION_LESS "2.0")
|
||||
message(FATAL_ERROR "OpenTX requires SDL 1.x, not 2.x")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "SDL not found! Simulator audio, and joystick inputs, will not work.")
|
||||
endif()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
## OpenTX 2.2 Branch
|
||||
|
||||
[](https://travis-ci.org/opentx/opentx)
|
||||
[](https://scan.coverity.com/projects/opentx-opentx)
|
||||
[](https://travis-ci.org/opentx/opentx)
|
||||
[](https://sonarcloud.io/dashboard?id=OpenTX:2.2)
|
||||
[](https://opentx.rocket.chat)
|
||||
[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DJ9MASSKVW8WN)
|
||||
|
||||
@@ -10,7 +10,6 @@ The ongoing development on 2.2.x is done in this branch.
|
||||
Refer to the [OpenTX wiki](https://github.com/opentx/opentx/wiki) for information about setting up the tool chains for building OpenTX and OpenTX Companion as well as other development related issues.
|
||||
|
||||
Useful links:
|
||||
* OpenTX Blog http://blog.open-tx.org/
|
||||
* OpenTX Main Site http://www.open-tx.org/
|
||||
* OpenTx University http://open-txu.org/
|
||||
* OpenTX User Manual https://www.gitbook.com/book/opentx/opentx-taranis-manual/details
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
# Find Xerces-C
|
||||
# The following setings are defined
|
||||
# XERCESC_ROOT_DIR, the root of the include and lib directory
|
||||
# XERCESC_INCLUDE_DIR, the full path of the include dir (ADVANCED)
|
||||
# XERCESC_LIBRARIES, the name of the xerces-c library (ADVANCED)
|
||||
|
||||
# Look for a root installation
|
||||
IF( MSVC )
|
||||
SET( XERCES_WINDIR C:/Programs/xerces-vc )
|
||||
ELSE( )
|
||||
SET( XERCES_WINDIR C:/Programs/xerces )
|
||||
ENDIF( )
|
||||
|
||||
FIND_PATH(XERCESC_ROOT_DIR include/xercesc/parsers/SAXParser.hpp
|
||||
${XERCES_WINDIR}
|
||||
"C:/mingw/msys/1.0/local"
|
||||
"C:/Program Files/CodeSynthesis XSD 3.2"
|
||||
/usr
|
||||
/usr/local
|
||||
"C:/MinGW"
|
||||
$ENV{CODESYNTH}
|
||||
DOC "The root of an installed xerces-c installation"
|
||||
)
|
||||
|
||||
# try to find the header
|
||||
FIND_PATH(XERCESC_INCLUDE_DIR xercesc/parsers/SAXParser.hpp
|
||||
${XERCESC_ROOT_DIR}/include
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
# Find the library
|
||||
FIND_LIBRARY(XERCESC_LIBRARY
|
||||
NAMES xerces-c xerces-c_3
|
||||
PATHS
|
||||
${XERCESC_ROOT_DIR}/lib
|
||||
${XERCESC_ROOT_DIR}/lib/vc-9.0
|
||||
${XERCESC_ROOT_DIR}/lib64/vc-9.0
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
DOC "The name of the xerces-c library"
|
||||
)
|
||||
|
||||
IF (XERCESC_ROOT_DIR)
|
||||
IF (XERCESC_INCLUDE_DIR AND XERCESC_LIBRARY)
|
||||
SET (XERCESC_FOUND TRUE)
|
||||
SET (XERCESC_LIBRARIES "${XERCESC_LIBRARY}")
|
||||
# FIXME: There should be a better way of handling this?
|
||||
# FIXME: How can we test to see if the lib dir isn't
|
||||
# FIXME: one of the default dirs?
|
||||
LINK_DIRECTORIES(${XERCESC_ROOT_DIR}/lib)
|
||||
ENDIF (XERCESC_INCLUDE_DIR AND XERCESC_LIBRARY)
|
||||
ENDIF (XERCESC_ROOT_DIR)
|
||||
|
||||
IF (XERCESC_FOUND)
|
||||
IF (NOT XERCESC_FIND_QUIETLY)
|
||||
MESSAGE (STATUS " found xerces-c: ${XERCESC_LIBRARY}")
|
||||
ENDIF (NOT XERCESC_FIND_QUIETLY)
|
||||
ELSE (XERCESC_FOUND)
|
||||
IF (XERCESC_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find Xerces-C")
|
||||
ENDIF (XERCESC_FIND_REQUIRED)
|
||||
ENDIF (XERCESC_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
XERCESC_INCLUDE_DIR
|
||||
XERCESC_LIBRARY
|
||||
# Find Xerces-C
|
||||
# The following setings are defined
|
||||
# XERCESC_ROOT_DIR, the root of the include and lib directory
|
||||
# XERCESC_INCLUDE_DIR, the full path of the include dir (ADVANCED)
|
||||
# XERCESC_LIBRARIES, the name of the xerces-c library (ADVANCED)
|
||||
|
||||
# Look for a root installation
|
||||
IF( MSVC )
|
||||
SET( XERCES_WINDIR C:/Programs/xerces-vc )
|
||||
ELSE( )
|
||||
SET( XERCES_WINDIR C:/Programs/xerces )
|
||||
ENDIF( )
|
||||
|
||||
FIND_PATH(XERCESC_ROOT_DIR include/xercesc/parsers/SAXParser.hpp
|
||||
${XERCES_WINDIR}
|
||||
"C:/mingw/msys/1.0/local"
|
||||
"C:/Program Files/CodeSynthesis XSD 3.2"
|
||||
/usr
|
||||
/usr/local
|
||||
"C:/MinGW"
|
||||
$ENV{CODESYNTH}
|
||||
DOC "The root of an installed xerces-c installation"
|
||||
)
|
||||
|
||||
# try to find the header
|
||||
FIND_PATH(XERCESC_INCLUDE_DIR xercesc/parsers/SAXParser.hpp
|
||||
${XERCESC_ROOT_DIR}/include
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
)
|
||||
|
||||
# Find the library
|
||||
FIND_LIBRARY(XERCESC_LIBRARY
|
||||
NAMES xerces-c xerces-c_3
|
||||
PATHS
|
||||
${XERCESC_ROOT_DIR}/lib
|
||||
${XERCESC_ROOT_DIR}/lib/vc-9.0
|
||||
${XERCESC_ROOT_DIR}/lib64/vc-9.0
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
DOC "The name of the xerces-c library"
|
||||
)
|
||||
|
||||
IF (XERCESC_ROOT_DIR)
|
||||
IF (XERCESC_INCLUDE_DIR AND XERCESC_LIBRARY)
|
||||
SET (XERCESC_FOUND TRUE)
|
||||
SET (XERCESC_LIBRARIES "${XERCESC_LIBRARY}")
|
||||
# FIXME: There should be a better way of handling this?
|
||||
# FIXME: How can we test to see if the lib dir isn't
|
||||
# FIXME: one of the default dirs?
|
||||
LINK_DIRECTORIES(${XERCESC_ROOT_DIR}/lib)
|
||||
ENDIF (XERCESC_INCLUDE_DIR AND XERCESC_LIBRARY)
|
||||
ENDIF (XERCESC_ROOT_DIR)
|
||||
|
||||
IF (XERCESC_FOUND)
|
||||
IF (NOT XERCESC_FIND_QUIETLY)
|
||||
MESSAGE (STATUS " found xerces-c: ${XERCESC_LIBRARY}")
|
||||
ENDIF (NOT XERCESC_FIND_QUIETLY)
|
||||
ELSE (XERCESC_FOUND)
|
||||
IF (XERCESC_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find Xerces-C")
|
||||
ENDIF (XERCESC_FIND_REQUIRED)
|
||||
ENDIF (XERCESC_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
XERCESC_INCLUDE_DIR
|
||||
XERCESC_LIBRARY
|
||||
)
|
||||
@@ -1,5 +1,74 @@
|
||||
<h2>Version 2.2.0 / 2017-05-30</h2>
|
||||
|
||||
Major release! Please see <a href=http://www.open-tx.org/2017/05/30/opentx-2.2.0>this page</a> for details.
|
||||
|
||||
<h2>Version 2.1.9 / 2016-09-14</h2>
|
||||
|
||||
<ul>
|
||||
<li>SD sync fixes (<a href=https://github.com/opentx/opentx/issues/3351>#3351</a>)</li>
|
||||
<li>Fixed: Telemetry mode "FrSky D (cable)" choice was missing for Taranis (<a href=https://github.com/opentx/opentx/issues/3372>#3372</a>)</li>
|
||||
<li>Show persistent option only for calculated sensors (<a href=https://github.com/opentx/opentx/issues/3454>#3454</a>)</li>
|
||||
<li>Fixed Flight mode clear command (<a href=https://github.com/opentx/opentx/issues/3214>#3214</a>)</li>
|
||||
<li>Fixed a problem with Rotary encoders linked to flight mode (could freeze Companion) (<a href=https://github.com/opentx/opentx/issues/3459>#3459</a>, <a href=https://github.com/opentx/opentx/issues/3470>#3470</a>)</li>
|
||||
<li>Telemetry simulator improvements: added fuel quantity sensor, increased RPM range (<a href=https://github.com/opentx/opentx/issues/3505>#3505</a>, <a href=https://github.com/opentx/opentx/issues/3506>#3506</a>)</li>
|
||||
<li>Implemented minimal support for the DYI Multimodule (<a href=https://github.com/opentx/opentx/issues/3526>#3526</a>)</li>
|
||||
<li>Fixed: GVar combo-box not being refreshed when GV check-box (re-)selected (<a href=https://github.com/opentx/opentx/issues/3518>#3518</a>)</li>
|
||||
<li>Fixed: Heli inversion not correctly shown/saved from Companion on Radios without virtual inputs (<a href=https://github.com/opentx/opentx/issues/3510>#3510</a>)</li>
|
||||
<li>Implemented print functions for the Heli setup screen (<a href=https://github.com/opentx/opentx/issues/3554>#3554</a>)</li>
|
||||
<li>Fixed: Flight modes linked trims display value (<a href=https://github.com/opentx/opentx/issues/3547>#3547</a>, <a href=https://github.com/opentx/opentx/issues/3568>#3568</a>)</li>
|
||||
<li>Fixed: New model global variables and rotary encoders initialisation (<a href=https://github.com/opentx/opentx/issues/3473>#3473</a>)</li>
|
||||
<li>Fixed: Prevent circular linked global variables and rotary encoders (<a href=https://github.com/opentx/opentx/issues/3472>#3472</a>)</li>
|
||||
<li>Fixed wrong log replay speed issue in Telemetry simulator (<a href=https://github.com/opentx/opentx/issues/3708>#3708</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.8 / 2016-04-14</h2>
|
||||
|
||||
<ul>
|
||||
<li>Telemetry Simulator sensor instance number fixed (<a href=https://github.com/opentx/opentx/issues/3207>#3207</a>)</li>
|
||||
<li>Fixed: Throttle Source combo-box was populated multiple times (<a href=https://github.com/opentx/opentx/issues/3222>#3222</a>)</li>
|
||||
<li>RTC option tool-tip corrected (<a href=https://github.com/opentx/opentx/issues/3225>#3225</a>)</li>
|
||||
<li>Fixed: Companion was looking for custom scripts at the wrong place (<a href=https://github.com/opentx/opentx/issues/3237>#3237</a>)</li>
|
||||
<li>Offset displayed in inputs screen (<a href=https://github.com/opentx/opentx/issues/3248>#3248</a>)</li>
|
||||
<li>Import/export handling was broken for Average formula telemetry sensors (<a href=https://github.com/opentx/opentx/issues/3262>#3262</a>)</li>
|
||||
<li>Fixed: Hardware Setup control types and names were not stored in profile (<a href=https://github.com/opentx/opentx/issues/3260>#3260</a>)</li>
|
||||
<li>Fixed voice language list (<a href=https://github.com/opentx/opentx/issues/3338>#3338</a>)</li>
|
||||
<li>Fixed data overflow in Special Functions Override Channel (<a href=https://github.com/opentx/opentx/issues/3347>#3347</a>)</li>
|
||||
<li>Fixed: Sync dialog new line problem (only present for some UI languages) (<a href=https://github.com/opentx/opentx/issues/3350>#3350</a>)</li>
|
||||
<li>Removed a few legacy timer limitations, fix non-working limit (<a href=https://github.com/opentx/opentx/issues/3301>#3301</a>)</li>
|
||||
<li>Default AVR fuse settings changed to disable JTAG interface (<a href=https://github.com/opentx/opentx/issues/3379>#3379</a>)</li>
|
||||
<li>Channel range fix (Start, Channels) in Model Settings, Setup page, int/ext module settings</li>
|
||||
<li>Use friendly GVAR names in dialogs (if available) (<a href=https://github.com/opentx/opentx/issues/3353>#3353</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.7 / 2016-01-04</h2>
|
||||
|
||||
<ul>
|
||||
<li>Lua 'execute' failed in non-root directory (in Simulator) (<a href=https://github.com/opentx/opentx/issues/3024>#3024</a>)</li>
|
||||
<!-- this is disabled until the speed problem is fixed <li>Header line always visible in Outputs, Logical Switches and Special Functions (<a href=https://github.com/opentx/opentx/issues/2861>#2861</a>)</li> -->
|
||||
<li>LR12 changes: removed option for remote failsafe configuration, added in EU firmware variant</li>
|
||||
<li>Added Clear option to the flight mode context menu (right click on the Name label) (<a href=https://github.com/opentx/opentx/issues/3026>#3026</a>)</li>
|
||||
<li>New features for Telemetry Simulator: log replay, user friendly sensor values (<a href=https://github.com/opentx/opentx/issues/3124>#3124</a>)</li>
|
||||
<li>Added F7 key to reload LUA permanent scripts in radio simulator (<a href=https://github.com/opentx/opentx/issues/3141>#3141</a>)</li>
|
||||
<li>AR9X firmware flashing fall-back was wrong</li>
|
||||
<li>Command line options support added to standalone simulator (try "./simulator21 --help" on Linux and "simulator.exe /help" on Windows for usage) (<a href=https://github.com/opentx/opentx/issues/3160>#3160</a>)</li>
|
||||
<li>Various rounding problem fixed: Telemetry sensor Ratio parameter (<a href=https://github.com/opentx/opentx/issues/3117>#3117</a>),
|
||||
Outputs Sub-trim, Min and Max values (<a href=https://github.com/opentx/opentx/issues/3156>#3156</a>)</li>
|
||||
<li>Fixed: telemetry sensors Ratio and Offset value increment/decrement step (<a href=https://github.com/opentx/opentx/issues/3121>#3121</a>)</li>
|
||||
<li>Hardware/Calibration tab split int two tabs (<a href=https://github.com/opentx/opentx/issues/2974>#2974</a>)</li>
|
||||
<li>Fixed Fahrenheit temperature conversion error (if PREC was not 0) (<a href=https://github.com/opentx/opentx/issues/3146>#3146</a>)</li>
|
||||
<li>Application Setting 'Enable automatic backup before writing firmware' was not saved (<a href=https://github.com/opentx/opentx/issues/3040>#3040</a>)</li>
|
||||
<li>Fixed RPM package problem on Fedora (<a href=https://github.com/opentx/opentx/issues/3130>#3130</a>)</li>
|
||||
<li>Fixed conversion errors when loading 2.0.x EEPE (<a href=https://github.com/opentx/opentx/issues/3177>#3177</a>)</li>
|
||||
<li>Various texts and translations corrections</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Version 2.1.6 / 2015-11-11</h2>
|
||||
[Taranis]
|
||||
|
||||
<ul>
|
||||
<li>Telemetry custom screen changes didn't emit modified signal (<a href=https://github.com/opentx/opentx/issues/3029>#3029</a>)</li>
|
||||
<li>Hide D8/LR12 when eu firmware option is selected</li>
|
||||
|
||||
@@ -25,6 +25,7 @@ set(COMPANION_OSX_APP_BUNDLE_NAME "OpenTX Companion ${VERSION_MAJOR}.${VERSION_M
|
||||
# the binary (default homebrew path)
|
||||
set(DFU_UTIL_PATH "/usr/local/bin/dfu-util")
|
||||
set(AVRDUDE_PATH "/usr/local/bin/avrdude")
|
||||
set(AVRDUDE_CONF "/usr/local/etc/avrdude.conf")
|
||||
|
||||
option(ALLOW_NIGHTLY_BUILDS "Allow nightly builds download / update") # Disabled by default
|
||||
if(ALLOW_NIGHTLY_BUILDS)
|
||||
@@ -104,7 +105,6 @@ include_directories(
|
||||
${COMPANION_SRC_DIRECTORY}
|
||||
${COMPANION_SRC_DIRECTORY}/shared
|
||||
${SIMU_SRC_DIRECTORY}
|
||||
${COMPANION_SRC_DIRECTORY}/thirdparty/qxtcommandoptions
|
||||
${COMPANION_SRC_DIRECTORY}/thirdparty/qcustomplot
|
||||
${COMPANION_SRC_DIRECTORY}/thirdparty/miniz
|
||||
${COMPANION_SRC_DIRECTORY}/storage
|
||||
@@ -207,7 +207,6 @@ add_subdirectory(generaledit)
|
||||
add_subdirectory(simulation)
|
||||
add_subdirectory(storage)
|
||||
add_subdirectory(thirdparty/qcustomplot)
|
||||
add_subdirectory(thirdparty/qxtcommandoptions)
|
||||
|
||||
############# Companion ###############
|
||||
|
||||
@@ -220,7 +219,7 @@ set(companion_SRCS
|
||||
burnconfigdialog.cpp
|
||||
multimodelprinter.cpp
|
||||
comparedialog.cpp
|
||||
contributorsdialog.cpp
|
||||
creditsdialog.cpp
|
||||
releasenotesdialog.cpp
|
||||
releasenotesfirmwaredialog.cpp
|
||||
customizesplashdialog.cpp
|
||||
@@ -254,7 +253,7 @@ set(companion_MOC_HDRS
|
||||
printdialog.h
|
||||
fusesdialog.h
|
||||
logsdialog.h
|
||||
contributorsdialog.h
|
||||
creditsdialog.h
|
||||
releasenotesdialog.h
|
||||
releasenotesfirmwaredialog.h
|
||||
customizesplashdialog.h
|
||||
@@ -315,7 +314,7 @@ PrintTargetReport("${COMPANION_NAME}")
|
||||
set(simu_SRCS simulator.cpp )
|
||||
|
||||
add_executable(${SIMULATOR_NAME} MACOSX_BUNDLE ${WIN_EXECUTABLE_TYPE} ${simu_SRCS} ${icon_RC})
|
||||
target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation ${CPN_COMMON_LIB} storage qxtcommandoptions ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
|
||||
target_link_libraries(${SIMULATOR_NAME} PRIVATE simulation ${CPN_COMMON_LIB} storage ${PTHREAD_LIBRARY} ${SDL_LIBRARY} ${WIN_LINK_LIBRARIES})
|
||||
|
||||
############# Install ####################
|
||||
|
||||
@@ -352,6 +351,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
install(FILES images/linuxicons/512x512/companion.png DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/512x512/apps RENAME companion${C9X_NAME_SUFFIX}.png)
|
||||
install(FILES images/linuxicons/scalable/companion.svg DESTINATION ${INSTALL_TEMP_SHR_PFX}share/icons/hicolor/scalable/apps RENAME companion${C9X_NAME_SUFFIX}.svg)
|
||||
install(FILES ../targets/linux/45-companion-taranis.rules DESTINATION ${INSTALL_TEMP_LIB_PFX}lib/udev/rules.d RENAME 45-companion${C9X_NAME_SUFFIX}-taranis.rules)
|
||||
install(FILES ../targets/linux/45-usbasp.rules DESTINATION ${INSTALL_TEMP_LIB_PFX}lib/udev/rules.d RENAME 45-companion${C9X_NAME_SUFFIX}-usbasp.rules)
|
||||
# Linux specific code
|
||||
set(OperatingSystem "Linux")
|
||||
|
||||
@@ -525,8 +525,12 @@ IF(APPLE)
|
||||
# Copy dfu-util and avrdude, resolve symlink first
|
||||
get_filename_component(DFU_UTIL_ABSOLUTE_PATH ${DFU_UTIL_PATH} REALPATH)
|
||||
get_filename_component(AVRDUDE_ABSOLUTE_PATH ${AVRDUDE_PATH} REALPATH)
|
||||
get_filename_component(AVRDUDECONF_ABSOLUTE_PATH ${AVRDUDE_CONF} REALPATH)
|
||||
install(PROGRAMS ${DFU_UTIL_ABSOLUTE_PATH} ${AVRDUDE_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
|
||||
install(FILES ${AVRDUDECONF_ABSOLUTE_PATH} DESTINATION ${companion_res_dir} COMPONENT Runtime)
|
||||
|
||||
set(bundle_tools_path "\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/dfu-util;\${CMAKE_INSTALL_PREFIX}/${companion_res_dir}/avrdude")
|
||||
|
||||
|
||||
# Include depencies (adding frameworks, fixing the embbeded libraries)
|
||||
# I get write errors without setting BU_CHMOD_BUNDLE_ITEMS even though it is
|
||||
@@ -555,6 +559,7 @@ if(DPKG_PROGRAM)
|
||||
set(CPACK_DEBIAN_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
|
||||
set(CPACK_DEBIAN_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
|
||||
set(CPACK_DEBIAN_ARCHITECTURE $(CMAKE_SYSTEM_PROCESSOR))
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5multimedia5-plugins")
|
||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||
elseif(APPLE)
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "appdebugmessagehandler.h"
|
||||
|
||||
#include <QFileDevice>
|
||||
|
||||
AppDebugMessageHandler::AppDebugMessageHandler(QObject * parent) :
|
||||
QObject(parent),
|
||||
m_appDebugOutputLevel(APP_DBG_HANDLER_DEFAULT_LEVEL),
|
||||
@@ -55,6 +57,25 @@ void AppDebugMessageHandler::setShowFunctionDeclarations(bool showFunctionDeclar
|
||||
m_showFunctionDeclarations = showFunctionDeclarations;
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::addOutputDevice(QIODevice * device)
|
||||
{
|
||||
if (device && !m_outputDevices.contains(device))
|
||||
m_outputDevices.append(device);
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::removeOutputDevice(QIODevice * device)
|
||||
{
|
||||
if (device) {
|
||||
// no QVector::removeAll() in Qt < 5.4
|
||||
int i = 0;
|
||||
foreach (QIODevice * d, m_outputDevices) {
|
||||
if (d == device)
|
||||
m_outputDevices.remove(i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AppDebugMessageHandler::installAppMessageHandler()
|
||||
{
|
||||
m_defaultHandler = qInstallMessageHandler(g_appDebugMessageHandler);
|
||||
@@ -98,7 +119,7 @@ void AppDebugMessageHandler::messageHandler(QtMsgType type, const QMessageLogCon
|
||||
|
||||
qSetMessagePattern(msgPattern);
|
||||
|
||||
if (!m_defaultHandler || receivers(SIGNAL(messageOutput(quint8, const QString &)))) {
|
||||
if (!m_defaultHandler || m_outputDevices.size() || receivers(SIGNAL(messageOutput(quint8, const QString &)))) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0))
|
||||
msgPattern = qFormatLogMessage(type, context, msg);
|
||||
#else
|
||||
@@ -112,6 +133,14 @@ void AppDebugMessageHandler::messageHandler(QtMsgType type, const QMessageLogCon
|
||||
#endif
|
||||
|
||||
emit messageOutput(lvl, msgPattern);
|
||||
|
||||
foreach (QIODevice * d, m_outputDevices) {
|
||||
if (d && d->isWritable() && (!d->property("level").isValid() || d->property("level").toInt() <= lvl)) {
|
||||
d->write(qPrintable(msgPattern % "\n"));
|
||||
if (QFileDevice * fd = qobject_cast<QFileDevice *>(d))
|
||||
fd->flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (QThread::currentThread() == qApp->thread()) // gui thread
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QIODevice>
|
||||
#include <QMessageLogContext>
|
||||
#include <QObject>
|
||||
#include <QRegularExpression>
|
||||
@@ -94,7 +95,7 @@
|
||||
#else
|
||||
#define qInfo qDebug
|
||||
#endif
|
||||
#define QtInfoMsg 4
|
||||
#define QtInfoMsg QtMsgType(4)
|
||||
#endif
|
||||
|
||||
class AppDebugMessageHandler : public QObject
|
||||
@@ -110,6 +111,8 @@ class AppDebugMessageHandler : public QObject
|
||||
void setAppDebugOutputLevel(const quint8 & appDebugOutputLevel);
|
||||
void setShowSourcePath(bool showSourcePath);
|
||||
void setShowFunctionDeclarations(bool showFunctionDeclarations);
|
||||
void addOutputDevice(QIODevice * device);
|
||||
void removeOutputDevice(QIODevice * device);
|
||||
|
||||
void installAppMessageHandler();
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext & context, const QString & msg);
|
||||
@@ -123,6 +126,7 @@ class AppDebugMessageHandler : public QObject
|
||||
QRegularExpression m_srcPathFilter;
|
||||
QRegularExpression m_functionFilter;
|
||||
quint8 m_appDebugOutputLevel;
|
||||
QVector<QIODevice *> m_outputDevices;
|
||||
bool m_showSourcePath;
|
||||
bool m_showFunctionDeclarations;
|
||||
|
||||
|
||||
@@ -23,13 +23,10 @@
|
||||
#include "mainwindow.h"
|
||||
#include "appdata.h"
|
||||
#include "helpers.h"
|
||||
#include "firmwareinterface.h"
|
||||
#ifdef JOYSTICKS
|
||||
#if defined(JOYSTICKS)
|
||||
#include "joystick.h"
|
||||
#include "joystickdialog.h"
|
||||
#endif
|
||||
#include <QDesktopServices>
|
||||
#include <QtGui>
|
||||
|
||||
AppPreferencesDialog::AppPreferencesDialog(QWidget * parent) :
|
||||
QDialog(parent),
|
||||
@@ -41,6 +38,8 @@ AppPreferencesDialog::AppPreferencesDialog(QWidget * parent) :
|
||||
|
||||
initSettings();
|
||||
connect(ui->downloadVerCB, SIGNAL(currentIndexChanged(int)), this, SLOT(baseFirmwareChanged()));
|
||||
connect(ui->opt_appDebugLog, &QCheckBox::toggled, this, &AppPreferencesDialog::toggleAppLogSettings);
|
||||
connect(ui->opt_fwTraceLog, &QCheckBox::toggled, this, &AppPreferencesDialog::toggleAppLogSettings);
|
||||
connect(this, SIGNAL(accepted()), this, SLOT(writeValues()));
|
||||
|
||||
#if !defined(JOYSTICKS)
|
||||
@@ -61,9 +60,8 @@ AppPreferencesDialog::~AppPreferencesDialog()
|
||||
|
||||
void AppPreferencesDialog::writeValues()
|
||||
{
|
||||
g.useCompanionNightlyBuilds(ui->useCompanionNightlyBuilds->isChecked());
|
||||
g.autoCheckApp(ui->autoCheckCompanion->isChecked());
|
||||
g.useFirmwareNightlyBuilds(ui->useFirmwareNightlyBuilds->isChecked());
|
||||
g.OpenTxBranch(DownloadBranchType(ui->OpenTxBranch->currentIndex()));
|
||||
g.autoCheckFw(ui->autoCheckFirmware->isChecked());
|
||||
g.showSplash(ui->showSplash->isChecked());
|
||||
g.simuSW(ui->simuSW->isChecked());
|
||||
@@ -77,6 +75,10 @@ void AppPreferencesDialog::writeValues()
|
||||
g.embedSplashes(ui->splashincludeCB->currentIndex());
|
||||
g.enableBackup(ui->backupEnable->isChecked());
|
||||
|
||||
g.appDebugLog(ui->opt_appDebugLog->isChecked());
|
||||
g.fwTraceLog(ui->opt_fwTraceLog->isChecked());
|
||||
g.appLogsDir(ui->appLogsDir->text());
|
||||
|
||||
if (ui->joystickChkB ->isChecked() && ui->joystickCB->isEnabled()) {
|
||||
g.jsSupport(ui->joystickChkB ->isChecked());
|
||||
g.jsCtrl(ui->joystickCB ->currentIndex());
|
||||
@@ -131,13 +133,10 @@ void AppPreferencesDialog::initSettings()
|
||||
ui->snapshotPath->setDisabled(true);
|
||||
ui->snapshotPathButton->setDisabled(true);
|
||||
}
|
||||
#if defined(ALLOW_NIGHTLY_BUILDS)
|
||||
ui->useCompanionNightlyBuilds->setChecked(g.useCompanionNightlyBuilds());
|
||||
ui->useFirmwareNightlyBuilds->setChecked(g.useFirmwareNightlyBuilds());
|
||||
#else
|
||||
ui->useCompanionNightlyBuilds->hide();
|
||||
ui->useFirmwareNightlyBuilds->hide();
|
||||
#if !defined(ALLOW_NIGHTLY_BUILDS)
|
||||
// TODO should we gray out nightly builds here?
|
||||
#endif
|
||||
ui->OpenTxBranch->setCurrentIndex(g.OpenTxBranch());
|
||||
ui->autoCheckCompanion->setChecked(g.autoCheckApp());
|
||||
ui->autoCheckFirmware->setChecked(g.autoCheckFw());
|
||||
ui->showSplash->setChecked(g.showSplash());
|
||||
@@ -168,10 +167,15 @@ void AppPreferencesDialog::initSettings()
|
||||
}
|
||||
}
|
||||
else {
|
||||
ui->backupEnable->setDisabled(true);
|
||||
ui->backupEnable->setDisabled(true);
|
||||
}
|
||||
ui->splashincludeCB->setCurrentIndex(g.embedSplashes());
|
||||
|
||||
ui->opt_appDebugLog->setChecked(g.appDebugLog());
|
||||
ui->opt_fwTraceLog->setChecked(g.fwTraceLog());
|
||||
ui->appLogsDir->setText(g.appLogsDir());
|
||||
toggleAppLogSettings();
|
||||
|
||||
#if defined(JOYSTICKS)
|
||||
ui->joystickChkB->setChecked(g.jsSupport());
|
||||
if (ui->joystickChkB->isChecked()) {
|
||||
@@ -286,6 +290,15 @@ void AppPreferencesDialog::on_ProfilebackupPathButton_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AppPreferencesDialog::on_btn_appLogsDir_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getExistingDirectory(this, tr("Select a folder for application logs"), ui->appLogsDir->text());
|
||||
if (!fileName.isEmpty()) {
|
||||
ui->appLogsDir->setText(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::on_ge_pathButton_clicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Select Google Earth executable"),ui->ge_lineedit->text());
|
||||
@@ -458,6 +471,14 @@ void AppPreferencesDialog::firmwareOptionChanged(bool state)
|
||||
}
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::toggleAppLogSettings()
|
||||
{
|
||||
bool vis = (ui->opt_appDebugLog->isChecked() || ui->opt_fwTraceLog->isChecked());
|
||||
ui->appLogsDir->setVisible(vis);
|
||||
ui->lbl_appLogsDir->setVisible(vis);
|
||||
ui->btn_appLogsDir->setVisible(vis);
|
||||
}
|
||||
|
||||
void AppPreferencesDialog::populateFirmwareOptions(const Firmware * firmware)
|
||||
{
|
||||
const Firmware * parent = firmware->getFirmwareBase();
|
||||
@@ -539,4 +560,3 @@ void AppPreferencesDialog::shrink()
|
||||
{
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ class AppPreferencesDialog : public QDialog
|
||||
void shrink();
|
||||
void baseFirmwareChanged();
|
||||
void firmwareOptionChanged(bool state);
|
||||
void toggleAppLogSettings();
|
||||
|
||||
void writeValues();
|
||||
void on_libraryPathButton_clicked();
|
||||
@@ -74,6 +75,7 @@ class AppPreferencesDialog : public QDialog
|
||||
void on_sdPathButton_clicked();
|
||||
void on_SplashSelect_clicked();
|
||||
void on_clearImageButton_clicked();
|
||||
void on_btn_appLogsDir_clicked();
|
||||
|
||||
#if defined(JOYSTICKS)
|
||||
void on_joystickChkB_clicked();
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>623</width>
|
||||
<height>537</height>
|
||||
<width>863</width>
|
||||
<height>673</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -26,9 +26,6 @@
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
@@ -763,189 +760,459 @@ Mode 4:
|
||||
<attribute name="title">
|
||||
<string>Application Settings</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="14" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Automatic Backup Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="autoCheckCompanion">
|
||||
<property name="text">
|
||||
<string>Automatic check for Companion updates</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<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="2" column="1">
|
||||
<widget class="QSpinBox" name="historySize">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>40</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QCheckBox" name="useFirmwareNightlyBuilds">
|
||||
<property name="text">
|
||||
<string>Use OpenTX firmware nightly builds</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QLineEdit" name="backupPath">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>350</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="1">
|
||||
<widget class="QComboBox" name="splashincludeCB">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Only show user splash images</string>
|
||||
</property>
|
||||
<item row="7" column="1">
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="autoCheckFirmware">
|
||||
<property name="text">
|
||||
<string>Automatic check for OpenTX firmware updates</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="autoCheckCompanion">
|
||||
<property name="text">
|
||||
<string>Automatic check for Companion updates</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QComboBox" name="OpenTxBranch">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use releases (stable)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use releases and release candidates (testing)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use nightly builds (unstable)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Show user and companion splash images</string>
|
||||
</property>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10" stretch="0,1">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="historySize">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>40</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>most recently used files</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</widget>
|
||||
<item row="6" column="0" rowspan="2">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Startup Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="20" column="0">
|
||||
<widget class="QLabel" name="ge_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Google Earth Executable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Automatic Backup Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" rowspan="2" colspan="2">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remember</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<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="12" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="backupPath">
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="backupPathButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="17" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="libraryPath">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="libraryPathButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="23" column="0">
|
||||
<widget class="QLabel" name="lbl_appLogsDir">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Output Logs Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" rowspan="2" colspan="2">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QCheckBox" name="opt_removeBlankSlots">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>This option maintains the behaviour from older OpenTx versions where empty model slots are preserved when a model is deleted or moved. </p><p>When this option is de-selected, the other models may be re-arranged to fill the gap left by the removed model.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove empty model slots when deleting models (only applies for radios w/out categories)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="opt_newMdl_useWizard">
|
||||
<property name="text">
|
||||
<string>Use model wizard</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">btnGrp_newModelActions</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="opt_newMdl_useEditor">
|
||||
<property name="text">
|
||||
<string>Open model editor</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">btnGrp_newModelActions</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="opt_newMdl_useNone">
|
||||
<property name="text">
|
||||
<string>Just create the model</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">btnGrp_newModelActions</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QCheckBox" name="backupEnable">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable automatic backup before writing firmware</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="22" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Debug Output Logging</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0" rowspan="2" colspan="2">
|
||||
<widget class="Line" name="line_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" 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="14" column="0" rowspan="2" colspan="2">
|
||||
<widget class="Line" name="line_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="20" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="ge_lineedit">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ge_pathButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select Executable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="23" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="appLogsDir">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_appLogsDir">
|
||||
<property name="text">
|
||||
<string>Select Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="22" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="opt_appDebugLog">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Keep a log of all debugging messages generated by the desktop Companion/Simulator applications. An OpenTX developer may request this to help diagnose an issue.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Application (Companion/Simulator)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="opt_fwTraceLog">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Keep a log of all messages generated by the radio firmware when running in Simulator. This is the same information one would also see in the Simulator <span style=" font-style:italic;">Debug Output</span> window.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Radio Firmware (in Simulator)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="16" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Splash Screen Library</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="21" column="0" colspan="2">
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>User Splash Screens</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Action on New Model</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<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="2" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Files to keep</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="3">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1" colspan="3">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="autoCheckFirmware">
|
||||
<property name="text">
|
||||
<string>Automatic check for OpenTX firmware updates</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="backupPathButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Splash Screen Library</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="ge_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Google Earth Executable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="20" column="1">
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -958,155 +1225,6 @@ Mode 4:
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="15" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="backupEnable">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable automatic backup before writing firmware</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="1">
|
||||
<widget class="QLineEdit" name="libraryPath">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="1" colspan="3">
|
||||
<widget class="Line" name="line_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>User Splash Screens</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QCheckBox" name="useCompanionNightlyBuilds">
|
||||
<property name="text">
|
||||
<string>Use Companion nightly builds</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="ge_lineedit">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>350</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="ge_pathButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select Executable</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="18" column="2" colspan="2">
|
||||
<widget class="QPushButton" name="libraryPathButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select Folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Action on New Model</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1" colspan="3">
|
||||
<widget class="QCheckBox" name="opt_removeBlankSlots">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>This option maintains the behaviour from older OpenTx versions where empty model slots are preserved when a model is deleted or moved. </p><p>When this option is de-selected, the other models may be re-arranged to fill the gap left by the removed model.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove empty model slots when deleting models (only applies for radios w/out categories)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="opt_newMdl_useWizard">
|
||||
<property name="text">
|
||||
<string>Use model wizard</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">btnGrp_newModelActions</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="opt_newMdl_useEditor">
|
||||
<property name="text">
|
||||
<string>Open model editor</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">btnGrp_newModelActions</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="opt_newMdl_useNone">
|
||||
<property name="text">
|
||||
<string>Just create the model</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">btnGrp_newModelActions</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="simulatorTab">
|
||||
@@ -1181,7 +1299,7 @@ Mode 4:
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Simulator capture folder</string>
|
||||
<string>Screenshot capture folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -1363,18 +1481,7 @@ Mode 4:
|
||||
<tabstop>channelorderCB</tabstop>
|
||||
<tabstop>renameFirmware</tabstop>
|
||||
<tabstop>burnFirmware</tabstop>
|
||||
<tabstop>ge_lineedit</tabstop>
|
||||
<tabstop>ge_pathButton</tabstop>
|
||||
<tabstop>historySize</tabstop>
|
||||
<tabstop>showSplash</tabstop>
|
||||
<tabstop>autoCheckFirmware</tabstop>
|
||||
<tabstop>autoCheckCompanion</tabstop>
|
||||
<tabstop>backupPath</tabstop>
|
||||
<tabstop>backupPathButton</tabstop>
|
||||
<tabstop>backupEnable</tabstop>
|
||||
<tabstop>splashincludeCB</tabstop>
|
||||
<tabstop>libraryPath</tabstop>
|
||||
<tabstop>libraryPathButton</tabstop>
|
||||
<tabstop>snapshotPath</tabstop>
|
||||
<tabstop>snapshotPathButton</tabstop>
|
||||
<tabstop>snapshotClipboardCKB</tabstop>
|
||||
|
||||
@@ -99,6 +99,7 @@ const int Boards::getFlashSize(Type board)
|
||||
case BOARD_TARANIS_X9D:
|
||||
case BOARD_TARANIS_X9DP:
|
||||
case BOARD_TARANIS_X9E:
|
||||
case BOARD_TARANIS_X7:
|
||||
case BOARD_FLAMENCO:
|
||||
return FSIZE_TARANIS;
|
||||
case BOARD_X12S:
|
||||
@@ -151,10 +152,10 @@ const SwitchInfo Boards::getSwitchInfo(Board::Type board, unsigned index)
|
||||
}
|
||||
else {
|
||||
const Board::SwitchInfo switches[] = {
|
||||
{SWITCH_3POS, "3POS"},
|
||||
{SWITCH_2POS, "THR"},
|
||||
{SWITCH_2POS, "RUD"},
|
||||
{SWITCH_2POS, "ELE"},
|
||||
{SWITCH_3POS, "3POS"},
|
||||
{SWITCH_2POS, "AIL"},
|
||||
{SWITCH_2POS, "GEA"},
|
||||
{SWITCH_TOGGLE, "TRN"}
|
||||
@@ -171,37 +172,29 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
switch (capability) {
|
||||
case Sticks:
|
||||
return 4;
|
||||
|
||||
case Pots:
|
||||
if (IS_HORUS(board))
|
||||
return 3;
|
||||
else if (IS_TARANIS_X7(board))
|
||||
if (IS_TARANIS_X7(board))
|
||||
return 2;
|
||||
else if (IS_TARANIS_X9E(board))
|
||||
return 4;
|
||||
else if (IS_TARANIS(board))
|
||||
return 3;
|
||||
else
|
||||
return 3;
|
||||
|
||||
case Sliders:
|
||||
if (IS_HORUS(board))
|
||||
if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board))
|
||||
return 4;
|
||||
else if (IS_TARANIS_X7(board))
|
||||
return 0;
|
||||
else if (IS_TARANIS_X9E(board))
|
||||
return 4;
|
||||
else if (IS_TARANIS(board))
|
||||
else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
|
||||
case MouseAnalogs:
|
||||
if (IS_HORUS(board))
|
||||
if (IS_HORUS_X12S(board))
|
||||
return 2;
|
||||
else
|
||||
return 0;
|
||||
case FactoryInstalledSwitches:
|
||||
if (IS_TARANIS_X9E(board))
|
||||
return 8;
|
||||
// no break
|
||||
|
||||
case Switches:
|
||||
if (IS_TARANIS_X9E(board))
|
||||
return 18;
|
||||
@@ -211,11 +204,25 @@ const int Boards::getCapability(Board::Type board, Board::Capability capability)
|
||||
return 8;
|
||||
else
|
||||
return 7;
|
||||
|
||||
case FactoryInstalledSwitches:
|
||||
if (IS_TARANIS_X9E(board))
|
||||
return 8;
|
||||
else
|
||||
return getCapability(board, Switches);
|
||||
|
||||
case SwitchPositions:
|
||||
if (IS_HORUS_OR_TARANIS(board))
|
||||
return getCapability(board, Switches) * 3;
|
||||
else
|
||||
return 9;
|
||||
|
||||
case NumTrims:
|
||||
if (IS_HORUS(board))
|
||||
return 6;
|
||||
else
|
||||
return 4;
|
||||
|
||||
case NumTrimSwitches:
|
||||
return getCapability(board, NumTrims) * 2;
|
||||
}
|
||||
|
||||
@@ -111,6 +111,7 @@ namespace Board {
|
||||
Sliders,
|
||||
MouseAnalogs,
|
||||
Switches,
|
||||
SwitchPositions,
|
||||
FactoryInstalledSwitches,
|
||||
NumTrims,
|
||||
NumTrimSwitches
|
||||
|
||||
@@ -105,6 +105,18 @@ burnConfigDialog::~burnConfigDialog()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QStringList burnConfigDialog::getAvrdudeArgs()
|
||||
{
|
||||
QStringList args = avrArgs;
|
||||
if (!avrPort.isEmpty())
|
||||
args << "-P" << avrPort;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
args << "-C" << QFileInfo(QApplication::applicationDirPath() + "/../Resources/avrdude.conf").absoluteFilePath();
|
||||
#endif
|
||||
return args;
|
||||
}
|
||||
|
||||
void burnConfigDialog::getSettings()
|
||||
{
|
||||
avrLoc = g.avrdudeLocation();
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
QString getAVRDUDE() {return avrLoc;}
|
||||
QString getSAMBA() {return sambaLoc;}
|
||||
QString getDFU() {return dfuLoc;}
|
||||
QStringList getAvrdudeArgs() { QStringList args = avrArgs; if (!avrPort.isEmpty()) args << "-P" << avrPort; return args; }
|
||||
QStringList getAvrdudeArgs();
|
||||
QStringList getDFUArgs() {return dfuArgs;}
|
||||
QString getProgrammer() {return avrProgrammer;}
|
||||
QString getMCU() {return avrMCU;}
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QSplashScreen>
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
#include <SDL.h>
|
||||
@@ -68,6 +71,20 @@ int main(int argc, char *argv[])
|
||||
|
||||
CustomDebug::setFilterRules();
|
||||
|
||||
if (!g.hasCurrentSettings()) {
|
||||
QString previousVersion;
|
||||
if (g.findPreviousVersionSettings(&previousVersion)) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(QObject::tr("We have found existing settings for Companion version: %1.\nDo you want to import them?").arg(previousVersion));
|
||||
msgBox.setIcon(QMessageBox::Information);
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::Yes);
|
||||
int ret = msgBox.exec();
|
||||
|
||||
if (ret == QMessageBox::Yes)
|
||||
g.importSettings(previousVersion);
|
||||
}
|
||||
}
|
||||
g.init();
|
||||
|
||||
QStringList strl = QApplication::arguments();
|
||||
@@ -77,14 +94,21 @@ int main(int argc, char *argv[])
|
||||
exit(0);
|
||||
}
|
||||
|
||||
QFile dbgLog;
|
||||
if (AppDebugMessageHandler::instance() && g.appDebugLog() && !g.appLogsDir().isEmpty() && QDir().mkpath(g.appLogsDir())) {
|
||||
QString fn = g.appLogsDir() % "/CompanionDebug_" % QDateTime::currentDateTime().toString("yy-MM-dd_HH-mm-ss") % ".log";
|
||||
dbgLog.setFileName(fn);
|
||||
if (dbgLog.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
AppDebugMessageHandler::instance()->addOutputDevice(&dbgLog);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
app.setStyle(new MyProxyStyle);
|
||||
#endif
|
||||
|
||||
Translations::installTranslators();
|
||||
|
||||
// QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||
|
||||
#if defined(JOYSTICKS) || defined(SIMU_AUDIO)
|
||||
uint32_t sdlFlags = 0;
|
||||
#ifdef JOYSTICKS
|
||||
@@ -139,5 +163,11 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
qDebug() << "COMPANION EXIT" << result;
|
||||
|
||||
if (dbgLog.isOpen()) {
|
||||
AppDebugMessageHandler::instance()->removeOutputDevice(&dbgLog);
|
||||
dbgLog.close();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
<file>images/customize.png</file>
|
||||
<file>icon.png</file>
|
||||
<file>../../CREDITS.txt</file>
|
||||
<file>../../DONATIONS.txt</file>
|
||||
<file>../releasenotes.txt</file>
|
||||
<file>images/screenshot.png</file>
|
||||
<file>images/splash.png</file>
|
||||
@@ -48,21 +47,32 @@
|
||||
<file>images/simulator/icons/svg/trainer-active.svg</file>
|
||||
<file>images/simulator/icons/svg/word_wrap.svg</file>
|
||||
<file>images/simulator/icons/svg/word_wrap-on.svg</file>
|
||||
<file>images/simulator/Horus/middle.png</file>
|
||||
<file>images/simulator/Horus/left.png</file>
|
||||
<file>images/simulator/Horus/right.png</file>
|
||||
<file>images/simulator/Horus/top.png</file>
|
||||
<file>images/simulator/Horus/bottom.png</file>
|
||||
<file>images/simulator/Horus/led.png</file>
|
||||
<file>images/simulator/Horus/border-right.png</file>
|
||||
<file>images/simulator/Horus/left_btn1.png</file>
|
||||
<file>images/simulator/Horus/left_btn2.png</file>
|
||||
<file>images/simulator/Horus/left_scrnsht.png</file>
|
||||
<file>images/simulator/Horus/right_btnU.png</file>
|
||||
<file>images/simulator/Horus/right_btnL.png</file>
|
||||
<file>images/simulator/Horus/right_btnD.png</file>
|
||||
<file>images/simulator/Horus/right_btnR.png</file>
|
||||
<file>images/simulator/Horus/right_ent.png</file>
|
||||
<file>images/simulator/X12/middle.png</file>
|
||||
<file>images/simulator/X12/left.png</file>
|
||||
<file>images/simulator/X12/right.png</file>
|
||||
<file>images/simulator/X12/top.png</file>
|
||||
<file>images/simulator/X12/bottom.png</file>
|
||||
<file>images/simulator/X12/led.png</file>
|
||||
<file>images/simulator/X12/border-right.png</file>
|
||||
<file>images/simulator/X12/left_btn1.png</file>
|
||||
<file>images/simulator/X12/left_btn2.png</file>
|
||||
<file>images/simulator/X12/left_scrnsht.png</file>
|
||||
<file>images/simulator/X12/right_btnU.png</file>
|
||||
<file>images/simulator/X12/right_btnL.png</file>
|
||||
<file>images/simulator/X12/right_btnD.png</file>
|
||||
<file>images/simulator/X12/right_btnR.png</file>
|
||||
<file>images/simulator/X12/right_ent.png</file>
|
||||
<file>images/simulator/X10/left.png</file>
|
||||
<file>images/simulator/X10/right.png</file>
|
||||
<file>images/simulator/X10/top.png</file>
|
||||
<file>images/simulator/X10/bottom.png</file>
|
||||
<file>images/simulator/X10/left_mdl.png</file>
|
||||
<file>images/simulator/X10/left_page.png</file>
|
||||
<file>images/simulator/X10/left_scrnsht.png</file>
|
||||
<file>images/simulator/X10/left_rtn.png</file>
|
||||
<file>images/simulator/X10/left_sys.png</file>
|
||||
<file>images/simulator/X10/left_tele.png</file>
|
||||
<file>images/simulator/X10/right_ent.png</file>
|
||||
<file>images/simulator/9X/9xdb.png</file>
|
||||
<file>images/simulator/9X/9xdl.png</file>
|
||||
<file>images/simulator/9X/9xdr.png</file>
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#ifndef _CONSTANTS_H_
|
||||
#define _CONSTANTS_H_
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
#define CPN_MAX_MODELS 60
|
||||
#define CPN_MAX_TIMERS 3
|
||||
#define CPN_MAX_FLIGHT_MODES 9
|
||||
@@ -47,23 +49,31 @@
|
||||
#define CPN_MAX_MOUSE_ANALOGS 2
|
||||
#define CPN_MAX_ANALOGS (CPN_MAX_STICKS + CPN_MAX_POTS + CPN_MAX_MOUSE_ANALOGS)
|
||||
|
||||
#define CPN_STR_FILES QT_TRANSLATE_NOOP("CompanionMacros", "files")
|
||||
#define CPN_STR_RAD_MOD_SETTINGS QT_TRANSLATE_NOOP("CompanionMacros", "Radio and Models settings")
|
||||
#define HEX_FILES_FILTER "HEX " CPN_STR_FILES " (*.hex);;"
|
||||
#define BIN_FILES_FILTER "BIN " CPN_STR_FILES " (*.bin);;"
|
||||
#define DFU_FILES_FILTER "DFU " CPN_STR_FILES " (*.dfu);;"
|
||||
#define EEPE_FILES_FILTER "EEPE " CPN_STR_FILES " (*.eepe);;"
|
||||
#define OTX_FILES_FILTER "OpenTX " CPN_STR_FILES " (*.otx);;"
|
||||
#define EEPROM_FILES_FILTER CPN_STR_RAD_MOD_SETTINGS " " CPN_STR_FILES " (*.otx *.eepe *.bin *.hex);;" OTX_FILES_FILTER EEPE_FILES_FILTER BIN_FILES_FILTER HEX_FILES_FILTER
|
||||
#define FLASH_FILES_FILTER "FLASH " CPN_STR_FILES " (*.bin *.hex *.dfu);;" BIN_FILES_FILTER HEX_FILES_FILTER DFU_FILES_FILTER
|
||||
#define EXTERNAL_EEPROM_FILES_FILTER "EEPROM " CPN_STR_FILES " (*.bin *.hex);;" BIN_FILES_FILTER HEX_FILES_FILTER
|
||||
#define CPN_STR_FILES QCoreApplication::translate("Companion", "files")
|
||||
#define CPN_STR_RAD_MOD_SETTINGS QCoreApplication::translate("Companion", "Radio and Models settings")
|
||||
#define HEX_FILES_FILTER "HEX " % CPN_STR_FILES % " (*.hex);;"
|
||||
#define BIN_FILES_FILTER "BIN " % CPN_STR_FILES % " (*.bin);;"
|
||||
#define DFU_FILES_FILTER "DFU " % CPN_STR_FILES % " (*.dfu);;"
|
||||
#define EEPE_FILES_FILTER "EEPE " % CPN_STR_FILES % " (*.eepe);;"
|
||||
#define OTX_FILES_FILTER "OpenTX " % CPN_STR_FILES % " (*.otx);;"
|
||||
#define EEPROM_FILES_FILTER CPN_STR_RAD_MOD_SETTINGS % " " % CPN_STR_FILES % " (*.otx *.eepe *.bin *.hex);;" % OTX_FILES_FILTER % EEPE_FILES_FILTER % BIN_FILES_FILTER % HEX_FILES_FILTER
|
||||
#define FLASH_FILES_FILTER "FLASH " % CPN_STR_FILES % " (*.bin *.hex *.dfu);;" % BIN_FILES_FILTER % HEX_FILES_FILTER % DFU_FILES_FILTER
|
||||
#define EXTERNAL_EEPROM_FILES_FILTER "EEPROM " % CPN_STR_FILES % " (*.bin *.hex);;" % BIN_FILES_FILTER % HEX_FILES_FILTER
|
||||
#define ER9X_EEPROM_FILE_TYPE "ER9X_EEPROM_FILE"
|
||||
#define EEPE_EEPROM_FILE_HEADER "EEPE EEPROM FILE"
|
||||
#define EEPE_MODEL_FILE_HEADER "EEPE MODEL FILE"
|
||||
|
||||
#define CPN_STR_SW_INDICATOR_UP QT_TRANSLATE_NOOP("RawSwitch", "\xE2\x86\x91") // Switch up position indicator: Up arrow, or similar.
|
||||
#define CPN_STR_SW_INDICATOR_DN QT_TRANSLATE_NOOP("RawSwitch", "\xE2\x86\x93") // Switch down position indicator: Down arrow, or similar.
|
||||
#define CPN_STR_SW_INDICATOR_NEUT QT_TRANSLATE_NOOP("RawSwitch", "-") // Switch neutral (middle) position indicator.
|
||||
#define CPN_STR_SW_INDICATOR_REV QT_TRANSLATE_NOOP("RawSwitch", "!") // Switch reversed logic (NOT) indicator.
|
||||
#define CPN_STR_SW_INDICATOR_UP QCoreApplication::translate("RawSwitch", "\xE2\x86\x91") // Switch up position indicator: Up arrow, or similar.
|
||||
#define CPN_STR_SW_INDICATOR_DN QCoreApplication::translate("RawSwitch", "\xE2\x86\x93") // Switch down position indicator: Down arrow, or similar.
|
||||
#define CPN_STR_SW_INDICATOR_NEUT QCoreApplication::translate("RawSwitch", "-") // Switch neutral (middle) position indicator.
|
||||
#define CPN_STR_SW_INDICATOR_REV QCoreApplication::translate("RawSwitch", "!") // Switch reversed logic (NOT) indicator.
|
||||
|
||||
enum DownloadBranchType {
|
||||
BRANCH_RELEASE_STABLE,
|
||||
BRANCH_RC_TESTING,
|
||||
BRANCH_NIGHTLY_UNSTABLE
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(DownloadBranchType)
|
||||
|
||||
#endif // _CONSTANTS_H_
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "contributorsdialog.h"
|
||||
#include "creditsdialog.h"
|
||||
#include "ui_htmldialog.h"
|
||||
#include "helpers.h"
|
||||
#include <QFile>
|
||||
|
||||
ContributorsDialog::ContributorsDialog(QWidget * parent):
|
||||
CreditsDialog::CreditsDialog(QWidget * parent):
|
||||
QDialog(parent),
|
||||
ui(new Ui::HtmlDialog)
|
||||
{
|
||||
@@ -42,42 +42,8 @@ ContributorsDialog::ContributorsDialog(QWidget * parent):
|
||||
"</head>"
|
||||
"<body class=\"normal\">";
|
||||
|
||||
QFile credits(":/CREDITS.txt");
|
||||
if (credits.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QStringList names;
|
||||
while (!credits.atEnd()) {
|
||||
QByteArray line = credits.readLine();
|
||||
if (line.trimmed() == "")
|
||||
break;
|
||||
names.append(line.trimmed());
|
||||
}
|
||||
str.append(formatTable(tr("Main Developers"), names, 3));
|
||||
|
||||
names.clear();
|
||||
while (!credits.atEnd()) {
|
||||
QByteArray line = credits.readLine();
|
||||
names.append(line.trimmed());
|
||||
}
|
||||
str.append(formatTable(tr("Other contributors"), names, 3));
|
||||
}
|
||||
|
||||
QFile donations(":/DONATIONS.txt");
|
||||
if (donations.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QStringList names;
|
||||
while (!donations.atEnd()) {
|
||||
QByteArray line = donations.readLine();
|
||||
if (line.trimmed() == "")
|
||||
break;
|
||||
names.append(line.trimmed());
|
||||
}
|
||||
str.append(formatTable(tr("Companies and projects who have donated to OpenTX"), names, 3));
|
||||
|
||||
names.clear();
|
||||
while (!donations.atEnd()) {
|
||||
QByteArray line = donations.readLine();
|
||||
names.append(line);
|
||||
}
|
||||
str.append(formatTable(tr("People who have donated to OpenTX"), names, 6));
|
||||
foreach(CreditsSection section, readCredits()) {
|
||||
str.append(formatTable(sectionTitle(section.title), section.names, 3));
|
||||
}
|
||||
|
||||
str.append("<table><tr><td class=\"normal\"> </td></tr>" \
|
||||
@@ -87,9 +53,9 @@ ContributorsDialog::ContributorsDialog(QWidget * parent):
|
||||
#if 0
|
||||
QFile blacklist(":/BLACKLIST.txt");
|
||||
if (blacklist.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QStringList names;
|
||||
names << blacklist.readAll();
|
||||
str.append(formatTable(tr("OpenTX Blacklist"), names, 1));
|
||||
QStringList names;
|
||||
names << blacklist.readAll();
|
||||
str.append(formatTable(tr("OpenTX Blacklist"), names, 1));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -99,12 +65,45 @@ ContributorsDialog::ContributorsDialog(QWidget * parent):
|
||||
ui->textEditor->setOpenExternalLinks(true);
|
||||
}
|
||||
|
||||
ContributorsDialog::~ContributorsDialog()
|
||||
CreditsDialog::~CreditsDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QString ContributorsDialog::formatTable(const QString & title, const QStringList & names, int columns)
|
||||
QList<CreditsDialog::CreditsSection> CreditsDialog::readCredits()
|
||||
{
|
||||
QFile credits(":/CREDITS.txt");
|
||||
QList<CreditsSection> result;
|
||||
if (credits.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
while (!credits.atEnd()) {
|
||||
QByteArray line = credits.readLine().trimmed();
|
||||
if (line.size() >= 2) {
|
||||
if (line.startsWith("[") && line.endsWith("]")) {
|
||||
result.push_back(CreditsSection(line.mid(1, line.size() - 2)));
|
||||
} else {
|
||||
result.back().addName(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString CreditsDialog::sectionTitle(const QString & title)
|
||||
{
|
||||
if (title == "Main developers")
|
||||
return tr("Main developers");
|
||||
else if (title == "Translators")
|
||||
return tr("Translators");
|
||||
else if (title == "Companies and projects who have donated to OpenTX")
|
||||
return tr("Companies and projects who have donated to OpenTX");
|
||||
else if (title == "People who have donated to OpenTX")
|
||||
return tr("People who have donated to OpenTX");
|
||||
else
|
||||
return tr("Other contributors");
|
||||
}
|
||||
|
||||
QString CreditsDialog::formatTable(const QString & title, const QStringList & names, int columns)
|
||||
{
|
||||
const float cwidth = 100.0 / columns;
|
||||
QString str = "<table width=\"100%\" border=0 cellspacing=0 cellpadding=2>" \
|
||||
@@ -18,8 +18,8 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CONTRIBUTORSDIALOG_H_
|
||||
#define _CONTRIBUTORSDIALOG_H_
|
||||
#ifndef _CREDITSDIALOG_H_
|
||||
#define _CREDITSDIALOG_H_
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -27,17 +27,36 @@ namespace Ui {
|
||||
class HtmlDialog;
|
||||
}
|
||||
|
||||
class ContributorsDialog : public QDialog
|
||||
class CreditsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class CreditsSection
|
||||
{
|
||||
public:
|
||||
CreditsSection(const QString & title):
|
||||
title(title)
|
||||
{
|
||||
}
|
||||
|
||||
void addName(const QString & name)
|
||||
{
|
||||
names.push_back(name);
|
||||
}
|
||||
|
||||
QString title;
|
||||
QStringList names;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit ContributorsDialog(QWidget * parent = 0);
|
||||
~ContributorsDialog();
|
||||
explicit CreditsDialog(QWidget * parent = 0);
|
||||
~CreditsDialog();
|
||||
|
||||
private:
|
||||
Ui::HtmlDialog * ui;
|
||||
QList<CreditsSection> readCredits();
|
||||
QString sectionTitle(const QString & title);
|
||||
QString formatTable(const QString & title, const QStringList & names, int colums);
|
||||
};
|
||||
|
||||
#endif // _CONTRIBUTORSDIALOG_H_
|
||||
#endif // _CREDITSDIALOG_H_
|
||||
@@ -150,11 +150,9 @@ bool Side::saveImage()
|
||||
return true;
|
||||
}
|
||||
|
||||
//*** customizeSplashDialog Class ***
|
||||
|
||||
customizeSplashDialog::customizeSplashDialog(QWidget *parent) :
|
||||
CustomizeSplashDialog::CustomizeSplashDialog(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::customizeSplashDialog)
|
||||
ui(new Ui::CustomizeSplashDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("paintbrush.png"));
|
||||
@@ -185,22 +183,22 @@ customizeSplashDialog::customizeSplashDialog(QWidget *parent) :
|
||||
resize(0,0);
|
||||
}
|
||||
|
||||
customizeSplashDialog::~customizeSplashDialog()
|
||||
CustomizeSplashDialog::~CustomizeSplashDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_copyRightToLeftButton_clicked() {
|
||||
void CustomizeSplashDialog::on_copyRightToLeftButton_clicked() {
|
||||
left.copyImage(right);
|
||||
}
|
||||
void customizeSplashDialog::on_copyLeftToRightButton_clicked() {
|
||||
void CustomizeSplashDialog::on_copyLeftToRightButton_clicked() {
|
||||
right.copyImage(left);
|
||||
}
|
||||
|
||||
|
||||
void customizeSplashDialog::on_leftLoadFwButton_clicked() {loadFirmware(left);}
|
||||
void customizeSplashDialog::on_rightLoadFwButton_clicked() {loadFirmware(right);}
|
||||
void customizeSplashDialog::loadFirmware(Side side)
|
||||
void CustomizeSplashDialog::on_leftLoadFwButton_clicked() {loadFirmware(left);}
|
||||
void CustomizeSplashDialog::on_rightLoadFwButton_clicked() {loadFirmware(right);}
|
||||
void CustomizeSplashDialog::loadFirmware(Side side)
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Firmware File"), g.flashDir(), FLASH_FILES_FILTER);
|
||||
if (!fileName.isEmpty()) {
|
||||
@@ -212,9 +210,9 @@ void customizeSplashDialog::loadFirmware(Side side)
|
||||
side.markSourceButton();
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_leftLoadPictButton_clicked() {loadPicture(left);}
|
||||
void customizeSplashDialog::on_rightLoadPictButton_clicked() {loadPicture(right);}
|
||||
void customizeSplashDialog::loadPicture(Side side)
|
||||
void CustomizeSplashDialog::on_leftLoadPictButton_clicked() {loadPicture(left);}
|
||||
void CustomizeSplashDialog::on_rightLoadPictButton_clicked() {loadPicture(right);}
|
||||
void CustomizeSplashDialog::loadPicture(Side side)
|
||||
{
|
||||
QString supportedImageFormats;
|
||||
for (int formatIndex = 0; formatIndex < QImageReader::supportedImageFormats().count(); formatIndex++) {
|
||||
@@ -232,9 +230,9 @@ void customizeSplashDialog::loadPicture(Side side)
|
||||
side.markSourceButton();
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_leftLoadProfileButton_clicked() {loadProfile(left);}
|
||||
void customizeSplashDialog::on_rightLoadProfileButton_clicked() {loadProfile(right);}
|
||||
void customizeSplashDialog::loadProfile(Side side)
|
||||
void CustomizeSplashDialog::on_leftLoadProfileButton_clicked() {loadProfile(left);}
|
||||
void CustomizeSplashDialog::on_rightLoadProfileButton_clicked() {loadProfile(right);}
|
||||
void CustomizeSplashDialog::loadProfile(Side side)
|
||||
{
|
||||
QString fileName=g.profile[g.id()].splashFile();
|
||||
|
||||
@@ -245,9 +243,9 @@ void customizeSplashDialog::loadProfile(Side side)
|
||||
side.markSourceButton();
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_leftLibraryButton_clicked(){libraryButton_clicked(left);}
|
||||
void customizeSplashDialog::on_rightLibraryButton_clicked(){libraryButton_clicked(right);}
|
||||
void customizeSplashDialog::libraryButton_clicked( Side side )
|
||||
void CustomizeSplashDialog::on_leftLibraryButton_clicked(){libraryButton_clicked(left);}
|
||||
void CustomizeSplashDialog::on_rightLibraryButton_clicked(){libraryButton_clicked(right);}
|
||||
void CustomizeSplashDialog::libraryButton_clicked( Side side )
|
||||
{
|
||||
QString fileName;
|
||||
SplashLibraryDialog *ld = new SplashLibraryDialog(this,&fileName);
|
||||
@@ -258,9 +256,9 @@ void customizeSplashDialog::libraryButton_clicked( Side side )
|
||||
}
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_leftSaveButton_clicked(){saveButton_clicked(left);}
|
||||
void customizeSplashDialog::on_rightSaveButton_clicked(){saveButton_clicked(right);}
|
||||
void customizeSplashDialog::saveButton_clicked( Side side )
|
||||
void CustomizeSplashDialog::on_leftSaveButton_clicked(){saveButton_clicked(left);}
|
||||
void CustomizeSplashDialog::on_rightSaveButton_clicked(){saveButton_clicked(right);}
|
||||
void CustomizeSplashDialog::saveButton_clicked( Side side )
|
||||
{
|
||||
if (side.saveImage()){
|
||||
QMessageBox::information(this, tr("File Saved"), tr("The image was saved to the file %1").arg(*side.saveToFileName));
|
||||
@@ -272,9 +270,9 @@ void customizeSplashDialog::saveButton_clicked( Side side )
|
||||
QMessageBox::critical(this, tr("File Save Error"), tr("Failed to write image to %1").arg(*side.saveToFileName));
|
||||
}
|
||||
|
||||
void customizeSplashDialog::on_leftInvertButton_clicked(){invertButton_clicked(left);}
|
||||
void customizeSplashDialog::on_rightInvertButton_clicked(){invertButton_clicked(right);}
|
||||
void customizeSplashDialog::invertButton_clicked(Side side)
|
||||
void CustomizeSplashDialog::on_leftInvertButton_clicked(){invertButton_clicked(left);}
|
||||
void CustomizeSplashDialog::on_rightInvertButton_clicked(){invertButton_clicked(right);}
|
||||
void CustomizeSplashDialog::invertButton_clicked(Side side)
|
||||
{
|
||||
QImage image = side.imageLabel->pixmap()->toImage();
|
||||
image.invertPixels();
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class customizeSplashDialog;
|
||||
class CustomizeSplashDialog;
|
||||
}
|
||||
|
||||
const int WIDTH_TARANIS = 212;
|
||||
@@ -63,15 +63,15 @@ private:
|
||||
LCDFormat *format;
|
||||
};
|
||||
|
||||
class customizeSplashDialog : public QDialog
|
||||
class CustomizeSplashDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
Side left;
|
||||
Side right;
|
||||
|
||||
public:
|
||||
explicit customizeSplashDialog(QWidget *parent = 0);
|
||||
~customizeSplashDialog();
|
||||
explicit CustomizeSplashDialog(QWidget *parent = 0);
|
||||
~CustomizeSplashDialog();
|
||||
|
||||
private slots:
|
||||
void on_leftLoadFwButton_clicked();
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
void saveButton_clicked( Side );
|
||||
void invertButton_clicked( Side );
|
||||
|
||||
Ui::customizeSplashDialog *ui;
|
||||
Ui::CustomizeSplashDialog *ui;
|
||||
enum sideEnum { LEFT, RIGHT };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>customizeSplashDialog</class>
|
||||
<widget class="QDialog" name="customizeSplashDialog">
|
||||
<class>CustomizeSplashDialog</class>
|
||||
<widget class="QDialog" name="CustomizeSplashDialog">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
|
||||
@@ -114,6 +114,23 @@ void getEEPROMZString(char *dst, const char *src, int size)
|
||||
}
|
||||
}
|
||||
|
||||
QString getElementName(const QString & prefix, unsigned int index, const char * name = NULL, bool padding = false)
|
||||
{
|
||||
QString result = prefix;
|
||||
if (padding)
|
||||
result += QString("%1").arg(index, 2, 10, QChar('0'));
|
||||
else
|
||||
result += QString("%1").arg(index);
|
||||
if (name) {
|
||||
QString trimmed = QString(name).trimmed();
|
||||
if (trimmed.length() > 0) {
|
||||
result += ":" + QString(name).trimmed();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
float ValToTim(int value)
|
||||
{
|
||||
return ((value < -109 ? 129+value : (value < 7 ? (113+value)*5 : (53+value)*10))/10.0);
|
||||
@@ -134,27 +151,6 @@ int TimToVal(float value)
|
||||
return (temp-129);
|
||||
}
|
||||
|
||||
QString getSignedStr(int value)
|
||||
{
|
||||
return value > 0 ? QString("+%1").arg(value) : QString("%1").arg(value);
|
||||
}
|
||||
|
||||
QString getGVarString(int16_t val, bool sign)
|
||||
{
|
||||
if (val >= -10000 && val <= 10000) {
|
||||
if (sign)
|
||||
return QString("%1%").arg(getSignedStr(val));
|
||||
else
|
||||
return QString("%1%").arg(val);
|
||||
}
|
||||
else {
|
||||
if (val<0)
|
||||
return QObject::tr("-GV%1").arg(-val-10000);
|
||||
else
|
||||
return QObject::tr("GV%1").arg(val-10000);
|
||||
}
|
||||
}
|
||||
|
||||
void SensorData::updateUnit()
|
||||
{
|
||||
if (type == TELEM_TYPE_CALCULATED) {
|
||||
@@ -494,17 +490,6 @@ RawSourceRange RawSource::getRange(const ModelData * model, const GeneralSetting
|
||||
return result;
|
||||
}
|
||||
|
||||
QString RotaryEncoderString(int index)
|
||||
{
|
||||
static const QString rotary[] = { QObject::tr("REa"), QObject::tr("REb") };
|
||||
return CHECK_IN_ARRAY(rotary, index);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RawSource
|
||||
*/
|
||||
|
||||
QString RawSource::toString(const ModelData * model, const GeneralSettings * const generalSettings) const
|
||||
{
|
||||
static const QString trims[] = {
|
||||
@@ -530,6 +515,8 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
QObject::tr("ACC"), QObject::tr("GPS Time"),
|
||||
};
|
||||
|
||||
static const QString rotary[] = { QObject::tr("REa"), QObject::tr("REb") };
|
||||
|
||||
if (index<0) {
|
||||
return QObject::tr("----");
|
||||
}
|
||||
@@ -538,10 +525,12 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
int genAryIdx = 0;
|
||||
switch (type) {
|
||||
case SOURCE_TYPE_VIRTUAL_INPUT:
|
||||
result = QObject::tr("[I%1]").arg(index+1);
|
||||
{
|
||||
const char * name = NULL;
|
||||
if (model)
|
||||
result += QString(model->inputNames[index]);
|
||||
return result;
|
||||
name = model->inputNames[index];
|
||||
return getElementName(QCoreApplication::translate("Input", "I"), index + 1, name);
|
||||
}
|
||||
|
||||
case SOURCE_TYPE_LUA_OUTPUT:
|
||||
return QObject::tr("LUA%1%2").arg(index/16+1).arg(QChar('a'+index%16));
|
||||
@@ -552,8 +541,8 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
result = QString(generalSettings->potName[genAryIdx]);
|
||||
else if (isSlider(&genAryIdx))
|
||||
result = QString(generalSettings->sliderName[genAryIdx]);
|
||||
else
|
||||
result = QString(generalSettings->stickName[index]);
|
||||
else if (isStick(&genAryIdx))
|
||||
result = QString(generalSettings->stickName[genAryIdx]);
|
||||
}
|
||||
if (result.isEmpty())
|
||||
result = getCurrentFirmware()->getAnalogInputName(index);;
|
||||
@@ -562,7 +551,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
case SOURCE_TYPE_TRIM:
|
||||
return CHECK_IN_ARRAY(trims, index);
|
||||
case SOURCE_TYPE_ROTARY_ENCODER:
|
||||
return RotaryEncoderString(index);
|
||||
return CHECK_IN_ARRAY(rotary, index);
|
||||
case SOURCE_TYPE_MAX:
|
||||
return QObject::tr("MAX");
|
||||
|
||||
@@ -574,16 +563,21 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
return result;
|
||||
|
||||
case SOURCE_TYPE_CUSTOM_SWITCH:
|
||||
return QObject::tr("L%1").arg(index+1);
|
||||
return RawSwitch(SWITCH_TYPE_VIRTUAL, index+1).toString();
|
||||
|
||||
case SOURCE_TYPE_CYC:
|
||||
return QObject::tr("CYC%1").arg(index+1);
|
||||
|
||||
case SOURCE_TYPE_PPM:
|
||||
return QObject::tr("TR%1").arg(index+1);
|
||||
return getElementName(QCoreApplication::translate("Trainer", "TR"), index + 1);
|
||||
|
||||
case SOURCE_TYPE_CH:
|
||||
return QObject::tr("CH%1").arg(index+1);
|
||||
{
|
||||
const char * name = NULL;
|
||||
if (getCurrentFirmware()->getCapability(ChannelsName) && model)
|
||||
name = model->limitData[index].name;
|
||||
return getElementName(QCoreApplication::translate("Channel", "CH"), index + 1, name);
|
||||
}
|
||||
|
||||
case SOURCE_TYPE_SPECIAL:
|
||||
return CHECK_IN_ARRAY(special, index);
|
||||
@@ -591,7 +585,7 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
case SOURCE_TYPE_TELEMETRY:
|
||||
if (IS_ARM(getCurrentBoard())) {
|
||||
div_t qr = div(index, 3);
|
||||
result = model ? QString(model->sensorData[qr.quot].label) : QString("[T%1]").arg(qr.quot+1);
|
||||
result = getElementName(QCoreApplication::translate("Telemetry", "TELE"), qr.quot+1, model ? model->sensorData[qr.quot].label : NULL);
|
||||
if (qr.rem)
|
||||
result += (qr.rem == 1 ? "-" : "+");
|
||||
return result;
|
||||
@@ -601,13 +595,28 @@ QString RawSource::toString(const ModelData * model, const GeneralSettings * con
|
||||
}
|
||||
|
||||
case SOURCE_TYPE_GVAR:
|
||||
return QObject::tr("GV%1").arg(index+1);
|
||||
{
|
||||
const char * name = NULL;
|
||||
if (getCurrentFirmware()->getCapability(GvarsName) && model)
|
||||
name = model->gvarData[index].name;
|
||||
return getElementName(QCoreApplication::translate("Global Variable", "GV"), index + 1, name);
|
||||
}
|
||||
|
||||
default:
|
||||
return QObject::tr("----");
|
||||
}
|
||||
}
|
||||
|
||||
bool RawSource::isStick(int * stickIndex) const
|
||||
{
|
||||
if (type == SOURCE_TYPE_STICK && index < getBoardCapability(getCurrentBoard(), Board::Sticks)) {
|
||||
if (stickIndex)
|
||||
*stickIndex = index;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RawSource::isPot(int * potsIndex) const
|
||||
{
|
||||
if (type == SOURCE_TYPE_STICK &&
|
||||
@@ -636,7 +645,7 @@ bool RawSource::isSlider(int * sliderIndex) const
|
||||
* RawSwitch
|
||||
*/
|
||||
|
||||
QString RawSwitch::toString(Board::Type board, const GeneralSettings * const generalSettings) const
|
||||
QString RawSwitch::toString(Board::Type board, const GeneralSettings * const generalSettings, const ModelData * const modelData) const
|
||||
{
|
||||
if (board == Board::BOARD_UNKNOWN) {
|
||||
board = getCurrentBoard();
|
||||
@@ -648,10 +657,6 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
QString("AIL"), QString("GEA"), QString("TRN")
|
||||
};
|
||||
|
||||
static const QString flightModes[] = {
|
||||
QObject::tr("FM0"), QObject::tr("FM1"), QObject::tr("FM2"), QObject::tr("FM3"), QObject::tr("FM4"), QObject::tr("FM5"), QObject::tr("FM6"), QObject::tr("FM7"), QObject::tr("FM8")
|
||||
};
|
||||
|
||||
static const QString trimsSwitches[] = {
|
||||
QObject::tr("RudTrim Left"), QObject::tr("RudTrim Right"),
|
||||
QObject::tr("EleTrim Down"), QObject::tr("EleTrim Up"),
|
||||
@@ -676,7 +681,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
<< CPN_STR_SW_INDICATOR_DN;
|
||||
|
||||
if (index < 0) {
|
||||
return CPN_STR_SW_INDICATOR_REV % RawSwitch(type, -index).toString(board, generalSettings);
|
||||
return CPN_STR_SW_INDICATOR_REV % RawSwitch(type, -index).toString(board, generalSettings, modelData);
|
||||
}
|
||||
else {
|
||||
QString swName;
|
||||
@@ -696,7 +701,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
}
|
||||
|
||||
case SWITCH_TYPE_VIRTUAL:
|
||||
return QObject::tr("L%1").arg(index);
|
||||
return getElementName(QCoreApplication::translate("Logic Switch", "L"), index, NULL, true);
|
||||
|
||||
case SWITCH_TYPE_MULTIPOS_POT:
|
||||
if (!getCurrentFirmware()->getCapability(MultiposPotsPositions))
|
||||
@@ -724,7 +729,7 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
return QObject::tr("One");
|
||||
|
||||
case SWITCH_TYPE_FLIGHT_MODE:
|
||||
return CHECK_IN_ARRAY(flightModes, index-1);
|
||||
return getElementName(QCoreApplication::translate("Flight mode", "FM"), index - 1, modelData ? modelData->flightModeData[index-1].name : NULL);
|
||||
|
||||
case SWITCH_TYPE_NONE:
|
||||
return QObject::tr("----");
|
||||
@@ -732,6 +737,12 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
case SWITCH_TYPE_TIMER_MODE:
|
||||
return CHECK_IN_ARRAY(timerModes, index);
|
||||
|
||||
case SWITCH_TYPE_SENSOR:
|
||||
return getElementName(QCoreApplication::translate("Telemetry", "TELE"), index, modelData ? modelData->sensorData[index-1].label : NULL);
|
||||
|
||||
case SWITCH_TYPE_TELEMETRY:
|
||||
return QObject::tr("Telemetry");
|
||||
|
||||
default:
|
||||
return QObject::tr("???");
|
||||
}
|
||||
@@ -743,23 +754,48 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen
|
||||
* CurveReference
|
||||
*/
|
||||
|
||||
QString CurveReference::toString() const
|
||||
QString CurveReference::toString(const ModelData * model, bool verbose) const
|
||||
{
|
||||
if (value == 0) {
|
||||
return "----";
|
||||
}
|
||||
else {
|
||||
switch(type) {
|
||||
case CURVE_REF_DIFF:
|
||||
return QObject::tr("Diff(%1)").arg(getGVarString(value));
|
||||
case CURVE_REF_EXPO:
|
||||
return QObject::tr("Expo(%1)").arg(getGVarString(value));
|
||||
case CURVE_REF_FUNC:
|
||||
return QObject::tr("Function(%1)").arg(QString("x>0" "x<0" "|x|" "f>0" "f<0" "|f|").mid(3*(value-1), 3));
|
||||
default:
|
||||
return QString(value > 0 ? QObject::tr("Curve(%1)") : QObject::tr("!Curve(%1)")).arg(abs(value));
|
||||
}
|
||||
|
||||
QString ret;
|
||||
unsigned idx = abs(value) - 1;
|
||||
|
||||
switch(type) {
|
||||
case CURVE_REF_DIFF:
|
||||
ret = QObject::tr("Diff(%1)").arg(Helpers::getAdjustmentString(value, model));
|
||||
break;
|
||||
|
||||
case CURVE_REF_EXPO:
|
||||
ret = QObject::tr("Expo(%1)").arg(Helpers::getAdjustmentString(value, model));
|
||||
break;
|
||||
|
||||
case CURVE_REF_FUNC:
|
||||
ret = QString("x>0" "x<0" "|x|" "f>0" "f<0" "|f|").mid(3*(value-1), 3);
|
||||
if (verbose)
|
||||
ret = QObject::tr("Function(%1)").arg(ret);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (model)
|
||||
ret = model->curves[idx].nameToString(idx);
|
||||
else
|
||||
ret = CurveData().nameToString(idx);
|
||||
if (verbose)
|
||||
ret = QObject::tr("Curve(%1)").arg(ret);
|
||||
if (value < 0)
|
||||
ret.prepend(CPN_STR_SW_INDICATOR_REV);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool LogicalSwitchData::isEmpty() const
|
||||
{
|
||||
return (func == 0);
|
||||
}
|
||||
|
||||
CSFunctionFamily LogicalSwitchData::getFunctionFamily() const
|
||||
@@ -846,10 +882,15 @@ void CustomFunctionData::clear()
|
||||
}
|
||||
}
|
||||
|
||||
QString CustomFunctionData::funcToString() const
|
||||
bool CustomFunctionData::isEmpty() const
|
||||
{
|
||||
return (swtch.type == SWITCH_TYPE_NONE);
|
||||
}
|
||||
|
||||
QString CustomFunctionData::funcToString(const ModelData * model) const
|
||||
{
|
||||
if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32)
|
||||
return QObject::tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString());
|
||||
return QObject::tr("Override %1").arg(RawSource(SOURCE_TYPE_CH, func).toString(model));
|
||||
else if (func == FuncTrainer)
|
||||
return QObject::tr("Trainer");
|
||||
else if (func == FuncTrainerRUD)
|
||||
@@ -893,7 +934,7 @@ QString CustomFunctionData::funcToString() const
|
||||
else if (func == FuncBackgroundMusicPause)
|
||||
return QObject::tr("Background Music Pause");
|
||||
else if (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast)
|
||||
return QObject::tr("Adjust GV%1").arg(func-FuncAdjustGV1+1);
|
||||
return QObject::tr("Adjust %1").arg(RawSource(SOURCE_TYPE_GVAR, func-FuncAdjustGV1).toString(model));
|
||||
else if (func == FuncSetFailsafeInternalModule)
|
||||
return QObject::tr("SetFailsafe Int. Module");
|
||||
else if (func == FuncSetFailsafeExternalModule)
|
||||
@@ -1068,6 +1109,11 @@ bool CurveData::isEmpty() const
|
||||
return true;
|
||||
}
|
||||
|
||||
QString CurveData::nameToString(const int idx) const
|
||||
{
|
||||
return getElementName(QCoreApplication::translate("Curve", "CV"), idx + 1, name);
|
||||
}
|
||||
|
||||
QString LimitData::minToString() const
|
||||
{
|
||||
return QString::number((qreal)min/10);
|
||||
@@ -1132,7 +1178,6 @@ GeneralSettings::GeneralSettings()
|
||||
memset(this, 0, sizeof(GeneralSettings));
|
||||
|
||||
contrast = 25;
|
||||
vBatWarn = 90;
|
||||
|
||||
for (int i=0; i < CPN_MAX_ANALOGS; ++i) {
|
||||
calibMid[i] = 0x200;
|
||||
@@ -1143,7 +1188,29 @@ GeneralSettings::GeneralSettings()
|
||||
Firmware * firmware = Firmware::getCurrentVariant();
|
||||
Board::Type board = firmware->getBoard();
|
||||
|
||||
for (int i=0; i<getBoardCapability(board, Board::FactoryInstalledSwitches); i++) {
|
||||
// vBatWarn is voltage in 100mV, vBatMin is in 100mV but with -9V offset, vBatMax has a -12V offset
|
||||
vBatWarn = 90;
|
||||
if (IS_TARANIS_X9E(board) || IS_HORUS_X12S(board)) {
|
||||
// NI-MH 9.6V
|
||||
vBatWarn = 87;
|
||||
vBatMin = -5; //8,5V
|
||||
vBatMax = -5; //11,5V
|
||||
}
|
||||
else if (IS_HORUS_X10(board)) {
|
||||
// Lipo 2V
|
||||
vBatWarn = 66;
|
||||
vBatMin = -28; // 6.2V
|
||||
vBatMax = -38; // 8.2V
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
// NI-MH 7.2V, X9D, X9D+ and X7
|
||||
vBatWarn = 65;
|
||||
vBatMin = -30; //6V
|
||||
vBatMax = -40; //8V
|
||||
}
|
||||
|
||||
|
||||
for (int i=0; i<getBoardCapability(board, Board::FactoryInstalledSwitches); i++) {
|
||||
switchConfig[i] = Boards::getSwitchInfo(board, i).config;
|
||||
}
|
||||
|
||||
@@ -1173,13 +1240,13 @@ GeneralSettings::GeneralSettings()
|
||||
potConfig[2] = Board::POT_WITHOUT_DETENT;
|
||||
}
|
||||
|
||||
if (IS_HORUS(board) || IS_TARANIS_X9E(board)) {
|
||||
if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board)) {
|
||||
sliderConfig[0] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[1] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[2] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[3] = Board::SLIDER_WITH_DETENT;
|
||||
}
|
||||
else if (IS_TARANIS(board) && !IS_TARANIS_X7(board)) {
|
||||
else if (IS_TARANIS_X9(board) || IS_HORUS_X10(board)) {
|
||||
sliderConfig[0] = Board::SLIDER_WITH_DETENT;
|
||||
sliderConfig[1] = Board::SLIDER_WITH_DETENT;
|
||||
}
|
||||
@@ -1188,7 +1255,7 @@ GeneralSettings::GeneralSettings()
|
||||
speakerVolume = 12;
|
||||
}
|
||||
|
||||
if (IS_TARANIS_X9E(board)) {
|
||||
if (IS_HORUS(board) || IS_TARANIS_X9E(board) || IS_TARANIS_X7(board)) {
|
||||
strcpy(bluetoothName, "Taranis");
|
||||
}
|
||||
|
||||
@@ -1368,8 +1435,6 @@ void FrSkyData::clear()
|
||||
mAhPersistent = 0;
|
||||
storedMah = 0;
|
||||
fasOffset = 0;
|
||||
rssiAlarms[0].clear(2, 45);
|
||||
rssiAlarms[1].clear(3, 42);
|
||||
for (int i=0; i<4; i++)
|
||||
screens[i].clear();
|
||||
varioSource = 2/*VARIO*/;
|
||||
@@ -1494,11 +1559,6 @@ void ModelData::clearMixes()
|
||||
mixData[i].clear();
|
||||
}
|
||||
|
||||
RadioData::RadioData()
|
||||
{
|
||||
models.resize(getCurrentFirmware()->getCapability(Models));
|
||||
}
|
||||
|
||||
void ModelData::clear()
|
||||
{
|
||||
memset(this, 0, sizeof(ModelData));
|
||||
@@ -1525,6 +1585,9 @@ void ModelData::clear()
|
||||
for (int i=0; i<CPN_MAX_FLIGHT_MODES; i++) {
|
||||
flightModeData[i].clear(i);
|
||||
}
|
||||
for (int i=0; i<CPN_MAX_GVARS; i++) {
|
||||
gvarData[i].clear();
|
||||
}
|
||||
clearInputs();
|
||||
clearMixes();
|
||||
for (int i=0; i<CPN_MAX_CHNOUT; i++)
|
||||
@@ -1541,6 +1604,7 @@ void ModelData::clear()
|
||||
timers[i].clear();
|
||||
swashRingData.clear();
|
||||
frsky.clear();
|
||||
rssiAlarms.clear();
|
||||
for (int i=0; i<CPN_MAX_SENSORS; i++)
|
||||
sensorData[i].clear();
|
||||
|
||||
@@ -1657,8 +1721,8 @@ bool ModelData::isGVarLinked(int phaseIdx, int gvarIdx)
|
||||
int ModelData::getGVarFieldValue(int phaseIdx, int gvarIdx)
|
||||
{
|
||||
int idx = flightModeData[phaseIdx].gvars[gvarIdx];
|
||||
for (int i=0; idx>1024 && i<CPN_MAX_FLIGHT_MODES; i++) {
|
||||
int nextPhase = idx - 1025;
|
||||
for (int i=0; idx>GVAR_MAX_VALUE && i<CPN_MAX_FLIGHT_MODES; i++) {
|
||||
int nextPhase = idx - GVAR_MAX_VALUE - 1;
|
||||
if (nextPhase >= phaseIdx) nextPhase += 1;
|
||||
phaseIdx = nextPhase;
|
||||
idx = flightModeData[phaseIdx].gvars[gvarIdx];
|
||||
@@ -1727,6 +1791,29 @@ int ModelData::getChannelsMax(bool forceExtendedLimits) const
|
||||
return 100;
|
||||
}
|
||||
|
||||
bool ModelData::isAvailable(const RawSwitch & swtch) const
|
||||
{
|
||||
unsigned index = abs(swtch.index) - 1;
|
||||
|
||||
if (swtch.type == SWITCH_TYPE_VIRTUAL) {
|
||||
return logicalSw[index].func != LS_FN_OFF;
|
||||
}
|
||||
else if (swtch.type == SWITCH_TYPE_FLIGHT_MODE) {
|
||||
return index == 0 || flightModeData[index].swtch.type != SWITCH_TYPE_NONE;
|
||||
}
|
||||
else if (swtch.type == SWITCH_TYPE_SENSOR) {
|
||||
return strlen(sensorData[index].label) > 0;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
float ModelData::getGVarFieldValuePrec(int phaseIdx, int gvarIdx)
|
||||
{
|
||||
return getGVarFieldValue(phaseIdx, gvarIdx) * gvarData[gvarIdx].multiplierGet();
|
||||
}
|
||||
|
||||
QList<EEPROMInterface *> eepromInterfaces;
|
||||
|
||||
void unregisterEEpromInterfaces()
|
||||
@@ -1778,7 +1865,7 @@ void ShowEepromWarnings(QWidget *parent, const QString &title, unsigned long err
|
||||
std::bitset<NUM_ERRORS> errors((unsigned long long)errorsFound);
|
||||
QStringList warningsList;
|
||||
if (errors.test(WARNING_WRONG_FIRMWARE)) { warningsList << QT_TRANSLATE_NOOP("EepromInterface", "- Your radio probably uses a wrong firmware,\n eeprom size is 4096 but only the first 2048 are used"); }
|
||||
if (errors.test(OLD_VERSION)) { warningsList << QT_TRANSLATE_NOOP("EepromInterface", "- Your eeprom is from an old version of OpenTX, upgrading!\n You should 'save as' to keep the old file as a backup."); }
|
||||
if (errors.test(OLD_VERSION)) { warningsList << QT_TRANSLATE_NOOP("EepromInterface", "- Your eeprom is from an old version of OpenTX, upgrading!\n To keep your original file as a backup, please choose File -> Save As specifying a different name."); }
|
||||
|
||||
QMessageBox msgBox(parent);
|
||||
msgBox.setWindowTitle(title);
|
||||
@@ -1861,3 +1948,67 @@ void FlightModeData::clear(const int phase)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString GVarData::unitToString() const
|
||||
{
|
||||
switch (unit) {
|
||||
case GVAR_UNIT_NUMBER:
|
||||
return QObject::tr("");
|
||||
case GVAR_UNIT_PERCENT:
|
||||
return QObject::tr("%");
|
||||
default:
|
||||
return QObject::tr("?"); // highlight unknown value
|
||||
}
|
||||
}
|
||||
|
||||
QString GVarData::precToString() const
|
||||
{
|
||||
switch (prec) {
|
||||
case GVAR_PREC_MUL10:
|
||||
return QObject::tr("0._");
|
||||
case GVAR_PREC_MUL1:
|
||||
return QObject::tr("0.0");
|
||||
default:
|
||||
return QObject::tr("?.?"); // highlight unknown value
|
||||
}
|
||||
}
|
||||
|
||||
int GVarData::multiplierSet()
|
||||
{
|
||||
return (prec == 0 ? 1 : 10);
|
||||
}
|
||||
|
||||
float GVarData::multiplierGet() const
|
||||
{
|
||||
return (prec == 0 ? 1 : 0.1);
|
||||
}
|
||||
|
||||
void GVarData::setMin(float val)
|
||||
{
|
||||
min = (val * multiplierSet()) - GVAR_MIN_VALUE;
|
||||
}
|
||||
|
||||
void GVarData::setMax(float val)
|
||||
{
|
||||
max = GVAR_MAX_VALUE - (val * multiplierSet());
|
||||
}
|
||||
|
||||
int GVarData::getMin() const
|
||||
{
|
||||
return GVAR_MIN_VALUE + min;
|
||||
}
|
||||
|
||||
int GVarData::getMax() const
|
||||
{
|
||||
return GVAR_MAX_VALUE - max;
|
||||
}
|
||||
|
||||
float GVarData::getMinPrec() const
|
||||
{
|
||||
return getMin() * multiplierGet();
|
||||
}
|
||||
|
||||
float GVarData::getMaxPrec() const
|
||||
{
|
||||
return getMax() * multiplierGet();
|
||||
}
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
#include <iostream>
|
||||
#include <QDebug>
|
||||
|
||||
QString RotaryEncoderString(int index);
|
||||
|
||||
const uint8_t modn12x3[4][4]= {
|
||||
{1, 2, 3, 4},
|
||||
{1, 3, 2, 4},
|
||||
@@ -52,7 +50,6 @@ enum Capability {
|
||||
VoicesMaxLength,
|
||||
MultiLangVoice,
|
||||
ModelImage,
|
||||
SwitchesPositions,
|
||||
CustomFunctions,
|
||||
SafetyChannelCustomFunction,
|
||||
LogicalSwitches,
|
||||
@@ -72,6 +69,8 @@ enum Capability {
|
||||
SoundMod,
|
||||
SoundPitch,
|
||||
MaxVolume,
|
||||
MaxContrast,
|
||||
MinContrast,
|
||||
Haptic,
|
||||
HasBeeper,
|
||||
ModelTrainerEnable,
|
||||
@@ -187,9 +186,6 @@ void getEEPROMString(char *dst, const char *src, int size);
|
||||
float ValToTim(int value);
|
||||
int TimToVal(float value);
|
||||
|
||||
QString getSignedStr(int value);
|
||||
QString getGVarString(int16_t val, bool sign=false);
|
||||
|
||||
inline int applyStickMode(int stick, unsigned int mode)
|
||||
{
|
||||
if (mode == 0 || mode > 4) {
|
||||
|
||||
@@ -95,7 +95,6 @@ Er9xGeneral::operator GeneralSettings ()
|
||||
|
||||
result.view = std::min((uint8_t)4, view);
|
||||
result.disableThrottleWarning = disableThrottleWarning;
|
||||
result.switchWarning = disableSwitchWarning ? 0 : -1;
|
||||
result.disableMemoryWarning = disableMemoryWarning;
|
||||
|
||||
switch (beeperVal) {
|
||||
|
||||
@@ -82,7 +82,9 @@ inline void applyStickModeToModel(Er9xModelData & model, unsigned int mode)
|
||||
#if 0
|
||||
unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
std::cout << "trying er9x xml import... ";
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying er9x xml import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
@@ -94,7 +96,7 @@ unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
}
|
||||
else {
|
||||
radioData.generalSettings=er9xGeneral;
|
||||
std::cout << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
dbg << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
}
|
||||
for (int i=0; i<getCapability(Models); i++) {
|
||||
Er9xModelData er9xModel;
|
||||
@@ -104,7 +106,7 @@ unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
radioData.models[i] = er9xModel;
|
||||
}
|
||||
}
|
||||
std::cout << "ok\n";
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
@@ -112,18 +114,20 @@ unsigned long Er9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
|
||||
unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
std::cout << "trying er9x import... ";
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying er9x import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != Boards::getEEpromSize(Board::BOARD_STOCK)) {
|
||||
std::cout << "wrong size\n";
|
||||
dbg << "wrong size";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_STOCK)) {
|
||||
std::cout << "wrong file system\n";
|
||||
dbg << "wrong file system";
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
@@ -132,16 +136,16 @@ unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, i
|
||||
Er9xGeneral er9xGeneral;
|
||||
|
||||
if (efile->readRlc1((uint8_t*)&er9xGeneral, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
dbg << "no";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
dbg << "version " << (unsigned int)er9xGeneral.myVers << " ";
|
||||
|
||||
switch(er9xGeneral.myVers) {
|
||||
case 3:
|
||||
std::cout << "(old gruvin9x) ";
|
||||
dbg << "(old gruvin9x) ";
|
||||
case 4:
|
||||
// case 5:
|
||||
case 6:
|
||||
@@ -151,14 +155,14 @@ unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, i
|
||||
case 10:
|
||||
break;
|
||||
default:
|
||||
std::cout << "not er9x\n";
|
||||
dbg << "not er9x";
|
||||
errors.set(NOT_ER9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (!efile->readRlc1((uint8_t*)&er9xGeneral, sizeof(Er9xGeneral))) {
|
||||
std::cout << "ko\n";
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
|
||||
@@ -177,7 +181,7 @@ unsigned long Er9xInterface::load(RadioData &radioData, const uint8_t *eeprom, i
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "ok\n";
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
@@ -120,7 +120,6 @@ Ersky9xGeneral::operator GeneralSettings ()
|
||||
result.trainer = trainer;
|
||||
result.view = std::min((uint8_t)4, view);
|
||||
result.disableThrottleWarning = disableThrottleWarning;
|
||||
result.switchWarning = disableSwitchWarning ? 0 : -1;
|
||||
result.disableMemoryWarning = disableMemoryWarning;
|
||||
|
||||
switch (beeperVal) {
|
||||
|
||||
@@ -116,7 +116,9 @@ inline void applyStickModeToModel(Ersky9xModelData_v11 & model, unsigned int mod
|
||||
#if 0
|
||||
unsigned long Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
{
|
||||
std::cout << "trying ersky9x xml import... ";
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying ersky9x xml import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
@@ -128,25 +130,25 @@ unsigned long Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
}
|
||||
else {
|
||||
radioData.generalSettings=ersky9xGeneral;
|
||||
std::cout << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
dbg << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
}
|
||||
for(int i=0; i<getCapability(Models); i++) {
|
||||
if (ersky9xGeneral.myVers == 10) {
|
||||
if (!loadModelDataXML<Ersky9xModelData_v10>(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) {
|
||||
std::cout << "ko\n";
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!loadModelDataXML<Ersky9xModelData_v11>(&doc, &radioData.models[i], i, radioData.generalSettings.stickMode+1)) {
|
||||
std::cout << "ko\n";
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << "ok\n";
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
@@ -154,18 +156,20 @@ unsigned long Ersky9xInterface::loadxml(RadioData &radioData, QDomDocument &doc)
|
||||
|
||||
unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom, int size)
|
||||
{
|
||||
std::cout << "trying ersky9x import... ";
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying ersky9x import... ";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
if (size != Boards::getEEpromSize(Board::BOARD_SKY9X)) {
|
||||
std::cout << "wrong size\n";
|
||||
dbg << "wrong size";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *)eeprom, size, Board::BOARD_SKY9X)) {
|
||||
std::cout << "wrong file system\n";
|
||||
dbg << "wrong file system";
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
@@ -174,12 +178,12 @@ unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom
|
||||
Ersky9xGeneral ersky9xGeneral;
|
||||
|
||||
if (efile->readRlc2((uint8_t*)&ersky9xGeneral, 1) != 1) {
|
||||
std::cout << "no\n";
|
||||
dbg << "no";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
dbg << "version " << (unsigned int)ersky9xGeneral.myVers << " ";
|
||||
|
||||
switch(ersky9xGeneral.myVers) {
|
||||
case 10:
|
||||
@@ -187,13 +191,13 @@ unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom
|
||||
case 11:
|
||||
break;
|
||||
default:
|
||||
std::cout << "not ersky9x\n";
|
||||
dbg << "not ersky9x";
|
||||
errors.set(NOT_ERSKY9X);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
efile->openRd(FILE_GENERAL);
|
||||
if (!efile->readRlc2((uint8_t*)&ersky9xGeneral, sizeof(Ersky9xGeneral))) {
|
||||
std::cout << "ko\n";
|
||||
dbg << "ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
@@ -225,7 +229,7 @@ unsigned long Ersky9xInterface::load(RadioData &radioData, const uint8_t *eeprom
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "ok\n";
|
||||
dbg << "ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ class SwitchesConversionTable: public ConversionTable {
|
||||
|
||||
addConversion(RawSwitch(SWITCH_TYPE_OFF), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_ON), val++);
|
||||
|
||||
if (version >= 216) {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_ONE, -1), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_ONE, 1), val++);
|
||||
@@ -144,6 +145,15 @@ class SwitchesConversionTable: public ConversionTable {
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ARM(board) && version >= 218) {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_TELEMETRY, -1), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_TELEMETRY, 1), val++);
|
||||
for (int i=1; i<=CPN_MAX_SENSORS; i++) {
|
||||
addConversion(RawSwitch(SWITCH_TYPE_SENSOR, -i), -val+offset);
|
||||
addConversion(RawSwitch(SWITCH_TYPE_SENSOR, i), val++);
|
||||
}
|
||||
}
|
||||
|
||||
if (version < 216) {
|
||||
// previous "moment" switches
|
||||
for (int i=1; i<=MAX_SWITCHES_POSITION(board, version); i++) {
|
||||
@@ -243,9 +253,12 @@ class SourcesConversionTable: public ConversionTable {
|
||||
for (int i=0; i<32; i++) {
|
||||
addConversion(RawSource(SOURCE_TYPE_VIRTUAL_INPUT, i), val++);
|
||||
}
|
||||
for (int i=0; i<MAX_SCRIPTS(board); i++) {
|
||||
for (int j=0; j<6; j++) {
|
||||
addConversion(RawSource(SOURCE_TYPE_LUA_OUTPUT, i*16+j), val++);
|
||||
}
|
||||
|
||||
if (IS_STM32(board) && version >= 216) {
|
||||
for (int i = 0; i < MAX_SCRIPTS(board); i++) {
|
||||
for (int j = 0; j < 6; j++) {
|
||||
addConversion(RawSource(SOURCE_TYPE_LUA_OUTPUT, i * 16 + j), val++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -613,7 +626,7 @@ class SourceField: public ConversionField< UnsignedField<N> > {
|
||||
};
|
||||
|
||||
|
||||
int smallGvarToEEPROM(int gvar)
|
||||
int smallGvarImport(int gvar)
|
||||
{
|
||||
if (gvar < -10000) {
|
||||
gvar = 128 + gvar + 10000;
|
||||
@@ -624,7 +637,7 @@ int smallGvarToEEPROM(int gvar)
|
||||
return gvar;
|
||||
}
|
||||
|
||||
int smallGvarToC9x(int gvar)
|
||||
int smallGvarExport(int gvar)
|
||||
{
|
||||
if (gvar > 110) {
|
||||
gvar = gvar - 128 - 10000;
|
||||
@@ -751,7 +764,7 @@ class CurveReferenceField: public TransformedField {
|
||||
{
|
||||
if (curve.value != 0) {
|
||||
_curve_type = (unsigned int)curve.type;
|
||||
_curve_value = smallGvarToEEPROM(curve.value);
|
||||
_curve_value = smallGvarImport(curve.value);
|
||||
}
|
||||
else {
|
||||
_curve_type = 0;
|
||||
@@ -762,7 +775,7 @@ class CurveReferenceField: public TransformedField {
|
||||
virtual void afterImport()
|
||||
{
|
||||
curve.type = (CurveReference::CurveRefType)_curve_type;
|
||||
curve.value = smallGvarToC9x(_curve_value);
|
||||
curve.value = smallGvarExport(_curve_value);
|
||||
qCDebug(eepromImport) << QString("imported CurveReference(%1)").arg(curve.toString());
|
||||
}
|
||||
|
||||
@@ -881,7 +894,7 @@ class FlightModeField: public TransformedField {
|
||||
virtual void beforeExport()
|
||||
{
|
||||
for (int i=0; i<CPN_MAX_STICKS+MAX_AUX_TRIMS(board); i++) {
|
||||
if (IS_HORUS_OR_TARANIS(board) && version >= 216) {
|
||||
if ((IS_HORUS_OR_TARANIS(board) && version >= 216) || (IS_ARM(board) && version >= 218)) {
|
||||
if (phase.trimMode[i] < 0)
|
||||
trimMode[i] = TRIM_MODE_NONE;
|
||||
else
|
||||
@@ -909,7 +922,7 @@ class FlightModeField: public TransformedField {
|
||||
virtual void afterImport()
|
||||
{
|
||||
for (int i=0; i<CPN_MAX_STICKS+MAX_AUX_TRIMS(board); i++) {
|
||||
if (IS_HORUS_OR_TARANIS(board) && version >= 216) {
|
||||
if ((IS_HORUS_OR_TARANIS(board) && version >= 216) || (IS_ARM(board) && version >= 218)) {
|
||||
if (trimMode[i] == TRIM_MODE_NONE) {
|
||||
phase.trimMode[i] = -1;
|
||||
}
|
||||
@@ -993,7 +1006,7 @@ class MixField: public TransformedField {
|
||||
else
|
||||
internalField.Append(new ZCharField<6>(this, mix.name));
|
||||
}
|
||||
else if (IS_TARANIS(board) && version >= 217) {
|
||||
else if (IS_TARANIS(board) && version == 217) {
|
||||
internalField.Append(new UnsignedField<8>(this, _destCh));
|
||||
internalField.Append(new UnsignedField<9>(this, mix.flightModes));
|
||||
internalField.Append(new UnsignedField<2>(this, (unsigned int &)mix.mltpx));
|
||||
@@ -1010,7 +1023,7 @@ class MixField: public TransformedField {
|
||||
internalField.Append(new UnsignedField<8>(this, mix.speedDown));
|
||||
internalField.Append(new ZCharField<8>(this, mix.name));
|
||||
}
|
||||
else if (IS_ARM(board) && version >= 217) {
|
||||
else if (IS_ARM(board) && version == 217) {
|
||||
internalField.Append(new UnsignedField<5>(this, _destCh));
|
||||
internalField.Append(new UnsignedField<3>(this, mix.mixWarn));
|
||||
internalField.Append(new UnsignedField<9>(this, mix.flightModes));
|
||||
@@ -1169,7 +1182,7 @@ class MixField: public TransformedField {
|
||||
}
|
||||
else if (mix.curve.type == CurveReference::CURVE_REF_DIFF) {
|
||||
_curveMode = 0;
|
||||
_curveParam = smallGvarToEEPROM(mix.curve.value);
|
||||
_curveParam = smallGvarImport(mix.curve.value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1204,9 +1217,9 @@ class MixField: public TransformedField {
|
||||
|
||||
if (mix.srcRaw.type != SOURCE_TYPE_NONE) {
|
||||
mix.destCh = _destCh + 1;
|
||||
if (!IS_STM32(board) || version < 216) {
|
||||
if (!IS_ARM(board) || (!IS_STM32(board) && version < 218) || version < 216) {
|
||||
if (!_curveMode)
|
||||
mix.curve = CurveReference(CurveReference::CURVE_REF_DIFF, smallGvarToC9x(_curveParam));
|
||||
mix.curve = CurveReference(CurveReference::CURVE_REF_DIFF, smallGvarExport(_curveParam));
|
||||
else if (_curveParam > 6)
|
||||
mix.curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, _curveParam-6);
|
||||
else if (_curveParam < 0)
|
||||
@@ -1366,13 +1379,13 @@ class InputField: public TransformedField {
|
||||
|
||||
virtual void beforeExport()
|
||||
{
|
||||
_weight = smallGvarToEEPROM(expo.weight);
|
||||
_weight = smallGvarImport(expo.weight);
|
||||
|
||||
if (IS_HORUS_OR_TARANIS(board) && version >= 216) {
|
||||
_offset = smallGvarToEEPROM(expo.offset);
|
||||
if ((IS_HORUS_OR_TARANIS(board) && version >= 216) || (IS_ARM(board) && version >= 218)) {
|
||||
_offset = smallGvarImport(expo.offset);
|
||||
}
|
||||
|
||||
if (!IS_TARANIS(board) || version < 216) {
|
||||
if (!IS_ARM(board) || (!IS_TARANIS(board) && version < 218) || version < 216) {
|
||||
if (expo.curve.type==CurveReference::CURVE_REF_FUNC && expo.curve.value) {
|
||||
_curveMode = true;
|
||||
_curveParam = expo.curve.value;
|
||||
@@ -1383,33 +1396,26 @@ class InputField: public TransformedField {
|
||||
}
|
||||
else {
|
||||
_curveMode = false;
|
||||
_curveParam = smallGvarToEEPROM(expo.curve.value);
|
||||
_curveParam = smallGvarImport(expo.curve.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void afterImport()
|
||||
{
|
||||
if (IS_STM32(board)) {
|
||||
if (version < 216) {
|
||||
if (expo.mode) {
|
||||
expo.srcRaw = RawSource(SOURCE_TYPE_STICK, expo.chn);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (expo.mode) {
|
||||
if ((IS_STM32(board) && version < 216 )|| (!IS_STM32(board) && expo.mode)) {
|
||||
expo.srcRaw = RawSource(SOURCE_TYPE_STICK, expo.chn);
|
||||
}
|
||||
|
||||
expo.weight = smallGvarToC9x(_weight);
|
||||
expo.weight = smallGvarExport(_weight);
|
||||
|
||||
if (IS_STM32(board) && version >= 216) {
|
||||
expo.offset = smallGvarToC9x(_offset);
|
||||
if ((IS_STM32(board) && version >= 216) || (IS_ARM(board) && version >= 218)) {
|
||||
expo.offset = smallGvarExport(_offset);
|
||||
}
|
||||
|
||||
if (!IS_STM32(board) || version < 216) {
|
||||
if (!IS_ARM(board) || (!IS_TARANIS(board) && version < 218) || version < 216) {
|
||||
if (!_curveMode)
|
||||
expo.curve = CurveReference(CurveReference::CURVE_REF_EXPO, smallGvarToC9x(_curveParam));
|
||||
expo.curve = CurveReference(CurveReference::CURVE_REF_EXPO, smallGvarExport(_curveParam));
|
||||
else if (_curveParam > 6)
|
||||
expo.curve = CurveReference(CurveReference::CURVE_REF_CUSTOM, _curveParam-6);
|
||||
else
|
||||
@@ -1592,7 +1598,7 @@ class CurvesField: public TransformedField {
|
||||
|
||||
for (int i=0; i<maxCurves; i++) {
|
||||
CurveData * curve = &curves[i];
|
||||
if (!IS_STM32(board) || version < 216) {
|
||||
if (!IS_ARM(board) || (!IS_STM32(board) && version < 218) || version < 216) {
|
||||
int * next = &_points[5*(i+1) + _curves[i]];
|
||||
int size = next - cur;
|
||||
if (size % 2 == 0) {
|
||||
@@ -2577,13 +2583,13 @@ class FrskyScreenField: public DataField {
|
||||
bars.Append(new SourceField<16>(this, screen.body.bars[i].source, board, version, variant));
|
||||
else
|
||||
bars.Append(new SourceField<8>(this, screen.body.bars[i].source, board, version, variant));
|
||||
bars.Append(new UnsignedField<16>(this, screen.body.bars[i].barMin));
|
||||
bars.Append(new UnsignedField<16>(this, screen.body.bars[i].barMax));
|
||||
bars.Append(new SignedField<16>(this, screen.body.bars[i].barMin));
|
||||
bars.Append(new SignedField<16>(this, screen.body.bars[i].barMax));
|
||||
}
|
||||
else {
|
||||
bars.Append(new TelemetrySourceField<8>(this, screen.body.bars[i].source, board, version));
|
||||
bars.Append(new UnsignedField<8>(this, screen.body.bars[i].barMin));
|
||||
bars.Append(new UnsignedField<8>(this, screen.body.bars[i].barMax));
|
||||
bars.Append(new UnsignedField<8>(this, (unsigned &)screen.body.bars[i].barMin));
|
||||
bars.Append(new UnsignedField<8>(this, (unsigned &)screen.body.bars[i].barMax));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2774,7 +2780,7 @@ class TelemetryCurrentSourceConversionTable: public ConversionTable
|
||||
|
||||
class FrskyField: public StructField {
|
||||
public:
|
||||
FrskyField(DataField * parent, FrSkyData & frsky, Board::Type board, unsigned int version, unsigned int variant):
|
||||
FrskyField(DataField * parent, FrSkyData & frsky, RSSIAlarmData & rssiAlarms, Board::Type board, unsigned int version, unsigned int variant):
|
||||
StructField(parent, "FrSky"),
|
||||
telemetryVarioSourceConversionTable(board, version),
|
||||
screenTypesConversionTable(board, version),
|
||||
@@ -2846,10 +2852,12 @@ class FrskyField: public StructField {
|
||||
Append(new SignedField<8>(this, frsky.varioCenterMin));
|
||||
Append(new SignedField<8>(this, frsky.varioMin));
|
||||
Append(new SignedField<8>(this, frsky.varioMax));
|
||||
for (int i=0; i<2; i++) {
|
||||
Append(new ConversionField< UnsignedField<2> >(this, frsky.rssiAlarms[i].level, &rssiConversionTable[i], "RSSI"));
|
||||
Append(new ConversionField< SignedField<6> >(this, frsky.rssiAlarms[i].value, -45+i*3));
|
||||
}
|
||||
Append(new BoolField<1>(this, rssiAlarms.disabled));
|
||||
Append(new SpareBitsField<1>(this));
|
||||
Append(new ConversionField<SignedField<6> >(this, rssiAlarms.warning, -45));
|
||||
Append(new SpareBitsField<2>(this));
|
||||
Append(new ConversionField<SignedField<6> >(this, rssiAlarms.critical, -42));
|
||||
|
||||
if (version == 216) {
|
||||
Append(new BoolField<1>(this, frsky.mAhPersistent));
|
||||
Append(new UnsignedField<15>(this, frsky.storedMah));
|
||||
@@ -2878,8 +2886,8 @@ class FrskyField: public StructField {
|
||||
Append(new SignedField<4>(this, frsky.varioMin, "Vario Min"));
|
||||
Append(new SignedField<4>(this, frsky.varioMax));
|
||||
for (int i=0; i<2; i++) {
|
||||
Append(new ConversionField< UnsignedField<2> >(this, frsky.rssiAlarms[i].level, &rssiConversionTable[i], "RSSI level"));
|
||||
Append(new ConversionField< SignedField<6> >(this, frsky.rssiAlarms[i].value, -45+i*3, 0, 0, 100, "RSSI value"));
|
||||
Append(new ConversionField< UnsignedField<2> >(this, rssiAlarms.level[i], &rssiConversionTable[i], "RSSI level"));
|
||||
Append(new ConversionField< SignedField<6> >(this, i ==0 ? rssiAlarms.warning : rssiAlarms.critical, -45+i*3, 0, 0, 100, "RSSI value"));
|
||||
}
|
||||
for (int i=0; i<2; i++) {
|
||||
Append(new FrskyScreenField(this, frsky.screens[i], board, version, variant));
|
||||
@@ -3218,18 +3226,19 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
|
||||
if (board != BOARD_STOCK && (board != BOARD_M128 || version < 215)) {
|
||||
for (int i=0; i<MAX_GVARS(board, version); i++) {
|
||||
if (version >= 218) {
|
||||
internalField.Append(new ZCharField<3>(this, modelData.gvars_names[i], "GVar name"));
|
||||
internalField.Append(new SpareBitsField<12>(this)); // TODO min
|
||||
internalField.Append(new SpareBitsField<12>(this)); // TODO max
|
||||
internalField.Append(new BoolField<1>(this, modelData.gvars_popups[i]));
|
||||
internalField.Append(new SpareBitsField<1>(this));
|
||||
internalField.Append(new SpareBitsField<2>(this));
|
||||
internalField.Append(new ZCharField<3>(this, modelData.gvarData[i].name, "GVar name"));
|
||||
internalField.Append(new UnsignedField<12>(this, (unsigned &)modelData.gvarData[i].min));
|
||||
internalField.Append(new UnsignedField<12>(this, (unsigned &)modelData.gvarData[i].max));
|
||||
internalField.Append(new BoolField<1>(this, modelData.gvarData[i].popup));
|
||||
internalField.Append(new UnsignedField<1>(this, modelData.gvarData[i].prec));
|
||||
internalField.Append(new UnsignedField<2>(this, modelData.gvarData[i].unit));
|
||||
internalField.Append(new SpareBitsField<4>(this));
|
||||
}
|
||||
else {
|
||||
internalField.Append(new ZCharField<6>(this, modelData.gvars_names[i], "GVar name"));
|
||||
internalField.Append(new ZCharField<3>(this, modelData.gvarData[i].name, "GVar name"));
|
||||
internalField.Append(new SpareBitsField<3*8>(this));
|
||||
if (version >= 216) {
|
||||
internalField.Append(new BoolField<1>(this, modelData.gvars_popups[i]));
|
||||
internalField.Append(new BoolField<1>(this, modelData.gvarData[i].popup));
|
||||
internalField.Append(new SpareBitsField<7>(this));
|
||||
}
|
||||
}
|
||||
@@ -3243,7 +3252,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig
|
||||
}
|
||||
|
||||
if ((board != BOARD_STOCK && (board != BOARD_M128 || version < 215)) || (variant & FRSKY_VARIANT)) {
|
||||
internalField.Append(new FrskyField(this, modelData.frsky, board, version, variant));
|
||||
internalField.Append(new FrskyField(this, modelData.frsky, modelData.rssiAlarms, board, version, variant));
|
||||
}
|
||||
else if ((board == BOARD_STOCK || board == BOARD_M128) && (variant & MAVLINK_VARIANT)) {
|
||||
internalField.Append(new MavlinkField(this, modelData.mavlink, board, version));
|
||||
@@ -3420,8 +3429,18 @@ void OpenTxModelData::beforeExport()
|
||||
// qDebug() << QString("before export model") << modelData.name;
|
||||
|
||||
for (int module=0; module<3; module++) {
|
||||
if (modelData.moduleData[module].protocol >= PULSES_PXX_XJT_X16 && modelData.moduleData[module].protocol <= PULSES_PXX_XJT_LR12) {
|
||||
subprotocols[module] = modelData.moduleData[module].protocol - PULSES_PXX_XJT_X16;
|
||||
if ((modelData.moduleData[module].protocol >= PULSES_PXX_XJT_X16 && modelData.moduleData[module].protocol <= PULSES_PXX_XJT_LR12) ||
|
||||
modelData.moduleData[module].protocol == PULSES_PXX_R9M) {
|
||||
if (! (modelData.moduleData[module].protocol == PULSES_PXX_R9M)) {
|
||||
subprotocols[module] = modelData.moduleData[module].protocol - PULSES_PXX_XJT_X16;
|
||||
}
|
||||
int pxxByte = (modelData.moduleData[module].pxx.power & 0x03)
|
||||
| modelData.moduleData[module].pxx.receiver_telem_off << 4
|
||||
| modelData.moduleData[module].pxx.receiver_channel_9_16 << 5;
|
||||
modelData.moduleData[module].ppm.delay = 300 + 50 * pxxByte;
|
||||
modelData.moduleData[module].ppm.pulsePol = modelData.moduleData[module].pxx.external_antenna;
|
||||
modelData.moduleData[module].ppm.outputType = modelData.moduleData[module].pxx.sport_out;
|
||||
|
||||
}
|
||||
else if (modelData.moduleData[module].protocol >= PULSES_LP45 && modelData.moduleData[module].protocol <= PULSES_DSMX) {
|
||||
subprotocols[module] = modelData.moduleData[module].protocol - PULSES_LP45;
|
||||
@@ -3496,6 +3515,17 @@ void OpenTxModelData::afterImport()
|
||||
modelData.moduleData[module].multi.lowPowerMode = modelData.moduleData[module].ppm.outputType;
|
||||
modelData.moduleData[module].multi.autoBindMode = modelData.moduleData[module].ppm.pulsePol;
|
||||
}
|
||||
|
||||
if ((modelData.moduleData[module].protocol >= PULSES_PXX_XJT_X16 && modelData.moduleData[module].protocol <= PULSES_PXX_XJT_LR12) ||
|
||||
modelData.moduleData[module].protocol == PULSES_PXX_R9M) {
|
||||
// Do the same for pxx
|
||||
unsigned int pxxByte = (unsigned int)((modelData.moduleData[module].ppm.delay - 300) / 50);
|
||||
modelData.moduleData[module].pxx.power = pxxByte & 0x03;
|
||||
modelData.moduleData[module].pxx.receiver_telem_off = static_cast<bool>(pxxByte & (1 << 4));
|
||||
modelData.moduleData[module].pxx.receiver_channel_9_16 = static_cast<bool>(pxxByte & (1 << 5));
|
||||
modelData.moduleData[module].pxx.sport_out = modelData.moduleData[module].ppm.outputType;
|
||||
modelData.moduleData[module].pxx.external_antenna = modelData.moduleData[module].ppm.pulsePol;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_TARANIS(board) && version < 217 && modelData.moduleData[1].protocol != PULSES_OFF) {
|
||||
@@ -3653,22 +3683,25 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.backlightBright));
|
||||
if (version < 218) internalField.Append(new SignedField<8>(this, generalData.txCurrentCalibration));
|
||||
if (version >= 213) {
|
||||
if (version < 218) internalField.Append(new SignedField<8>(this, generalData.temperatureWarn)); // TODO
|
||||
if (version < 218) internalField.Append(new SignedField<8>(this, generalData.temperatureWarn));
|
||||
if (version < 218) internalField.Append(new UnsignedField<8>(this, generalData.mAhWarn));
|
||||
if (version < 218) internalField.Append(new UnsignedField<16>(this, generalData.mAhUsed));
|
||||
internalField.Append(new UnsignedField<32>(this, generalData.globalTimer));
|
||||
if (version < 218) internalField.Append(new SignedField<8>(this, generalData.temperatureCalib)); // TODO
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.btBaudrate)); // TODO
|
||||
if (version < 218) internalField.Append(new BoolField<8>(this, generalData.optrexDisplay)); //TODO
|
||||
if (version < 218) internalField.Append(new UnsignedField<8>(this, generalData.sticksGain)); // TODO
|
||||
if (version < 218) internalField.Append(new SignedField<8>(this, generalData.temperatureCalib));
|
||||
internalField.Append(new UnsignedField<4>(this, generalData.bluetoothBaudrate));
|
||||
internalField.Append(new UnsignedField<4>(this, generalData.bluetoothMode));
|
||||
if (version < 218) internalField.Append(new BoolField<8>(this, generalData.optrexDisplay));
|
||||
if (version < 218) internalField.Append(new UnsignedField<8>(this, generalData.sticksGain));
|
||||
}
|
||||
if (version >= 214) {
|
||||
if (version < 218) internalField.Append(new UnsignedField<8>(this, generalData.rotarySteps)); // TODO
|
||||
if (version < 218) internalField.Append(new UnsignedField<8>(this, generalData.rotarySteps));
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.countryCode));
|
||||
internalField.Append(new UnsignedField<1>(this, generalData.imperial));
|
||||
if (version >= 218) {
|
||||
internalField.Append(new BoolField<1>(this, generalData.jitterFilter));
|
||||
internalField.Append(new SpareBitsField<6>(this));
|
||||
internalField.Append(new BoolField<1>(this, generalData.disableRssiPoweroffAlarm));
|
||||
internalField.Append(new UnsignedField<2>(this, generalData.usbMode));
|
||||
internalField.Append(new SpareBitsField<3>(this));
|
||||
}
|
||||
else {
|
||||
internalField.Append(new SpareBitsField<7>(this));
|
||||
@@ -3738,6 +3771,16 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.backlightColor));
|
||||
}
|
||||
}
|
||||
else if (IS_SKY9X(board) && version >= 218) {
|
||||
internalField.Append(new SignedField<8>(this, generalData.txCurrentCalibration));
|
||||
internalField.Append(new SignedField<8>(this, generalData.temperatureWarn));
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.mAhWarn));
|
||||
internalField.Append(new UnsignedField<16>(this, generalData.mAhUsed));
|
||||
internalField.Append(new SignedField<8>(this, generalData.temperatureCalib));
|
||||
internalField.Append(new BoolField<8>(this, generalData.optrexDisplay));
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.sticksGain));
|
||||
internalField.Append(new UnsignedField<8>(this, generalData.rotarySteps));
|
||||
}
|
||||
|
||||
if (IS_TARANIS_X9E(board))
|
||||
internalField.Append(new SpareBitsField<64>(this)); // switchUnlockStates
|
||||
@@ -3787,7 +3830,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type
|
||||
}
|
||||
|
||||
if (IS_HORUS(board)) {
|
||||
internalField.Append(new BoolField<1>(this, generalData.bluetoothEnable));
|
||||
internalField.Append(new SpareBitsField<1>(this));
|
||||
internalField.Append(new UnsignedField<7>(this, generalData.backlightOffBright));
|
||||
internalField.Append(new ZCharField<10>(this, generalData.bluetoothName, "Bluetooth name"));
|
||||
}
|
||||
|
||||
@@ -98,13 +98,11 @@ class ProtocolsConversionTable: public ConversionTable
|
||||
addConversion(PULSES_DSM2, val++);
|
||||
addConversion(PULSES_DSMX, val++);
|
||||
}
|
||||
if (IS_HORUS_OR_TARANIS(board)) {
|
||||
if (IS_ARM(board)) {
|
||||
addConversion(PULSES_CROSSFIRE, val++);
|
||||
addConversion(PULSES_MULTIMODULE, val++);
|
||||
}
|
||||
else if (IS_ARM(board)) {
|
||||
val++;
|
||||
addConversion(PULSES_MULTIMODULE, val++);
|
||||
addConversion(PULSES_PXX_R9M, val++);
|
||||
addConversion(PULSES_SBUS, val++);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -26,11 +26,15 @@
|
||||
#include <QMessageBox>
|
||||
#include <QTime>
|
||||
#include <QUrl>
|
||||
#include <companion/src/storage/storage.h>
|
||||
|
||||
using namespace Board;
|
||||
|
||||
#define OPENTX_FIRMWARE_DOWNLOADS "http://downloads-22.open-tx.org/firmware"
|
||||
#define OPENTX_NIGHT_FIRMWARE_DOWNLOADS "http://downloads-22.open-tx.org/nightly/firmware"
|
||||
const char * const OPENTX_FIRMWARE_DOWNLOAD_URL[] = {
|
||||
"https://downloads.open-tx.org/2.2/release/firmware",
|
||||
"https://downloads.open-tx.org/2.2/rc/firmware",
|
||||
"https://downloads.open-tx.org/2.2/nightlies/firmware"
|
||||
};
|
||||
|
||||
#define FILE_TYP_GENERAL 1
|
||||
#define FILE_TYP_MODEL 2
|
||||
@@ -95,30 +99,6 @@ const char * OpenTxEepromInterface::getName()
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t OpenTxEepromInterface::getFourCC()
|
||||
{
|
||||
switch (board) {
|
||||
case BOARD_X12S:
|
||||
case BOARD_X10:
|
||||
return 0x3478746F;
|
||||
case BOARD_TARANIS_X7:
|
||||
return 0x3678746F;
|
||||
case BOARD_TARANIS_X9E:
|
||||
return 0x3578746F;
|
||||
case BOARD_TARANIS_X9D:
|
||||
case BOARD_TARANIS_X9DP:
|
||||
return 0x3378746F;
|
||||
case BOARD_SKY9X:
|
||||
case BOARD_AR9X:
|
||||
return 0x3278746F;
|
||||
case BOARD_MEGA2560:
|
||||
case BOARD_GRUVIN9X:
|
||||
return 0x3178746F;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenTxEepromInterface::loadRadioSettingsFromRLE(GeneralSettings & settings, RleFile * rleFile, uint8_t version)
|
||||
{
|
||||
QByteArray data(sizeof(settings), 0); // GeneralSettings should be always bigger than the EEPROM struct
|
||||
@@ -130,7 +110,7 @@ bool OpenTxEepromInterface::loadRadioSettingsFromRLE(GeneralSettings & settings,
|
||||
return checkVariant(settings.version, settings.variant);
|
||||
}
|
||||
else {
|
||||
std::cout << " error when loading general settings";
|
||||
qWarning() << " error when loading general settings";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -163,7 +143,7 @@ bool OpenTxEepromInterface::saveToByteArray(const T & src, QByteArray & data, ui
|
||||
// manager.Dump();
|
||||
manager.Export(raw);
|
||||
data.resize(8);
|
||||
*((uint32_t*)&data.data()[0]) = getFourCC();
|
||||
*((uint32_t*)&data.data()[0]) = StorageFormat::getFourCC(board);
|
||||
data[4] = version;
|
||||
data[5] = 'M';
|
||||
*((uint16_t*)&data.data()[6]) = raw.size();
|
||||
@@ -186,12 +166,12 @@ template <class T, class M>
|
||||
bool OpenTxEepromInterface::loadFromByteArray(T & dest, const QByteArray & data)
|
||||
{
|
||||
uint32_t fourcc = *((uint32_t*)&data.data()[0]);
|
||||
if (getFourCC() != fourcc) {
|
||||
if (StorageFormat::getFourCC(board) != fourcc) {
|
||||
if (IS_HORUS(board) && fourcc == 0x3178396F) {
|
||||
qDebug() << QString().sprintf("%s: Deprecated fourcc used %x vs %x", getName(), fourcc, getFourCC());
|
||||
qDebug() << QString().sprintf("%s: Deprecated fourcc used %x vs %x", getName(), fourcc, StorageFormat::getFourCC(board));
|
||||
}
|
||||
else {
|
||||
qDebug() << QString().sprintf("%s: Wrong fourcc %x vs %x", getName(), fourcc, getFourCC());
|
||||
qDebug() << QString().sprintf("%s: Wrong fourcc %x vs %x", getName(), fourcc, StorageFormat::getFourCC(board));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -203,7 +183,9 @@ bool OpenTxEepromInterface::loadFromByteArray(T & dest, const QByteArray & data)
|
||||
|
||||
unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t * eeprom, int size)
|
||||
{
|
||||
std::cout << "trying " << getName() << " import...";
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying " << getName() << " import...";
|
||||
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
@@ -216,7 +198,7 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
|
||||
}
|
||||
}
|
||||
if (notnull) {
|
||||
std::cout << " wrong size (" << size << ")\n";
|
||||
dbg << " wrong size (" << size << ")";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
@@ -227,14 +209,14 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << " wrong size (" << size << "/" << Boards::getEEpromSize(board) << ")\n";
|
||||
dbg << " wrong size (" << size << "/" << Boards::getEEpromSize(board) << ")";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
|
||||
if (!efile->EeFsOpen((uint8_t *) eeprom, size, board)) {
|
||||
std::cout << " wrong file system\n";
|
||||
dbg << " wrong file system";
|
||||
errors.set(WRONG_FILE_SYSTEM);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
@@ -243,12 +225,12 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
|
||||
|
||||
uint8_t version;
|
||||
if (efile->readRlc2(&version, 1) != 1) {
|
||||
std::cout << " no\n";
|
||||
dbg << " no";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << " version " << (unsigned int) version;
|
||||
dbg << " version " << (unsigned int) version;
|
||||
|
||||
EepromLoadErrors version_error = checkVersion(version);
|
||||
if (version_error == OLD_VERSION) {
|
||||
@@ -257,24 +239,24 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
|
||||
ShowEepromWarnings(NULL, QObject::tr("Warning"), errors.to_ulong());
|
||||
}
|
||||
else if (version_error == NOT_OPENTX) {
|
||||
std::cout << " not open9x\n";
|
||||
dbg << " not open9x";
|
||||
errors.set(version_error);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (!loadRadioSettingsFromRLE(radioData.generalSettings, efile, version)) {
|
||||
std::cout << " ko\n";
|
||||
dbg << " ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << " variant " << radioData.generalSettings.variant;
|
||||
dbg << " variant " << radioData.generalSettings.variant;
|
||||
if (getCurrentFirmware()->getCapability(Models) == 0) {
|
||||
radioData.models.resize(firmware->getCapability(Models));
|
||||
}
|
||||
for (int i = 0; i < firmware->getCapability(Models); i++) {
|
||||
if (!loadModelFromRLE(radioData.models[i], efile, i, version, radioData.generalSettings.variant)) {
|
||||
std::cout << " ko\n";
|
||||
if (i < (int)radioData.models.size() && !loadModelFromRLE(radioData.models[i], efile, i, version, radioData.generalSettings.variant)) {
|
||||
dbg << " ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
if (getCurrentFirmware()->getCapability(Models) == 0) {
|
||||
radioData.models.resize(i);
|
||||
@@ -282,7 +264,7 @@ unsigned long OpenTxEepromInterface::load(RadioData &radioData, const uint8_t *
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
std::cout << " ok\n";
|
||||
dbg << " ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
@@ -355,7 +337,7 @@ int OpenTxEepromInterface::save(uint8_t * eeprom, const RadioData & radioData, u
|
||||
}
|
||||
|
||||
for (int i = 0; i < getCurrentFirmware()->getCapability(Models); i++) {
|
||||
if (!radioData.models[i].isEmpty()) {
|
||||
if (i < (int)radioData.models.size() && !radioData.models[i].isEmpty()) {
|
||||
OpenTxModelData generator((ModelData &)radioData.models[i], board, version, variant);
|
||||
// generator.Dump();
|
||||
QByteArray data;
|
||||
@@ -512,11 +494,6 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
return 0;
|
||||
case PermTimers:
|
||||
return (IS_2560(board) || IS_ARM(board));
|
||||
case SwitchesPositions:
|
||||
if (IS_HORUS_OR_TARANIS(board))
|
||||
return getBoardCapability(board, Board::Switches) * 3;
|
||||
else
|
||||
return 9;
|
||||
case CustomFunctions:
|
||||
if (IS_ARM(board))
|
||||
return 64;
|
||||
@@ -566,6 +543,16 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
return 0;
|
||||
case MaxVolume:
|
||||
return (IS_ARM(board) ? 23 : 7);
|
||||
case MaxContrast:
|
||||
if (IS_TARANIS_X7(board))
|
||||
return 30;
|
||||
else
|
||||
return 45;
|
||||
case MinContrast:
|
||||
if (IS_TARANIS_X9(board))
|
||||
return 0;
|
||||
else
|
||||
return 10;
|
||||
case HasSoundMixer:
|
||||
return (IS_ARM(board) ? 1 : 0);
|
||||
case ExtraInputs:
|
||||
@@ -587,7 +574,7 @@ int OpenTxFirmware::getCapability(::Capability capability)
|
||||
case ChannelsName:
|
||||
return (IS_ARM(board) ? (HAS_LARGE_LCD(board) ? 6 : 4) : 0);
|
||||
case HasCvNames:
|
||||
return (IS_HORUS_OR_TARANIS(board) ? 1 : 0);
|
||||
return (IS_ARM(board) ? 1 : 0);
|
||||
case Telemetry:
|
||||
if (IS_2560(board) || IS_ARM(board) || id.contains("frsky") || id.contains("telemetrez"))
|
||||
return TM_HASTELEMETRY | TM_HASOFFSET | TM_HASWSHH;
|
||||
@@ -772,7 +759,7 @@ QString OpenTxFirmware::getAnalogInputName(unsigned int index)
|
||||
};
|
||||
return CHECK_IN_ARRAY(pots, index);
|
||||
}
|
||||
else if (IS_HORUS(board)) {
|
||||
else if (IS_HORUS_X12S(board)) {
|
||||
const QString pots[] = {
|
||||
QObject::tr("S1"),
|
||||
QObject::tr("6P"),
|
||||
@@ -786,6 +773,16 @@ QString OpenTxFirmware::getAnalogInputName(unsigned int index)
|
||||
};
|
||||
return CHECK_IN_ARRAY(pots, index);
|
||||
}
|
||||
else if (IS_HORUS_X10(board)) {
|
||||
const QString pots[] = {
|
||||
QObject::tr("S1"),
|
||||
QObject::tr("6P"),
|
||||
QObject::tr("S2"),
|
||||
QObject::tr("LS"),
|
||||
QObject::tr("RS")
|
||||
};
|
||||
return CHECK_IN_ARRAY(pots, index);
|
||||
}
|
||||
else {
|
||||
return "???";
|
||||
}
|
||||
@@ -826,11 +823,13 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
|
||||
case PULSES_PXX_XJT_X16:
|
||||
case PULSES_PXX_XJT_D8:
|
||||
case PULSES_PXX_XJT_LR12:
|
||||
case PULSES_PXX_R9M:
|
||||
//case PULSES_PXX_DJT: // Unavailable for now
|
||||
case PULSES_LP45:
|
||||
case PULSES_DSM2:
|
||||
case PULSES_DSMX:
|
||||
case PULSES_CROSSFIRE:
|
||||
case PULSES_SBUS:
|
||||
return 1;
|
||||
case PULSES_MULTIMODULE:
|
||||
return id.contains("multimodule") ? 1 : 0;
|
||||
@@ -858,9 +857,11 @@ int OpenTxFirmware::isAvailable(PulsesProtocol proto, int port)
|
||||
case PULSES_PXX_XJT_X16:
|
||||
case PULSES_PXX_XJT_D8:
|
||||
case PULSES_PXX_XJT_LR12:
|
||||
case PULSES_PXX_R9M:
|
||||
case PULSES_LP45:
|
||||
case PULSES_DSM2:
|
||||
case PULSES_DSMX:
|
||||
case PULSES_SBUS:
|
||||
return 1;
|
||||
case PULSES_MULTIMODULE:
|
||||
return id.contains("multimodule") ? 1 : 0;
|
||||
@@ -967,29 +968,29 @@ bool OpenTxEepromInterface::checkVariant(unsigned int version, unsigned int vari
|
||||
efile->openRd(i);
|
||||
int sz = efile->readRlc2(tmp, sizeof(tmp));
|
||||
if (sz == 849) {
|
||||
std::cout << " warning: M128 variant not set (but model size seems ok)";
|
||||
qWarning() << " warning: M128 variant not set (but model size seems ok)";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << " wrong variant (" << variant << ")";
|
||||
qWarning() << " wrong variant (" << variant << ")";
|
||||
return false;
|
||||
}
|
||||
else if (IS_TARANIS_X9E(board)) {
|
||||
if (variant != TARANIS_X9E_VARIANT) {
|
||||
std::cout << " wrong variant (" << variant << ")";
|
||||
qWarning() << " wrong variant (" << variant << ")";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (IS_TARANIS_X7(board)) {
|
||||
if (variant != TARANIS_X7_VARIANT) {
|
||||
std::cout << " wrong variant (" << variant << ")";
|
||||
qWarning() << " wrong variant (" << variant << ")";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (IS_TARANIS(board)) {
|
||||
if (variant != 0) {
|
||||
std::cout << " wrong variant (" << variant << ")";
|
||||
qWarning() << " wrong variant (" << variant << ")";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1022,10 +1023,12 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
|
||||
{
|
||||
std::bitset<NUM_ERRORS> errors;
|
||||
|
||||
std::cout << "trying " << getName() << " backup import...";
|
||||
QDebug dbg = qDebug();
|
||||
dbg.setAutoInsertSpaces(false);
|
||||
dbg << "trying " << getName() << " backup import...";
|
||||
|
||||
if (esize < 8 || memcmp(eeprom, "o9x", 3) != 0) {
|
||||
std::cout << " no\n";
|
||||
dbg << " no\n";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
@@ -1042,13 +1045,13 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
|
||||
backupBoard = BOARD_GRUVIN9X;
|
||||
break;
|
||||
default:
|
||||
std::cout << " unknown board\n";
|
||||
dbg << " unknown board";
|
||||
errors.set(UNKNOWN_BOARD);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (backupBoard != board) {
|
||||
std::cout << " not right board\n";
|
||||
dbg << " not right board";
|
||||
errors.set(WRONG_BOARD);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
@@ -1058,7 +1061,7 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
|
||||
uint16_t size = ((uint16_t) eeprom[7] << 8) + eeprom[6];
|
||||
uint16_t variant = ((uint16_t) eeprom[9] << 8) + eeprom[8];
|
||||
|
||||
std::cout << " version " << (unsigned int) version << " ";
|
||||
dbg << " version " << (unsigned int) version << " ";
|
||||
|
||||
EepromLoadErrors version_error = checkVersion(version);
|
||||
if (version_error == OLD_VERSION) {
|
||||
@@ -1066,42 +1069,38 @@ unsigned long OpenTxEepromInterface::loadBackup(RadioData &radioData, const uint
|
||||
errors.set(HAS_WARNINGS);
|
||||
}
|
||||
else if (version_error == NOT_OPENTX) {
|
||||
std::cout << " not open9x\n";
|
||||
dbg << " not open9x";
|
||||
errors.set(version_error);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (size > esize - 8) {
|
||||
std::cout << " wrong size\n";
|
||||
dbg << " wrong size";
|
||||
errors.set(WRONG_SIZE);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
if (bcktype == 'M') {
|
||||
if (!loadModelFromBackup(radioData.models[index], &eeprom[8], size, version, variant)) {
|
||||
std::cout << " ko\n";
|
||||
dbg << " ko";
|
||||
errors.set(UNKNOWN_ERROR);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << " backup type not supported\n";
|
||||
dbg << " backup type not supported";
|
||||
errors.set(BACKUP_NOT_SUPPORTED);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
std::cout << " ok\n";
|
||||
dbg << " ok";
|
||||
errors.set(ALL_OK);
|
||||
return errors.to_ulong();
|
||||
}
|
||||
|
||||
QString OpenTxFirmware::getFirmwareBaseUrl()
|
||||
{
|
||||
#if defined(ALLOW_NIGHTLY_BUILDS)
|
||||
return (g.useFirmwareNightlyBuilds() ? OPENTX_NIGHT_FIRMWARE_DOWNLOADS : OPENTX_FIRMWARE_DOWNLOADS);
|
||||
#else
|
||||
return OPENTX_FIRMWARE_DOWNLOADS;
|
||||
#endif
|
||||
return OPENTX_FIRMWARE_DOWNLOAD_URL[g.boundedOpenTxBranch()];
|
||||
}
|
||||
|
||||
QString OpenTxFirmware::getFirmwareUrl()
|
||||
@@ -1152,13 +1151,8 @@ void addOpenTxFrskyOptions(OpenTxFirmware * firmware)
|
||||
addOpenTxArmOptions(firmware);
|
||||
firmware->addOption("noheli", QObject::tr("Disable HELI menu and cyclic mix support"));
|
||||
firmware->addOption("nogvars", QObject::tr("Disable Global variables"));
|
||||
firmware->addOption("lua", QObject::tr("Support for Lua model scripts"));
|
||||
firmware->addOption("lua", QObject::tr("Enable Lua custom scripts screen"));
|
||||
firmware->addOption("luac", QObject::tr("Enable Lua compiler"));
|
||||
firmware->addOption("bindopt", QObject::tr("Enable bindings options"));
|
||||
Option usb_options[] = {{"massstorage", QObject::tr("Instead of Joystick emulation, USB connection is Mass Storage (as in the Bootloader)")},
|
||||
{"cli", QObject::tr("Instead of Joystick emulation, USB connection is Command Line Interface")},
|
||||
{NULL}};
|
||||
firmware->addOptions(usb_options);
|
||||
}
|
||||
|
||||
void addOpenTxTaranisOptions(OpenTxFirmware * firmware)
|
||||
@@ -1245,26 +1239,24 @@ void registerOpenTxFirmwares()
|
||||
registerOpenTxFirmware(firmware);
|
||||
|
||||
/* FrSky X7 board */
|
||||
firmware = new OpenTxFirmware("opentx-x7", QObject::tr("FrSky Taranis X7"), BOARD_TARANIS_X7);
|
||||
firmware = new OpenTxFirmware("opentx-x7", QObject::tr("FrSky Taranis X7 / X7S"), BOARD_TARANIS_X7);
|
||||
// No mixersmon for now
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
firmware->addOption("internalppm", QObject::tr("Support for PPM internal module hack"));
|
||||
firmware->addOption("sqt5font", QObject::tr("Use alternative SQT5 font"));
|
||||
registerOpenTxFirmware(firmware);
|
||||
|
||||
/* FrSky X10 board */
|
||||
firmware = new OpenTxFirmware("opentx-x10", QObject::tr("FrSky Horus X10 / X10S"), BOARD_X10);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
|
||||
/* FrSky Horus board */
|
||||
firmware = new OpenTxFirmware("opentx-x12s", QObject::tr("FrSky Horus"), BOARD_X12S);
|
||||
firmware = new OpenTxFirmware("opentx-x12s", QObject::tr("FrSky Horus X12S"), BOARD_X12S);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
firmware->addOption("pcbdev", QObject::tr("Use ONLY with first DEV pcb version"));
|
||||
registerOpenTxFirmware(firmware);
|
||||
|
||||
|
||||
/* FrSky X10 board */
|
||||
/* Disabled for now
|
||||
firmware = new OpenTxFirmware("opentx-x10", QObject::tr("FrSky X10"), BOARD_X10);
|
||||
addOpenTxFrskyOptions(firmware);
|
||||
registerOpenTxFirmware(firmware);
|
||||
*/
|
||||
/* 9XR-Pro */
|
||||
firmware = new OpenTxFirmware("opentx-9xrpro", QObject::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO);
|
||||
firmware->addOption("heli", QObject::tr("Enable HELI menu and cyclic mix support"));
|
||||
|
||||
@@ -72,8 +72,6 @@ class OpenTxEepromInterface : public EEPROMInterface
|
||||
|
||||
uint8_t getLastDataVersion(Board::Type board);
|
||||
|
||||
uint32_t getFourCC();
|
||||
|
||||
RleFile * efile;
|
||||
|
||||
OpenTxFirmware * firmware;
|
||||
|
||||
@@ -102,7 +102,7 @@ void FlashEEpromDialog::updateUI()
|
||||
|
||||
void FlashEEpromDialog::on_eepromLoad_clicked()
|
||||
{
|
||||
QString filename = QFileDialog::getOpenFileName(this, tr("Choose Radio Backup file"), g.eepromDir(), tr(EXTERNAL_EEPROM_FILES_FILTER));
|
||||
QString filename = QFileDialog::getOpenFileName(this, tr("Choose Radio Backup file"), g.eepromDir(), EXTERNAL_EEPROM_FILES_FILTER);
|
||||
if (!filename.isEmpty()) {
|
||||
eepromFilename = filename;
|
||||
updateUI();
|
||||
|
||||
@@ -21,25 +21,22 @@
|
||||
#include "fwpreferencesdialog.h"
|
||||
#include "ui_fwpreferencesdialog.h"
|
||||
#include "mainwindow.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "helpers.h"
|
||||
#include "appdata.h"
|
||||
#include <QDesktopServices>
|
||||
#include <QtGui>
|
||||
|
||||
FirmwarePreferencesDialog::FirmwarePreferencesDialog(QWidget *parent) :
|
||||
const char * const OPENTX_SDCARD_DOWNLOAD_URL[] = {
|
||||
"https://downloads.open-tx.org/2.2/release/sdcard/",
|
||||
"https://downloads.open-tx.org/2.2/rc/sdcard/",
|
||||
"https://downloads.open-tx.org/2.2/nightlies/sdcard/"
|
||||
};
|
||||
|
||||
FirmwarePreferencesDialog::FirmwarePreferencesDialog(QWidget * parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::FirmwarePreferencesDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("fwpreferences.png"));
|
||||
initSettings();
|
||||
|
||||
foreach(const char *lang, getCurrentFirmware()->getFirmwareBase()->ttslanguages) {
|
||||
ui->voiceCombo->addItem(lang);
|
||||
if (Firmware::getCurrentVariant()->getId().contains(QString("-tts%1").arg(lang)))
|
||||
ui->voiceCombo->setCurrentIndex(ui->voiceCombo->count() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
FirmwarePreferencesDialog::~FirmwarePreferencesDialog()
|
||||
@@ -58,26 +55,26 @@ void FirmwarePreferencesDialog::initSettings()
|
||||
|
||||
void FirmwarePreferencesDialog::on_checkFWUpdates_clicked()
|
||||
{
|
||||
MainWindow * mw = (MainWindow *)this->parent();
|
||||
MainWindow * mw = qobject_cast<MainWindow *>(this->parent());
|
||||
mw->checkForFirmwareUpdate();
|
||||
initSettings();
|
||||
}
|
||||
|
||||
void FirmwarePreferencesDialog::on_fw_dnld_clicked()
|
||||
{
|
||||
MainWindow * mw = (MainWindow *)this->parent();
|
||||
MainWindow * mw = qobject_cast<MainWindow *>(this->parent());
|
||||
mw->dowloadLastFirmwareUpdate();
|
||||
initSettings();
|
||||
}
|
||||
|
||||
void FirmwarePreferencesDialog::on_voice_dnld_clicked()
|
||||
void FirmwarePreferencesDialog::on_sd_dnld_clicked()
|
||||
{
|
||||
QString url = "http://voices-21.open-tx.org/";
|
||||
QString url = OPENTX_SDCARD_DOWNLOAD_URL[g.boundedOpenTxBranch()];
|
||||
QString fwType = g.profile[g.id()].fwType();
|
||||
QStringList list = fwType.split("-");
|
||||
QString firmware = QString("%1-%2").arg(list[0]).arg(list[1]);
|
||||
url.append(QString("%1/%2/").arg(firmware).arg(ui->voiceCombo->currentText().toLower()));
|
||||
if (g.boundedOpenTxBranch() != BRANCH_NIGHTLY_UNSTABLE) {
|
||||
url.append(QString("%1/").arg(firmware));
|
||||
}
|
||||
QDesktopServices::openUrl(url);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ class FirmwarePreferencesDialog : public QDialog
|
||||
|
||||
private slots:
|
||||
void on_fw_dnld_clicked();
|
||||
void on_voice_dnld_clicked();
|
||||
void on_sd_dnld_clicked();
|
||||
void on_checkFWUpdates_clicked();
|
||||
};
|
||||
|
||||
|
||||
@@ -26,13 +26,22 @@
|
||||
<string>Downloads</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="24" column="5">
|
||||
<item row="23" column="3">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@@ -42,7 +51,7 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="5">
|
||||
<item row="3" column="3">
|
||||
<widget class="QPushButton" name="checkFWUpdates">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@@ -55,75 +64,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="voiceLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Sans Serif</family>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Voice</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QComboBox" name="voiceCombo">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Set voice language.
|
||||
May be different from firmware language</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="5">
|
||||
<widget class="QPushButton" name="voice_dnld">
|
||||
<property name="text">
|
||||
<string>Download Voice</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="5">
|
||||
<widget class="QPushButton" name="fw_dnld">
|
||||
<property name="text">
|
||||
<string>Download FW</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="3">
|
||||
<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>
|
||||
<item row="6" column="0" colspan="6">
|
||||
<widget class="Line" name="voiceLine">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="23" column="0" colspan="6">
|
||||
<widget class="Line" name="line_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="sizePolicy">
|
||||
@@ -147,20 +87,28 @@ May be different from firmware language</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="4">
|
||||
<widget class="QLabel" name="fwTypeLbl">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item row="5" column="3">
|
||||
<widget class="QPushButton" name="fw_dnld">
|
||||
<property name="text">
|
||||
<string notr="true">FwType</string>
|
||||
<string>Download firmware</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2" colspan="2">
|
||||
<item row="22" column="0" colspan="4">
|
||||
<widget class="Line" name="line_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3">
|
||||
<widget class="QPushButton" name="sd_dnld">
|
||||
<property name="text">
|
||||
<string>Download SD contents</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QLabel" name="lastRevisionLbl">
|
||||
<property name="text">
|
||||
<string notr="true">-</string>
|
||||
@@ -174,13 +122,38 @@ May be different from firmware language</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="3">
|
||||
<widget class="QLabel" name="fwTypeLbl">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">FwType</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<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>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>checkFWUpdates</tabstop>
|
||||
<tabstop>fw_dnld</tabstop>
|
||||
<tabstop>voiceCombo</tabstop>
|
||||
<tabstop>voice_dnld</tabstop>
|
||||
<tabstop>sd_dnld</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
|
||||
@@ -27,11 +27,10 @@ ui(new Ui::GeneralSetup)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QLabel * pmsl[] = {ui->ro_label,ui->ro1_label,ui->ro2_label,ui->ro3_label,ui->ro4_label,ui->ro5_label,ui->ro6_label,ui->ro7_label,ui->ro8_label, NULL};
|
||||
QSlider * tpmsld[] = {ui->chkSA, ui->chkSB, ui->chkSC, ui->chkSD, ui->chkSE, ui->chkSF, ui->chkSG, ui->chkSH, NULL};
|
||||
QLabel *pmsl[] = {ui->ro_label, ui->ro1_label, ui->ro2_label, ui->ro3_label, ui->ro4_label, ui->ro5_label, ui->ro6_label, ui->ro7_label, ui->ro8_label, NULL};
|
||||
QSlider *tpmsld[] = {ui->chkSA, ui->chkSB, ui->chkSC, ui->chkSD, ui->chkSE, ui->chkSF, ui->chkSG, ui->chkSH, NULL};
|
||||
|
||||
if (IS_TARANIS(firmware->getBoard())) {
|
||||
ui->contrastSB->setMinimum(0);
|
||||
if (firmware->getId().contains("readonly")) {
|
||||
uint16_t switchstate = generalSettings.switchUnlockStates;
|
||||
ui->chkSA->setValue(switchstate & 0x3);
|
||||
@@ -44,27 +43,27 @@ ui(new Ui::GeneralSetup)
|
||||
switchstate >>= 2;
|
||||
ui->chkSE->setValue(switchstate & 0x3);
|
||||
switchstate >>= 2;
|
||||
ui->chkSF->setValue((switchstate & 0x3)/2);
|
||||
ui->chkSF->setValue((switchstate & 0x3) / 2);
|
||||
switchstate >>= 2;
|
||||
ui->chkSG->setValue(switchstate & 0x3);
|
||||
switchstate >>= 2;
|
||||
ui->chkSH->setValue(switchstate & 0x3);
|
||||
}
|
||||
else {
|
||||
for (int i=0; pmsl[i]; i++) {
|
||||
for (int i = 0; pmsl[i]; i++) {
|
||||
pmsl[i]->hide();
|
||||
}
|
||||
for (int i=0; tpmsld[i]; i++) {
|
||||
for (int i = 0; tpmsld[i]; i++) {
|
||||
tpmsld[i]->hide();
|
||||
}
|
||||
this->layout()->removeItem(ui->TaranisReadOnlyUnlock);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i=0; pmsl[i]; i++) {
|
||||
for (int i = 0; pmsl[i]; i++) {
|
||||
pmsl[i]->hide();
|
||||
}
|
||||
for (int i=0; tpmsld[i]; i++) {
|
||||
for (int i = 0; tpmsld[i]; i++) {
|
||||
tpmsld[i]->hide();
|
||||
}
|
||||
this->layout()->removeItem(ui->TaranisReadOnlyUnlock);
|
||||
@@ -112,10 +111,10 @@ ui(new Ui::GeneralSetup)
|
||||
ui->varioVolume_SL->setValue(generalSettings.varioVolume);
|
||||
ui->bgVolume_SL->setValue(generalSettings.backgroundVolume);
|
||||
ui->wavVolume_SL->setValue(generalSettings.wavVolume);
|
||||
ui->varioP0_SB->setValue(700+(generalSettings.varioPitch*10));
|
||||
ui->varioP0_SB->setValue(700 + (generalSettings.varioPitch * 10));
|
||||
updateVarioPitchRange();
|
||||
ui->varioPMax_SB->setValue(700+(generalSettings.varioPitch*10)+1000+(generalSettings.varioRange*10));
|
||||
ui->varioR0_SB->setValue(500+(generalSettings.varioRepeat*10));
|
||||
ui->varioPMax_SB->setValue(700 + (generalSettings.varioPitch * 10) + 1000 + (generalSettings.varioRange * 10));
|
||||
ui->varioR0_SB->setValue(500 + (generalSettings.varioRepeat * 10));
|
||||
}
|
||||
|
||||
if (!firmware->getCapability(HasFAIMode)) {
|
||||
@@ -152,11 +151,22 @@ ui(new Ui::GeneralSetup)
|
||||
ui->adjustRTC->hide();
|
||||
}
|
||||
|
||||
if (IS_STM32(firmware->getBoard())){
|
||||
ui->usbModeCB->setCurrentIndex(generalSettings.usbMode);
|
||||
}
|
||||
else {
|
||||
ui->usbModeLabel->hide();
|
||||
ui->usbModeCB->hide();
|
||||
}
|
||||
|
||||
if (!firmware->getCapability(OptrexDisplay)) {
|
||||
ui->label_displayType->hide();
|
||||
ui->displayTypeCB->setDisabled(true);
|
||||
ui->displayTypeCB->hide();
|
||||
}
|
||||
else {
|
||||
ui->displayTypeCB->setCurrentIndex(generalSettings.optrexDisplay);
|
||||
}
|
||||
|
||||
if (!firmware->getCapability(HasVolume)) {
|
||||
ui->volume_SB->hide();
|
||||
@@ -197,7 +207,7 @@ ui(new Ui::GeneralSetup)
|
||||
}
|
||||
|
||||
int reCount = firmware->getCapability(RotaryEncoders);
|
||||
if (reCount==0) {
|
||||
if (reCount == 0) {
|
||||
ui->re_label->hide();
|
||||
ui->re_CB->hide();
|
||||
}
|
||||
@@ -205,13 +215,23 @@ ui(new Ui::GeneralSetup)
|
||||
populateRotEncCB(reCount);
|
||||
}
|
||||
|
||||
ui->contrastSB->setMinimum(firmware->getCapability(MinContrast));
|
||||
ui->contrastSB->setMaximum(firmware->getCapability(MaxContrast));
|
||||
ui->contrastSB->setValue(generalSettings.contrast);
|
||||
|
||||
ui->battwarningDSB->setValue((double)generalSettings.vBatWarn/10);
|
||||
ui->backlightautoSB->setValue(generalSettings.backlightDelay*5);
|
||||
ui->inactimerSB->setValue(generalSettings.inactivityTimer);
|
||||
|
||||
ui->memwarnChkB->setChecked(!generalSettings.disableMemoryWarning); //Default is zero=checked
|
||||
ui->alarmwarnChkB->setChecked(!generalSettings.disableAlarmWarning);//Default is zero=checked
|
||||
ui->memwarnChkB->setChecked(!generalSettings.disableMemoryWarning); // Default is zero=checked
|
||||
ui->alarmwarnChkB->setChecked(!generalSettings.disableAlarmWarning); // Default is zero=checked
|
||||
|
||||
if (IS_ARM(firmware->getBoard())) {
|
||||
ui->rssiPowerOffWarnChkB->setChecked(!generalSettings.disableRssiPoweroffAlarm); // Default is zero=checked
|
||||
}
|
||||
else {
|
||||
ui->rssiPowerOffWarnChkB->hide();
|
||||
}
|
||||
|
||||
if (IS_HORUS(firmware->getBoard())) {
|
||||
ui->splashScreenChkB->hide();
|
||||
@@ -325,6 +345,14 @@ void GeneralSetupPanel::on_backlightswCB_currentIndexChanged(int index)
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralSetupPanel::on_usbModeCB_currentIndexChanged(int index)
|
||||
{
|
||||
if (!lock) {
|
||||
generalSettings.usbMode = ui->usbModeCB->currentIndex();
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralSetupPanel::on_backlightColor_SL_valueChanged()
|
||||
{
|
||||
if (!lock) {
|
||||
@@ -607,18 +635,24 @@ void GeneralSetupPanel::on_inactimerSB_editingFinished()
|
||||
emit modified();
|
||||
}
|
||||
|
||||
void GeneralSetupPanel::on_memwarnChkB_stateChanged(int )
|
||||
void GeneralSetupPanel::on_memwarnChkB_stateChanged(int)
|
||||
{
|
||||
generalSettings.disableMemoryWarning = ui->memwarnChkB->isChecked() ? 0 : 1;
|
||||
emit modified();
|
||||
}
|
||||
|
||||
void GeneralSetupPanel::on_alarmwarnChkB_stateChanged(int )
|
||||
void GeneralSetupPanel::on_alarmwarnChkB_stateChanged(int)
|
||||
{
|
||||
generalSettings.disableAlarmWarning = ui->alarmwarnChkB->isChecked() ? 0 : 1;
|
||||
emit modified();
|
||||
}
|
||||
|
||||
void GeneralSetupPanel::on_rssiPowerOffWarnChkB_stateChanged(int)
|
||||
{
|
||||
generalSettings.disableRssiPoweroffAlarm = ui->rssiPowerOffWarnChkB->isChecked() ? 0 : 1;
|
||||
emit modified();
|
||||
}
|
||||
|
||||
void GeneralSetupPanel::on_beeperCB_currentIndexChanged(int index)
|
||||
{
|
||||
generalSettings.beeperMode = (GeneralSettings::BeeperMode)(index-2);
|
||||
|
||||
@@ -40,6 +40,7 @@ class GeneralSetupPanel : public GeneralPanel
|
||||
void on_splashScreenChkB_stateChanged(int);
|
||||
void on_splashScreenDuration_currentIndexChanged(int index);
|
||||
void on_alarmwarnChkB_stateChanged(int);
|
||||
void on_rssiPowerOffWarnChkB_stateChanged(int);
|
||||
void on_gpsFormatCB_currentIndexChanged(int index);
|
||||
void on_displayTypeCB_currentIndexChanged(int index);
|
||||
void on_BLBright_SB_editingFinished();
|
||||
@@ -58,6 +59,7 @@ class GeneralSetupPanel : public GeneralPanel
|
||||
void on_hapticmodeCB_currentIndexChanged(int index);
|
||||
void on_hapticLengthCB_currentIndexChanged(int index);
|
||||
void on_backlightswCB_currentIndexChanged(int index);
|
||||
void on_usbModeCB_currentIndexChanged(int index);
|
||||
void on_backlightColor_SL_valueChanged();
|
||||
void on_mavbaud_CB_currentIndexChanged(int index);
|
||||
void on_voiceLang_CB_currentIndexChanged(int index);
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "hardware.h"
|
||||
#include "ui_hardware.h"
|
||||
|
||||
void HardwarePanel::setupSwitchType(int index, QLabel * label, AutoLineEdit * name, AutoComboBox * type, bool threePos = true)
|
||||
void HardwarePanel::setupSwitchType(int index, QLabel * label, AutoLineEdit * name, AutoComboBox * type, bool threePos)
|
||||
{
|
||||
Board::Type board = getCurrentBoard();
|
||||
if (IS_STM32(board) && index < getBoardCapability(board, Board::Switches)) {
|
||||
@@ -92,7 +92,7 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
|
||||
ui(new Ui::Hardware)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
|
||||
Board::Type board = firmware->getBoard();
|
||||
|
||||
if (IS_STM32(board)) {
|
||||
@@ -110,6 +110,8 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
|
||||
ui->thrName->hide();
|
||||
ui->ailLabel->hide();
|
||||
ui->ailName->hide();
|
||||
ui->potsTypeSeparator_1->hide();
|
||||
ui->potsTypeSeparator_2->hide();
|
||||
}
|
||||
|
||||
setupPotType(0, ui->pot1Label, ui->pot1Name, ui->pot1Type);
|
||||
@@ -141,10 +143,11 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
|
||||
setupSwitchType(16, ui->sqLabel, ui->sqName, ui->sqType);
|
||||
setupSwitchType(17, ui->srLabel, ui->srName, ui->srType);
|
||||
|
||||
if (IS_HORUS_OR_TARANIS(board) && !IS_TARANIS_X7(board)) {
|
||||
if (IS_TARANIS(board) && !IS_TARANIS_X7(board)) {
|
||||
ui->serialPortMode->setCurrentIndex(generalSettings.hw_uartMode);
|
||||
}
|
||||
else {
|
||||
ui->serialPortMode->setCurrentIndex(0);
|
||||
ui->serialPortMode->hide();
|
||||
ui->serialPortLabel->hide();
|
||||
}
|
||||
@@ -160,10 +163,9 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings
|
||||
}
|
||||
else {
|
||||
ui->bluetoothLabel->hide();
|
||||
ui->bluetoothEnable->hide();
|
||||
ui->bluetoothName->hide();
|
||||
ui->bluetoothWidget->hide();
|
||||
}
|
||||
|
||||
|
||||
if (IS_HORUS_OR_TARANIS(board)) {
|
||||
ui->filterEnable->setChecked(!generalSettings.jitterFilter);
|
||||
}
|
||||
@@ -188,39 +190,52 @@ void HardwarePanel::on_filterEnable_stateChanged()
|
||||
|
||||
void HardwarePanel::on_PPM_MultiplierDSB_editingFinished()
|
||||
{
|
||||
generalSettings.PPM_Multiplier = (int)(ui->PPM_MultiplierDSB->value()*10)-10;
|
||||
emit modified();
|
||||
int val = (int)(ui->PPM_MultiplierDSB->value()*10)-10;
|
||||
if (generalSettings.PPM_Multiplier != val) {
|
||||
generalSettings.PPM_Multiplier = val;
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
void HardwarePanel::on_PPM1_editingFinished()
|
||||
{
|
||||
generalSettings.trainer.calib[0] = ui->PPM1->value();
|
||||
emit modified();
|
||||
if (generalSettings.trainer.calib[0] != ui->PPM1->value()) {
|
||||
generalSettings.trainer.calib[0] = ui->PPM1->value();
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
void HardwarePanel::on_PPM2_editingFinished()
|
||||
{
|
||||
generalSettings.trainer.calib[1] = ui->PPM2->value();
|
||||
emit modified();
|
||||
if (generalSettings.trainer.calib[1] != ui->PPM2->value()) {
|
||||
generalSettings.trainer.calib[1] = ui->PPM2->value();
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
void HardwarePanel::on_PPM3_editingFinished()
|
||||
{
|
||||
generalSettings.trainer.calib[2] = ui->PPM3->value();
|
||||
emit modified();
|
||||
if (generalSettings.trainer.calib[2] != ui->PPM3->value()) {
|
||||
generalSettings.trainer.calib[2] = ui->PPM3->value();
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
void HardwarePanel::on_PPM4_editingFinished()
|
||||
{
|
||||
generalSettings.trainer.calib[3] = ui->PPM4->value();
|
||||
emit modified();
|
||||
if (generalSettings.trainer.calib[3] != ui->PPM4->value()) {
|
||||
generalSettings.trainer.calib[3] = ui->PPM4->value();
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HardwarePanel::on_txCurrentHardware_editingFinished()
|
||||
void HardwarePanel::on_txCurrentCalibration_editingFinished()
|
||||
{
|
||||
generalSettings.txCurrentCalibration = ui->txCurrentCalibration->value();
|
||||
emit modified();
|
||||
if (generalSettings.txCurrentCalibration != ui->txCurrentCalibration->value()) {
|
||||
generalSettings.txCurrentCalibration = ui->txCurrentCalibration->value();
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
void HardwarePanel::on_bluetoothEnable_stateChanged(int)
|
||||
@@ -241,10 +256,12 @@ void HardwarePanel::setValues()
|
||||
ui->PPM_MultiplierDSB->setValue((qreal)(generalSettings.PPM_Multiplier+10)/10);
|
||||
}
|
||||
|
||||
void HardwarePanel::on_txVoltageHardware_editingFinished()
|
||||
void HardwarePanel::on_txVoltageCalibration_editingFinished()
|
||||
{
|
||||
generalSettings.txVoltageCalibration = ui->txVoltageCalibration->value()*10;
|
||||
emit modified();
|
||||
if (generalSettings.txVoltageCalibration != ui->txVoltageCalibration->value()*10) {
|
||||
generalSettings.txVoltageCalibration = ui->txVoltageCalibration->value()*10;
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
void HardwarePanel::on_serialPortMode_currentIndexChanged(int index)
|
||||
|
||||
@@ -40,14 +40,14 @@ class HardwarePanel : public GeneralPanel
|
||||
virtual ~HardwarePanel();
|
||||
|
||||
private slots:
|
||||
void on_txVoltageHardware_editingFinished();
|
||||
void on_PPM1_editingFinished();
|
||||
void on_PPM2_editingFinished();
|
||||
void on_PPM3_editingFinished();
|
||||
void on_PPM4_editingFinished();
|
||||
void on_PPM_MultiplierDSB_editingFinished();
|
||||
|
||||
void on_txCurrentHardware_editingFinished();
|
||||
void on_txCurrentCalibration_editingFinished();
|
||||
void on_txVoltageCalibration_editingFinished();
|
||||
void on_bluetoothEnable_stateChanged(int);
|
||||
void on_filterEnable_stateChanged();
|
||||
|
||||
@@ -56,7 +56,7 @@ class HardwarePanel : public GeneralPanel
|
||||
protected:
|
||||
void setupPotType(int index, QLabel * label, AutoLineEdit * name, AutoComboBox * type);
|
||||
void setupSliderType(int index, QLabel * label, AutoLineEdit * name, AutoComboBox * type);
|
||||
void setupSwitchType(int index, QLabel * label, AutoLineEdit * name, AutoComboBox * type, bool threePos);
|
||||
void setupSwitchType(int index, QLabel * label, AutoLineEdit * name, AutoComboBox * type, bool threePos = true);
|
||||
|
||||
private:
|
||||
Ui::Hardware *ui;
|
||||
|
||||
@@ -6,14 +6,23 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>359</width>
|
||||
<height>1594</height>
|
||||
<width>470</width>
|
||||
<height>1095</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2" rowstretch="0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0" columnstretch="0,0,0,0,0">
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="29" column="0">
|
||||
<widget class="QLabel" name="sqLabel">
|
||||
<property name="text">
|
||||
@@ -125,19 +134,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="5">
|
||||
<widget class="Line" name="potsTypeSeparator_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="AutoLineEdit" name="pot2Name">
|
||||
<property name="maxLength">
|
||||
@@ -730,32 +726,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="31" column="0" colspan="4">
|
||||
<widget class="Line" name="potsTypeSeparator_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="38" column="0" colspan="4">
|
||||
<widget class="Line" name="potsTypeSeparator_4">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="25" column="0">
|
||||
<widget class="QLabel" name="smLabel">
|
||||
<property name="text">
|
||||
@@ -1075,6 +1045,12 @@
|
||||
</item>
|
||||
<item row="32" column="0">
|
||||
<widget class="QLabel" name="bluetoothLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Bluetooth</string>
|
||||
</property>
|
||||
@@ -1090,24 +1066,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="32" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="bluetoothEnable">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AutoLineEdit" name="bluetoothName">
|
||||
<property name="maxLength">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="33" column="1">
|
||||
<widget class="QCheckBox" name="filterEnable">
|
||||
<property name="text">
|
||||
@@ -1122,19 +1080,116 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="32" column="1">
|
||||
<widget class="QWidget" name="bluetoothWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="bluetoothEnable">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>5</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="btNameLabel">
|
||||
<property name="text">
|
||||
<string>Device Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="AutoLineEdit" name="bluetoothName">
|
||||
<property name="maxLength">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="31" column="0" colspan="3">
|
||||
<widget class="Line" name="potsTypeSeparator_2">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="38" column="0" colspan="3">
|
||||
<widget class="Line" name="ppmSeparator">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0" colspan="3">
|
||||
<widget class="Line" name="potsTypeSeparator_1">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>AutoLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>autolineedit.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>AutoComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>autocombobox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>AutoLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>autolineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@@ -225,7 +225,7 @@ void CurveGroup::update()
|
||||
lastType = curve.type;
|
||||
curveValueCB->clear();
|
||||
for (int i=0; i<=6/*TODO constant*/; i++) {
|
||||
curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_FUNC, i).toString());
|
||||
curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_FUNC, i).toString(&model, false));
|
||||
}
|
||||
}
|
||||
curveValueCB->setCurrentIndex(curve.value);
|
||||
@@ -237,7 +237,7 @@ void CurveGroup::update()
|
||||
lastType = curve.type;
|
||||
curveValueCB->clear();
|
||||
for (int i= ((flags & HIDE_NEGATIVE_CURVES) ? 0 : -numcurves); i<=numcurves; i++) {
|
||||
curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, i).toString(), i);
|
||||
curveValueCB->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, i).toString(&model, false), i);
|
||||
if (i == curve.value) {
|
||||
curveValueCB->setCurrentIndex(curveValueCB->count() - 1);
|
||||
}
|
||||
@@ -324,38 +324,43 @@ void CurveGroup::valuesChanged()
|
||||
|
||||
void Helpers::populateGVCB(QComboBox & b, int value, const ModelData & model)
|
||||
{
|
||||
bool selected = false;
|
||||
int count = getCurrentFirmware()->getCapability(Gvars);
|
||||
|
||||
b.clear();
|
||||
|
||||
int count = getCurrentFirmware()->getCapability(Gvars);
|
||||
for (int i=-count; i<=-1; i++) {
|
||||
int16_t gval = (int16_t)(-10000+i);
|
||||
if (strlen(model.gvars_names[-i-1]) > 0)
|
||||
b.addItem(QObject::tr("-GV%1 (%2)").arg(-i).arg(model.gvars_names[-i-1]), gval);
|
||||
else
|
||||
b.addItem(QObject::tr("-GV%1").arg(-i), gval);
|
||||
if (value == gval) {
|
||||
b.setCurrentIndex(b.count()-1);
|
||||
selected = true;
|
||||
}
|
||||
b.addItem("-" + RawSource(SOURCE_TYPE_GVAR, abs(i)-1).toString(&model), gval);
|
||||
}
|
||||
|
||||
for (int i=1; i<=count; i++) {
|
||||
int16_t gval = (int16_t)(10000+i);
|
||||
if (strlen(model.gvars_names[i-1]) > 0)
|
||||
b.addItem(QObject::tr("GV%1 (%2)").arg(i).arg(model.gvars_names[i-1]), gval);
|
||||
else
|
||||
b.addItem(QObject::tr("GV%1").arg(i), gval);
|
||||
if (value == gval) {
|
||||
b.setCurrentIndex(b.count()-1);
|
||||
selected = true;
|
||||
}
|
||||
b.addItem(RawSource(SOURCE_TYPE_GVAR, i-1).toString(&model), gval);
|
||||
}
|
||||
|
||||
if (!selected) {
|
||||
b.setCurrentIndex(b.findData(value));
|
||||
if (b.currentIndex() == -1)
|
||||
b.setCurrentIndex(count);
|
||||
}
|
||||
|
||||
// Returns Diff/Expo/Weight/Offset adjustment value as either a percentage or a global variable name.
|
||||
QString Helpers::getAdjustmentString(int16_t val, const ModelData * model, bool sign)
|
||||
{
|
||||
QString ret;
|
||||
if (val >= -10000 && val <= 10000) {
|
||||
ret = "%1%";
|
||||
if (sign && val > 0)
|
||||
ret.prepend("+");
|
||||
ret = ret.arg(val);
|
||||
}
|
||||
else {
|
||||
ret = RawSource(SOURCE_TYPE_GVAR, abs(val) - 10001).toString(model);
|
||||
if (val < 0)
|
||||
ret.prepend("-");
|
||||
else if (sign)
|
||||
ret.prepend("+");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Helpers::populateGvarUseCB(QComboBox * b, unsigned int phase)
|
||||
@@ -368,29 +373,6 @@ void Helpers::populateGvarUseCB(QComboBox * b, unsigned int phase)
|
||||
}
|
||||
}
|
||||
|
||||
void Helpers::populateGvSourceCB(QComboBox * b, int value)
|
||||
{
|
||||
QString strings[] = { QObject::tr("---"), QObject::tr("Rud Trim"), QObject::tr("Ele Trim"), QObject::tr("Thr Trim"), QObject::tr("Ail Trim"), QObject::tr("Rot Enc"), QObject::tr("Rud"), QObject::tr("Ele"), QObject::tr("Thr"), QObject::tr("Ail"), QObject::tr("P1"), QObject::tr("P2"), QObject::tr("P3")};
|
||||
b->clear();
|
||||
for (int i=0; i<= 12; i++) {
|
||||
b->addItem(strings[i]);
|
||||
}
|
||||
b->setCurrentIndex(value);
|
||||
}
|
||||
|
||||
void Helpers::populatePhasesCB(QComboBox * b, int value)
|
||||
{
|
||||
for (int i=-getCurrentFirmware()->getCapability(FlightModes); i<=getCurrentFirmware()->getCapability(FlightModes); i++) {
|
||||
if (i < 0)
|
||||
b->addItem(QObject::tr("!Flight mode %1").arg(-i-1), i);
|
||||
else if (i > 0)
|
||||
b->addItem(QObject::tr("Flight mode %1").arg(i-1), i);
|
||||
else
|
||||
b->addItem(QObject::tr("----"), 0);
|
||||
}
|
||||
b->setCurrentIndex(value + getCurrentFirmware()->getCapability(FlightModes));
|
||||
}
|
||||
|
||||
void Helpers::populateFileComboBox(QComboBox * b, const QSet<QString> & set, const QString & current)
|
||||
{
|
||||
b->clear();
|
||||
@@ -422,83 +404,6 @@ void Helpers::getFileComboBoxValue(QComboBox * b, char * dest, int length)
|
||||
}
|
||||
}
|
||||
|
||||
void Helpers::addRawSwitchItems(QStandardItemModel * itemModel, const RawSwitchType & type, int count, const GeneralSettings * const generalSettings)
|
||||
{
|
||||
// Most RawSwitch() indices are one-based (vs. typical zero); these are exceptions to the rule:
|
||||
const static QVector<int> rawSwitchIndexBaseZeroTypes = QVector<int>() << SWITCH_TYPE_NONE << SWITCH_TYPE_ON << SWITCH_TYPE_OFF << SWITCH_TYPE_TIMER_MODE;
|
||||
|
||||
int rawIdxAdj = 0;
|
||||
const Board::Type board = getCurrentBoard();
|
||||
int i = (count < 0 ? count : 1);
|
||||
const int maxCount = (i < 0 ? 0 : count + i);
|
||||
|
||||
// handle exceptions in RawSwitch() index values
|
||||
if (rawSwitchIndexBaseZeroTypes.contains(type))
|
||||
rawIdxAdj = -1;
|
||||
|
||||
for ( ; i < maxCount; ++i) {
|
||||
if (generalSettings) {
|
||||
if (type == SWITCH_TYPE_SWITCH && IS_HORUS_OR_TARANIS(board) && !generalSettings->switchPositionAllowedTaranis(abs(i)))
|
||||
continue;
|
||||
if (type == SWITCH_TYPE_MULTIPOS_POT) {
|
||||
int pot = div(abs(i) - 1, getCurrentFirmware()->getCapability(MultiposPotsPositions)).quot;
|
||||
if (!generalSettings->isPotAvailable(pot) || generalSettings->potConfig[pot] != Board::POT_MULTIPOS_SWITCH)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
RawSwitch rs(type, i + rawIdxAdj);
|
||||
QStandardItem * modelItem = new QStandardItem(rs.toString(board, generalSettings));
|
||||
modelItem->setData(rs.toValue(), Qt::UserRole);
|
||||
itemModel->appendRow(modelItem);
|
||||
}
|
||||
}
|
||||
|
||||
QStandardItemModel * Helpers::getRawSwitchItemModel(const GeneralSettings * const generalSettings, SwitchContext context)
|
||||
{
|
||||
QStandardItemModel * itemModel = new QStandardItemModel();
|
||||
Board::Type board = getCurrentBoard();
|
||||
Firmware * fw = getCurrentFirmware();
|
||||
|
||||
// Descending switch direction: NOT (!) switches
|
||||
|
||||
if (context != MixesContext && context != GlobalFunctionsContext && IS_ARM(board)) {
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes), generalSettings);
|
||||
}
|
||||
if (context != GlobalFunctionsContext) {
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_VIRTUAL, -fw->getCapability(LogicalSwitches), generalSettings);
|
||||
}
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_ROTARY_ENCODER, -fw->getCapability(RotaryEncoders), generalSettings);
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_TRIM, -getBoardCapability(board, Board::NumTrimSwitches), generalSettings);
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_MULTIPOS_POT, -(fw->getCapability(MultiposPots) * fw->getCapability(MultiposPotsPositions)), generalSettings);
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_SWITCH, -fw->getCapability(SwitchesPositions), generalSettings);
|
||||
|
||||
// Ascending switch direction (including zero)
|
||||
|
||||
if (context == TimersContext) {
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_TIMER_MODE, 5, generalSettings);
|
||||
}
|
||||
else {
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_NONE, 1);
|
||||
}
|
||||
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_SWITCH, fw->getCapability(SwitchesPositions), generalSettings);
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_MULTIPOS_POT, fw->getCapability(MultiposPots) * fw->getCapability(MultiposPotsPositions), generalSettings);
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_TRIM, getBoardCapability(board, Board::NumTrimSwitches), generalSettings);
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_ROTARY_ENCODER, fw->getCapability(RotaryEncoders), generalSettings);
|
||||
if (context != GlobalFunctionsContext) {
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_VIRTUAL, fw->getCapability(LogicalSwitches), generalSettings);
|
||||
}
|
||||
if (context != MixesContext && context != GlobalFunctionsContext && IS_ARM(board)) {
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_FLIGHT_MODE, fw->getCapability(FlightModes), generalSettings);
|
||||
}
|
||||
if (context == SpecialFunctionsContext || context == GlobalFunctionsContext) {
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_ON, 1);
|
||||
addRawSwitchItems(itemModel, SWITCH_TYPE_ONE, 1);
|
||||
}
|
||||
|
||||
return itemModel;
|
||||
}
|
||||
|
||||
void Helpers::addRawSourceItems(QStandardItemModel * itemModel, const RawSourceType & type, int count, const GeneralSettings * const generalSettings,
|
||||
const ModelData * const model, const int start, const QList<int> exclude)
|
||||
{
|
||||
@@ -530,7 +435,7 @@ void Helpers::addRawSourceItems(QStandardItemModel * itemModel, const RawSourceT
|
||||
QStandardItemModel * Helpers::getRawSourceItemModel(const GeneralSettings * const generalSettings, const ModelData * const model, unsigned int flags)
|
||||
{
|
||||
QStandardItemModel * itemModel = new QStandardItemModel();
|
||||
Board::Type board = getCurrentBoard();
|
||||
Boards board = Boards(getCurrentBoard());
|
||||
Firmware * fw = getCurrentFirmware();
|
||||
|
||||
if (flags & POPULATE_NONE) {
|
||||
@@ -548,13 +453,13 @@ QStandardItemModel * Helpers::getRawSourceItemModel(const GeneralSettings * cons
|
||||
}
|
||||
|
||||
if (flags & POPULATE_SOURCES) {
|
||||
int totalSources = CPN_MAX_STICKS + getBoardCapability(board, Board::Pots) + getBoardCapability(board, Board::Sliders) + getBoardCapability(board, Board::MouseAnalogs);
|
||||
int totalSources = CPN_MAX_STICKS + board.getCapability(Board::Pots) + board.getCapability(Board::Sliders) + board.getCapability(Board::MouseAnalogs);
|
||||
addRawSourceItems(itemModel, SOURCE_TYPE_STICK, totalSources, generalSettings, model);
|
||||
addRawSourceItems(itemModel, SOURCE_TYPE_ROTARY_ENCODER, fw->getCapability(RotaryEncoders), generalSettings, model);
|
||||
}
|
||||
|
||||
if (flags & POPULATE_TRIMS) {
|
||||
addRawSourceItems(itemModel, SOURCE_TYPE_TRIM, getBoardCapability(board, Board::NumTrims), generalSettings, model);
|
||||
addRawSourceItems(itemModel, SOURCE_TYPE_TRIM, board.getCapability(Board::NumTrims), generalSettings, model);
|
||||
}
|
||||
|
||||
if (flags & POPULATE_SOURCES) {
|
||||
@@ -562,7 +467,7 @@ QStandardItemModel * Helpers::getRawSourceItemModel(const GeneralSettings * cons
|
||||
}
|
||||
|
||||
if (flags & POPULATE_SWITCHES) {
|
||||
addRawSourceItems(itemModel, SOURCE_TYPE_SWITCH, getBoardCapability(board, Board::Switches), generalSettings, model);
|
||||
addRawSourceItems(itemModel, SOURCE_TYPE_SWITCH, board.getCapability(Board::Switches), generalSettings, model);
|
||||
addRawSourceItems(itemModel, SOURCE_TYPE_CUSTOM_SWITCH, fw->getCapability(LogicalSwitches), generalSettings, model);
|
||||
}
|
||||
|
||||
@@ -573,7 +478,7 @@ QStandardItemModel * Helpers::getRawSourceItemModel(const GeneralSettings * cons
|
||||
}
|
||||
|
||||
if (flags & POPULATE_TELEMETRY) {
|
||||
if (IS_ARM(board)) {
|
||||
if (IS_ARM(board.getBoardType())) {
|
||||
addRawSourceItems(itemModel, SOURCE_TYPE_SPECIAL, 5, generalSettings, model);
|
||||
|
||||
if (model) {
|
||||
@@ -593,7 +498,7 @@ QStandardItemModel * Helpers::getRawSourceItemModel(const GeneralSettings * cons
|
||||
exclude << TELEMETRY_SOURCE_TX_TIME;
|
||||
if (!fw->getCapability(SportTelemetry))
|
||||
exclude << TELEMETRY_SOURCE_SWR;
|
||||
if (!IS_ARM(board))
|
||||
if (!IS_ARM(board.getBoardType()))
|
||||
exclude << TELEMETRY_SOURCE_TIMER3;
|
||||
int count = ((flags & POPULATE_TELEMETRYEXT) ? TELEMETRY_SOURCES_STATUS_COUNT : TELEMETRY_SOURCES_COUNT);
|
||||
addRawSourceItems(itemModel, SOURCE_TYPE_TELEMETRY, count, generalSettings, model, 0, exclude);
|
||||
@@ -795,10 +700,19 @@ QPixmap makePixMap(const QImage & image)
|
||||
int version2index(const QString & version)
|
||||
{
|
||||
int result = 999;
|
||||
QStringList parts = version.split("N");
|
||||
if (parts.size() > 1)
|
||||
result = parts[1].toInt(); // nightly build
|
||||
parts = parts[0].split('.');
|
||||
QStringList parts;
|
||||
QString mainVersion = version;
|
||||
if (version.contains("RC")) {
|
||||
parts = version.split("RC");
|
||||
result = parts[1].toInt() + 900; // RC0 = 900; RC1=901,..
|
||||
mainVersion = parts[0];
|
||||
}
|
||||
else if (version.contains("N")) {
|
||||
parts = version.split("N");
|
||||
result = parts[1].toInt(); // nightly build up to 899
|
||||
mainVersion = parts[0];
|
||||
}
|
||||
parts = mainVersion.split('.');
|
||||
if (parts.size() > 2)
|
||||
result += 1000 * parts[2].toInt();
|
||||
if (parts.size() > 1)
|
||||
@@ -820,9 +734,12 @@ const QString index2version(int index)
|
||||
int minor = index % 100;
|
||||
int major = index / 100;
|
||||
result = templt.arg(major).arg(minor).arg(revision);
|
||||
if (nightly > 0 && nightly < 999) {
|
||||
if (nightly > 0 && nightly < 900) {
|
||||
result += "N" + QString::number(nightly);
|
||||
}
|
||||
else if (nightly >= 900 && nightly < 1000) {
|
||||
result += "RC" + QString::number(nightly-900);
|
||||
}
|
||||
}
|
||||
else if (index >= 19900) {
|
||||
int revision = index % 100;
|
||||
|
||||
@@ -129,26 +129,13 @@ class CurveGroup : public QObject {
|
||||
|
||||
namespace Helpers
|
||||
{
|
||||
enum SwitchContext
|
||||
{
|
||||
LogicalSwitchesContext,
|
||||
SpecialFunctionsContext,
|
||||
GlobalFunctionsContext,
|
||||
TimersContext,
|
||||
MixesContext
|
||||
};
|
||||
|
||||
void addRawSwitchItems(QStandardItemModel * itemModel, const RawSwitchType & type, int count, const GeneralSettings * const generalSettings = NULL);
|
||||
QStandardItemModel * getRawSwitchItemModel(const GeneralSettings * const generalSettings = NULL, SwitchContext context = LogicalSwitchesContext);
|
||||
|
||||
void addRawSourceItems(QStandardItemModel * itemModel, const RawSourceType & type, int count, const GeneralSettings * const generalSettings = NULL,
|
||||
const ModelData * const model = NULL, const int start = 0, const QList<int> exclude = QList<int>());
|
||||
QStandardItemModel * getRawSourceItemModel(const GeneralSettings * const generalSettings = NULL, const ModelData * const model = NULL, unsigned int flags = 0);
|
||||
|
||||
void populateGvarUseCB(QComboBox *b, unsigned int phase);
|
||||
void populateGvSourceCB(QComboBox *b, int value);
|
||||
void populatePhasesCB(QComboBox *b, int value);
|
||||
void populateGVCB(QComboBox & b, int value, const ModelData & model);
|
||||
QString getAdjustmentString(int16_t val, const ModelData * model = NULL, bool sign = false);
|
||||
|
||||
void populateFileComboBox(QComboBox * b, const QSet<QString> & set, const QString & current);
|
||||
void getFileComboBoxValue(QComboBox * b, char * dest, int length);
|
||||
|
||||
@@ -1 +1 @@
|
||||
IDI_ICON1 ICON DISCARDABLE "icon.ico"
|
||||
IDI_ICON1 ICON DISCARDABLE "icon.ico"
|
||||
|
||||
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 965 B |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
@@ -100,6 +100,8 @@ LogsDialog::LogsDialog(QWidget *parent) :
|
||||
ui->mapsButton->hide();
|
||||
}
|
||||
|
||||
ui->SaveSession_PB->setEnabled(false);
|
||||
|
||||
// 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:
|
||||
@@ -116,6 +118,7 @@ LogsDialog::LogsDialog(QWidget *parent) :
|
||||
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()));
|
||||
connect(ui->SaveSession_PB, SIGNAL(clicked()), this, SLOT(on_saveSession_BT_clicked()));
|
||||
}
|
||||
|
||||
LogsDialog::~LogsDialog()
|
||||
@@ -610,6 +613,48 @@ void LogsDialog::on_fileOpen_BT_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
void LogsDialog::on_saveSession_BT_clicked()
|
||||
{
|
||||
int index = ui->sessions_CB->currentIndex();
|
||||
// ignore index 0 is its all sessions combined
|
||||
if(index > 0) {
|
||||
int n = csvlog.count();
|
||||
QList<QStringList> sessionCsvLog;
|
||||
// add CSV headers from first row of source file
|
||||
sessionCsvLog.push_back(csvlog[0]);
|
||||
// find session breaks
|
||||
int currentSession = 0;
|
||||
QDateTime lastvalue;
|
||||
for (int i = 1; i < n; i++) {
|
||||
QDateTime tmp = getRecordTimeStamp(i);
|
||||
if (!lastvalue.isValid() || lastvalue.secsTo(tmp) > 60) {
|
||||
currentSession++;
|
||||
}
|
||||
lastvalue = tmp;
|
||||
if(currentSession == index) {
|
||||
// add records to filtered list
|
||||
sessionCsvLog.push_back(csvlog[i]);
|
||||
}
|
||||
else if (currentSession > index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// save the filtered records to a new file
|
||||
QString newFilename = logFilename;
|
||||
newFilename.append(QString("-Session%1.csv").arg(index));
|
||||
QString filename = QFileDialog::getSaveFileName(this, "Save log", newFilename, "CSV files (.csv);", 0, 0); // getting the filename (full path)
|
||||
QFile data(filename);
|
||||
if(data.open(QFile::WriteOnly |QFile::Truncate)) {
|
||||
QTextStream output(&data);
|
||||
int numRecords = sessionCsvLog.count();
|
||||
for(int i = 0; i < numRecords; i++){
|
||||
output << sessionCsvLog[i].join(",") << '\n';
|
||||
}
|
||||
}
|
||||
sessionCsvLog.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool LogsDialog::cvsFileParse()
|
||||
{
|
||||
QFile file(ui->FileName_LE->text());
|
||||
@@ -697,6 +742,7 @@ QString LogsDialog::generateDuration(const QDateTime & start, const QDateTime &
|
||||
void LogsDialog::setFlightSessions()
|
||||
{
|
||||
ui->sessions_CB->clear();
|
||||
ui->SaveSession_PB->setEnabled(false);
|
||||
|
||||
int n = csvlog.count();
|
||||
// qDebug() << "records" << n;
|
||||
@@ -756,6 +802,11 @@ void LogsDialog::on_sessions_CB_currentIndexChanged(int index)
|
||||
|
||||
QItemSelection selection(topLeft, bottomRight);
|
||||
ui->logTable->selectionModel()->select(selection, QItemSelectionModel::Select);
|
||||
|
||||
ui->SaveSession_PB->setEnabled(true);
|
||||
}
|
||||
else {
|
||||
ui->SaveSession_PB->setEnabled(false);
|
||||
}
|
||||
|
||||
plotLock = false;
|
||||
|
||||
@@ -78,6 +78,7 @@ private slots:
|
||||
void removeAllGraphs();
|
||||
void plotLogs();
|
||||
void on_fileOpen_BT_clicked();
|
||||
void on_saveSession_BT_clicked();
|
||||
void on_sessions_CB_currentIndexChanged(int index);
|
||||
void on_mapsButton_clicked();
|
||||
void yAxisChangeRanges(QCPRange range);
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="SaveSession_PB">
|
||||
<property name="text">
|
||||
<string>Save session CSV</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "downloaddialog.h"
|
||||
#include "printdialog.h"
|
||||
#include "version.h"
|
||||
#include "contributorsdialog.h"
|
||||
#include "creditsdialog.h"
|
||||
#include "releasenotesdialog.h"
|
||||
#include "releasenotesfirmwaredialog.h"
|
||||
#include "customizesplashdialog.h"
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "process_sync.h"
|
||||
#include "radiointerface.h"
|
||||
#include "progressdialog.h"
|
||||
#include "progresswidget.h"
|
||||
#include "storage.h"
|
||||
#include "translations.h"
|
||||
|
||||
@@ -52,22 +53,31 @@
|
||||
#include <QFileInfo>
|
||||
#include <QDesktopServices>
|
||||
|
||||
#define OPENTX_COMPANION_DOWNLOADS "http://downloads-22.open-tx.org/companion"
|
||||
#define OPENTX_DOWNLOADS_PAGE_URL "http://www.open-tx.org/downloads"
|
||||
#define DONATE_STR "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QUZ48K4SEXDP2"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define COMPANION_STAMP "companion-macosx.stamp"
|
||||
#define COMPANION_INSTALLER "companion-macosx-%1.dmg"
|
||||
#else
|
||||
#define COMPANION_INSTALLER "macosx/opentx-companion-%1.dmg"
|
||||
#define COMPANION_FILEMASK tr("Diskimage (*.dmg)")
|
||||
#define COMPANION_INSTALL_QUESTION tr("Would you like to open the disk image to install the new version?")
|
||||
#elif WIN32
|
||||
#define COMPANION_STAMP "companion-windows.stamp"
|
||||
#define COMPANION_INSTALLER "companion-windows-%1.exe"
|
||||
#define COMPANION_INSTALLER "windows/companion-windows-%1.exe"
|
||||
#define COMPANION_FILEMASK tr("Executable (*.exe)")
|
||||
#define COMPANION_INSTALL_QUESTION tr("Would you like to launch the installer?")
|
||||
#else
|
||||
#define COMPANION_STAMP "companion-linux.stamp"
|
||||
#define COMPANION_INSTALLER "" // no automated updates for linux
|
||||
#define COMPANION_FILEMASK "*.*"
|
||||
#define COMPANION_INSTALL_QUESTION tr("Would you like to launch the installer?")
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define OPENTX_NIGHT_COMPANION_DOWNLOADS "http://downloads-22.open-tx.org/nightly/companion/windows"
|
||||
#else
|
||||
#define OPENTX_NIGHT_COMPANION_DOWNLOADS "http://downloads-22.open-tx.org/nightly/companion/linux"
|
||||
#endif
|
||||
const char * const OPENTX_COMPANION_DOWNLOAD_URL[] = {
|
||||
"https://downloads.open-tx.org/2.2/release/companion",
|
||||
"https://downloads.open-tx.org/2.2/rc/companion",
|
||||
"https://downloads.open-tx.org/2.2/nightlies/companion"
|
||||
};
|
||||
|
||||
MainWindow::MainWindow():
|
||||
downloadDialog_forWait(NULL),
|
||||
@@ -108,7 +118,16 @@ MainWindow::MainWindow():
|
||||
if (showSplash) {
|
||||
updateDelay += (SPLASH_TIME*1000);
|
||||
}
|
||||
QTimer::singleShot(updateDelay, this, SLOT(doAutoUpdates()));
|
||||
|
||||
if (g.isFirstUse()) {
|
||||
g.warningId(g.warningId() | AppMessages::MSG_WELCOME);
|
||||
QTimer::singleShot(updateDelay-500, this, SLOT(appPrefs())); // must be shown before warnings dialog but after splash
|
||||
}
|
||||
else {
|
||||
if (!g.previousVersion().isEmpty())
|
||||
g.warningId(g.warningId() | AppMessages::MSG_UPGRADED);
|
||||
QTimer::singleShot(updateDelay, this, SLOT(doAutoUpdates()));
|
||||
}
|
||||
QTimer::singleShot(updateDelay, this, SLOT(displayWarnings()));
|
||||
|
||||
QStringList strl = QApplication::arguments();
|
||||
@@ -161,21 +180,39 @@ MainWindow::~MainWindow()
|
||||
|
||||
void MainWindow::displayWarnings()
|
||||
{
|
||||
int warnId = g.warningId();
|
||||
if (warnId<WARNING_ID && warnId!=0) {
|
||||
int res=0;
|
||||
if (WARNING_LEVEL>0)
|
||||
QMessageBox::warning(this, "Companion", WARNING);
|
||||
else
|
||||
QMessageBox::about(this, "Companion", WARNING);
|
||||
res = QMessageBox::question(this, "Companion", tr("Display previous warning again at startup ?"), QMessageBox::Yes | QMessageBox::No);
|
||||
if (res == QMessageBox::No) {
|
||||
g.warningId(WARNING_ID);
|
||||
}
|
||||
using namespace AppMessages;
|
||||
static uint shownMsgs = 0;
|
||||
int showMsgs = g.warningId();
|
||||
int msgId;
|
||||
QString infoTxt;
|
||||
|
||||
if ((showMsgs & MSG_WELCOME) && !(shownMsgs & MSG_WELCOME)) {
|
||||
infoTxt = CPN_STR_MSG_WELCOME.arg(VERSION);
|
||||
msgId = MSG_WELCOME;
|
||||
}
|
||||
else if (warnId==0) {
|
||||
g.warningId(WARNING_ID);
|
||||
else if ((showMsgs & MSG_UPGRADED) && !(shownMsgs & MSG_UPGRADED)) {
|
||||
infoTxt = CPN_STR_MSG_UPGRADED.arg(VERSION);
|
||||
msgId = MSG_UPGRADED;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
QMessageBox msgBox(this);
|
||||
msgBox.setWindowTitle(tr("Companion"));
|
||||
msgBox.setIcon(QMessageBox::Information);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setInformativeText(infoTxt);
|
||||
QCheckBox * cb = new QCheckBox(tr("Show this message again at next startup?"), &msgBox);
|
||||
msgBox.setCheckBox(cb);
|
||||
|
||||
msgBox.exec();
|
||||
|
||||
shownMsgs |= msgId;
|
||||
if (!cb->isChecked())
|
||||
g.warningId(showMsgs & ~msgId);
|
||||
|
||||
displayWarnings(); // in case more warnings need showing
|
||||
}
|
||||
|
||||
void MainWindow::doAutoUpdates()
|
||||
@@ -207,11 +244,7 @@ void MainWindow::dowloadLastFirmwareUpdate()
|
||||
|
||||
QString MainWindow::getCompanionUpdateBaseUrl()
|
||||
{
|
||||
#if defined(ALLOW_NIGHTLY_BUILDS)
|
||||
return g.useCompanionNightlyBuilds() ? OPENTX_NIGHT_COMPANION_DOWNLOADS : OPENTX_COMPANION_DOWNLOADS;
|
||||
#else
|
||||
return OPENTX_COMPANION_DOWNLOADS;
|
||||
#endif
|
||||
return OPENTX_COMPANION_DOWNLOAD_URL[g.boundedOpenTxBranch()];
|
||||
}
|
||||
|
||||
void MainWindow::checkForUpdates()
|
||||
@@ -288,20 +321,20 @@ void MainWindow::checkForCompanionUpdateFinished(QNetworkReply * reply)
|
||||
if (version.isNull())
|
||||
return onUpdatesError();
|
||||
|
||||
int vnum = version2index(version);
|
||||
int webVersion = version2index(version);
|
||||
|
||||
QString c9xversion = QString(VERSION);
|
||||
int c9xver = version2index(c9xversion);
|
||||
int ownVersion = version2index(VERSION);
|
||||
|
||||
if (c9xver < vnum) {
|
||||
#if defined WIN32 || !defined __GNUC__ // || defined __APPLE__ // OSX should only notify of updates since no update packages are available.
|
||||
if (ownVersion < webVersion) {
|
||||
#if defined WIN32 || defined __APPLE__
|
||||
int ret = QMessageBox::question(this, "Companion", tr("A new version of Companion is available (version %1)<br>"
|
||||
"Would you like to download it?").arg(version) ,
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (ret == QMessageBox::Yes) {
|
||||
QDir dir(g.updatesDir());
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), dir.absoluteFilePath(QString(COMPANION_INSTALLER).arg(version)), tr("Executable (*.exe)"));
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), dir.absoluteFilePath(QString(COMPANION_INSTALLER).arg(version)), COMPANION_FILEMASK);
|
||||
|
||||
if (!fileName.isEmpty()) {
|
||||
g.updatesDir(QFileInfo(fileName).dir().absolutePath());
|
||||
downloadDialog * dd = new downloadDialog(this, QString("%1/%2").arg(getCompanionUpdateBaseUrl()).arg(QString(COMPANION_INSTALLER).arg(version)), fileName);
|
||||
@@ -311,7 +344,7 @@ void MainWindow::checkForCompanionUpdateFinished(QNetworkReply * reply)
|
||||
}
|
||||
}
|
||||
#else
|
||||
QMessageBox::warning(this, tr("New release available"), tr("A new release of Companion is available, please check the OpenTX website!"));
|
||||
QMessageBox::warning(this, tr("New release available"), tr("A new release of Companion is available, please check the <a href='%1'>OpenTX website!</a>").arg(OPENTX_DOWNLOADS_PAGE_URL));
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
@@ -325,8 +358,7 @@ void MainWindow::checkForCompanionUpdateFinished(QNetworkReply * reply)
|
||||
|
||||
void MainWindow::updateDownloaded()
|
||||
{
|
||||
int ret = QMessageBox::question(this, "Companion", tr("Would you like to launch the installer?") ,
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
int ret = QMessageBox::question(this, "Companion", COMPANION_INSTALL_QUESTION, QMessageBox::Yes | QMessageBox::No);
|
||||
if (ret == QMessageBox::Yes) {
|
||||
if (QDesktopServices::openUrl(QUrl::fromLocalFile(installer_fileName)))
|
||||
QApplication::exit();
|
||||
@@ -529,6 +561,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
g.mainWinGeo(saveGeometry());
|
||||
g.mainWinState(saveState());
|
||||
g.tabbedMdi(actTabbedWindows->isChecked());
|
||||
QApplication::closeAllWindows();
|
||||
mdiArea->closeAllSubWindows();
|
||||
if (mdiArea->currentSubWindow()) {
|
||||
event->ignore();
|
||||
@@ -657,9 +690,7 @@ void MainWindow::openFile(const QString & fileName, bool updateLastUsedDir)
|
||||
|
||||
void MainWindow::openFile()
|
||||
{
|
||||
QString fileFilter;
|
||||
fileFilter = tr(EEPROM_FILES_FILTER);
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Models and Settings file"), g.eepromDir(), fileFilter);
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open Models and Settings file"), g.eepromDir(), EEPROM_FILES_FILTER);
|
||||
openFile(fileName);
|
||||
}
|
||||
|
||||
@@ -732,29 +763,259 @@ void MainWindow::fwPrefs()
|
||||
|
||||
void MainWindow::contributors()
|
||||
{
|
||||
ContributorsDialog * dialog = new ContributorsDialog(this);
|
||||
CreditsDialog * dialog = new CreditsDialog(this);
|
||||
dialog->exec();
|
||||
dialog->deleteLater();
|
||||
}
|
||||
|
||||
// Create a widget with a line edit and folder select button and handles all interactions. Features autosuggest
|
||||
// path hints while typing, invalid paths shown in red. The label string is only for dialog title, not a QLabel.
|
||||
// This should probably be moved some place more reusable, esp. the QFileSystemModel.
|
||||
QWidget * folderSelectorWidget(QString * path, const QString & label, QWidget * parent)
|
||||
{
|
||||
static QFileSystemModel fileModel;
|
||||
static bool init = false;
|
||||
if (!init) {
|
||||
init = true;
|
||||
fileModel.setFilter(QDir::Dirs);
|
||||
fileModel.setRootPath("/");
|
||||
}
|
||||
|
||||
QWidget * fsw = new QWidget(parent);
|
||||
QLineEdit * le = new QLineEdit(parent);
|
||||
QCompleter * fsc = new QCompleter(fsw);
|
||||
fsc->setModel(&fileModel);
|
||||
//fsc->setCompletionMode(QCompleter::InlineCompletion);
|
||||
le->setCompleter(fsc);
|
||||
|
||||
QToolButton * btn = new QToolButton(fsw);
|
||||
btn->setIcon(CompanionIcon("open.png"));
|
||||
QHBoxLayout * l = new QHBoxLayout(fsw);
|
||||
l->setContentsMargins(0,0,0,0);
|
||||
l->setSpacing(3);
|
||||
l->addWidget(le);
|
||||
l->addWidget(btn);
|
||||
|
||||
QObject::connect(btn, &QToolButton::clicked, [=]() {
|
||||
QString dir = QFileDialog::getExistingDirectory(parent, label, le->text(), 0);
|
||||
if (!dir.isEmpty()) {
|
||||
le->setText(QDir::toNativeSeparators(dir));
|
||||
le->setFocus();
|
||||
}
|
||||
});
|
||||
|
||||
QObject::connect(le, &QLineEdit::textChanged, [=](const QString & text) {
|
||||
*path = text;
|
||||
if (QFile::exists(text))
|
||||
le->setStyleSheet("");
|
||||
else
|
||||
le->setStyleSheet("QLineEdit {color: red;}");
|
||||
});
|
||||
le->setText(QDir::toNativeSeparators(*path));
|
||||
|
||||
return fsw;
|
||||
}
|
||||
|
||||
void MainWindow::sdsync()
|
||||
{
|
||||
QString sdPath = g.profile[g.id()].sdPath();
|
||||
if (sdPath.isEmpty()) {
|
||||
QMessageBox::warning(this, QObject::tr("Synchronization error"), QObject::tr("No SD directory configured!"));
|
||||
const QString dlgTtl = tr("Synchronize SD");
|
||||
const QIcon dlgIcn = CompanionIcon("sdsync.png");
|
||||
const QString srcArw = CPN_STR_SW_INDICATOR_UP % " ";
|
||||
const QString dstArw = CPN_STR_SW_INDICATOR_DN % " ";
|
||||
QStringList errorMsgs;
|
||||
|
||||
// remember user-selectable options for duration of session
|
||||
static QString sourcePath;
|
||||
static QString destPath;
|
||||
static int syncDirection = SyncProcess::SYNC_A2B_B2A;
|
||||
static int compareType = SyncProcess::OVERWR_NEWER_IF_DIFF;
|
||||
static int maxFileSize = 2 * 1024 * 1024; // Bytes
|
||||
static bool dryRun = false;
|
||||
|
||||
if (sourcePath.isEmpty())
|
||||
sourcePath = g.profile[g.id()].sdPath();
|
||||
if (destPath.isEmpty())
|
||||
destPath = findMassstoragePath("SOUNDS").replace(QRegExp("[/\\\\]?SOUNDS"), "");
|
||||
|
||||
if (sourcePath.isEmpty())
|
||||
errorMsgs << tr("No local SD structure path configured!");
|
||||
if (destPath.isEmpty())
|
||||
errorMsgs << tr("No Radio or SD card detected!");
|
||||
|
||||
QDialog dlg(this);
|
||||
dlg.setWindowTitle(dlgTtl % tr(" :: Options"));
|
||||
dlg.setWindowIcon(dlgIcn);
|
||||
dlg.setSizeGripEnabled(true);
|
||||
dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
QLabel * lblSrc = new QLabel(tr("Local Folder:"), &dlg);
|
||||
QWidget * wdgSrc = folderSelectorWidget(&sourcePath, lblSrc->text(), &dlg);
|
||||
|
||||
QLabel * lblDst = new QLabel(tr("Radio Folder:"), &dlg);
|
||||
QWidget * wdgDst = folderSelectorWidget(&destPath, lblDst->text(), &dlg);
|
||||
|
||||
QLabel * lbDir = new QLabel(tr("Sync. Direction:"), &dlg);
|
||||
QComboBox * syncDir = new QComboBox(&dlg);
|
||||
syncDir->addItem(tr("%1%2 Both directions, to radio folder first").arg(dstArw, srcArw), SyncProcess::SYNC_A2B_B2A);
|
||||
syncDir->addItem(tr("%1%2 Both directions, to local folder first").arg(srcArw, dstArw), SyncProcess::SYNC_B2A_A2B);
|
||||
syncDir->addItem(tr(" %1 Only from local folder to radio folder").arg(dstArw), SyncProcess::SYNC_A2B);
|
||||
syncDir->addItem(tr(" %1 Only from radio folder to local folder").arg(srcArw), SyncProcess::SYNC_B2A);
|
||||
syncDir->setCurrentIndex(-1); // we set the default option later
|
||||
|
||||
QLabel * lbMode = new QLabel(tr("Existing Files:"), &dlg);
|
||||
QComboBox * copyMode = new QComboBox(&dlg);
|
||||
copyMode->setToolTip(tr("How to handle overwriting files which already exist in the destination folder."));
|
||||
copyMode->addItem(tr("Copy only if newer and different (compare contents)"), SyncProcess::OVERWR_NEWER_IF_DIFF);
|
||||
copyMode->addItem(tr("Copy only if newer (do not compare contents)"), SyncProcess::OVERWR_NEWER_ALWAYS);
|
||||
copyMode->addItem(tr("Copy only if different (ignore file time stamps)"), SyncProcess::OVERWR_IF_DIFF);
|
||||
copyMode->addItem(tr("Always copy (force overwite existing files)"), SyncProcess::OVERWR_ALWAYS);
|
||||
|
||||
QLabel * lbSize = new QLabel(tr("Max. File Size:"), &dlg);
|
||||
QSpinBox * maxSize = new QSpinBox(&dlg);
|
||||
maxSize->setRange(0, 100 * 1024);
|
||||
maxSize->setAccelerated(true);
|
||||
maxSize->setSpecialValueText(tr("Any size"));
|
||||
maxSize->setToolTip(tr("Skip files larger than this size. Enter zero for unlimited."));
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
|
||||
maxSize->setGroupSeparatorShown(true);
|
||||
#endif
|
||||
|
||||
QCheckBox * testRun = new QCheckBox(tr("Test-run only"), &dlg);
|
||||
testRun->setToolTip(tr("Run as normal but do not actually copy anything. Useful for verifying results before real sync."));
|
||||
connect(testRun, &QCheckBox::toggled, [=](bool on) { dryRun = on; });
|
||||
|
||||
// layout to hold size spinbox and checkbox option(s)
|
||||
QHBoxLayout * hlay1 = new QHBoxLayout();
|
||||
hlay1->addWidget(maxSize, 1);
|
||||
hlay1->addWidget(testRun);
|
||||
|
||||
// dialog OK/Cancel buttons
|
||||
QDialogButtonBox * bb = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, &dlg);
|
||||
|
||||
// Create main layout and add everything
|
||||
QGridLayout * dlgL = new QGridLayout(&dlg);
|
||||
dlgL->setSizeConstraint(QLayout::SetFixedSize);
|
||||
int row = 0;
|
||||
if (errorMsgs.size()) {
|
||||
QLabel * lblWarn = new QLabel(QString(errorMsgs.join('\n')), &dlg);
|
||||
lblWarn->setStyleSheet("QLabel { color: red; }");
|
||||
dlgL->addWidget(lblWarn, row++, 0, 1, 2);
|
||||
}
|
||||
dlgL->addWidget(lblSrc, row, 0);
|
||||
dlgL->addWidget(wdgSrc, row++, 1);
|
||||
dlgL->addWidget(lblDst, row, 0);
|
||||
dlgL->addWidget(wdgDst, row++, 1);
|
||||
dlgL->addWidget(lbDir, row, 0);
|
||||
dlgL->addWidget(syncDir, row++, 1);
|
||||
dlgL->addWidget(lbMode, row, 0);
|
||||
dlgL->addWidget(copyMode, row++, 1);
|
||||
dlgL->addWidget(lbSize, row, 0);
|
||||
dlgL->addLayout(hlay1, row++, 1);
|
||||
dlgL->addWidget(bb, row++, 0, 1, 2);
|
||||
dlgL->setRowStretch(row, 1);
|
||||
|
||||
connect(copyMode, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=](int) {
|
||||
compareType = copyMode->currentData().toInt();
|
||||
});
|
||||
|
||||
// function to dis/enable the OVERWR_ALWAYS option depending on sync direction
|
||||
connect(syncDir, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [=](int) {
|
||||
int dir = syncDir->currentData().toInt();
|
||||
int idx = copyMode->findData(SyncProcess::OVERWR_ALWAYS);
|
||||
int flg = (dir == SyncProcess::SYNC_A2B || dir == SyncProcess::SYNC_B2A) ? 33 : 0;
|
||||
if (!flg && idx == copyMode->currentIndex())
|
||||
copyMode->setCurrentIndex(copyMode->findData(SyncProcess::OVERWR_NEWER_IF_DIFF));
|
||||
copyMode->setItemData(idx, flg, Qt::UserRole - 1);
|
||||
syncDirection = dir;
|
||||
});
|
||||
|
||||
// function to set magnitude of file size spinbox, KB or MB
|
||||
connect(maxSize, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), [=](int value) {
|
||||
int multi = maxSize->property("multi").isValid() ? maxSize->property("multi").toInt() : 0;
|
||||
maxSize->blockSignals(true);
|
||||
if (value >= 10 * 1024 && multi != 1024 * 1024) {
|
||||
// KB -> MB
|
||||
multi = 1024 * 1024;
|
||||
maxSize->setValue(value / 1024);
|
||||
maxSize->setMaximum(100);
|
||||
maxSize->setSingleStep(1);
|
||||
maxSize->setSuffix(tr(" MB"));
|
||||
}
|
||||
else if ((value < 10 && multi != 1024) || !multi) {
|
||||
// MB -> KB
|
||||
if (multi)
|
||||
value *= 1024;
|
||||
multi = 1024;
|
||||
if (value == 9 * 1024)
|
||||
value += 1024 - 32; // avoid large jump when stepping from 10MB to 10,208KB
|
||||
maxSize->setMaximum(100 * 1024);
|
||||
maxSize->setValue(value);
|
||||
maxSize->setSingleStep(32);
|
||||
maxSize->setSuffix(tr(" KB"));
|
||||
}
|
||||
maxSize->setProperty("multi", multi);
|
||||
maxSize->blockSignals(false);
|
||||
maxFileSize = value * multi;
|
||||
});
|
||||
|
||||
copyMode->setCurrentIndex(copyMode->findData(compareType));
|
||||
syncDir->setCurrentIndex(syncDir->findData(syncDirection));
|
||||
maxSize->setValue(maxFileSize / 1024);
|
||||
testRun->setChecked(dryRun);
|
||||
|
||||
connect(bb, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
|
||||
connect(bb, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);
|
||||
|
||||
// to restart dialog on error/etc
|
||||
openDialog:
|
||||
|
||||
// show the modal options dialog
|
||||
if (dlg.exec() == QDialog::Rejected)
|
||||
return;
|
||||
|
||||
// validate
|
||||
errorMsgs.clear();
|
||||
if (sourcePath == destPath)
|
||||
errorMsgs << tr("Source and destination folders are the same!");
|
||||
if (sourcePath.isEmpty() || !QFile::exists(sourcePath))
|
||||
errorMsgs << tr("Source folder not found: %1").arg(sourcePath);
|
||||
if (destPath.isEmpty() || !QFile::exists(destPath))
|
||||
errorMsgs << tr("Destination folder not found: %1").arg(destPath);
|
||||
|
||||
if (!errorMsgs.isEmpty()) {
|
||||
QMessageBox::warning(this, dlgTtl % tr(" :: Error"), errorMsgs.join('\n'));
|
||||
goto openDialog;
|
||||
}
|
||||
QString massstoragePath = findMassstoragePath("SOUNDS");
|
||||
if (massstoragePath.isEmpty()) {
|
||||
QMessageBox::warning(this, QObject::tr("Synchronization error"), QObject::tr("No Radio connected!"));
|
||||
return;
|
||||
}
|
||||
massstoragePath = massstoragePath.left(massstoragePath.length() - 7);
|
||||
ProgressDialog progressDialog(this, tr("Synchronize SD"), CompanionIcon("sdsync.png"));
|
||||
SyncProcess syncProcess(massstoragePath, g.profile[g.id()].sdPath(), progressDialog.progress());
|
||||
if (!syncProcess.run()) {
|
||||
progressDialog.exec();
|
||||
}
|
||||
|
||||
// set up the progress dialog and the sync process worker
|
||||
ProgressDialog * progressDlg = new ProgressDialog(this, dlgTtl % tr(" :: Progress"), dlgIcn);
|
||||
progressDlg->setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
ProgressWidget * progWidget = progressDlg->progress();
|
||||
SyncProcess * syncProcess = new SyncProcess(sourcePath, destPath, syncDirection, compareType, maxFileSize, dryRun);
|
||||
|
||||
// move sync process to separate thread, we only use signals/slots from here on...
|
||||
QThread * syncThread = new QThread(this);
|
||||
syncProcess->moveToThread(syncThread);
|
||||
|
||||
// ...and quite a few of them!
|
||||
connect(this, &MainWindow::startSync, syncProcess, &SyncProcess::run);
|
||||
connect(syncThread, &QThread::finished, syncProcess, &SyncProcess::deleteLater);
|
||||
connect(syncProcess, &SyncProcess::finished, syncThread, &QThread::quit);
|
||||
connect(syncProcess, &SyncProcess::destroyed, syncThread, &QThread::quit);
|
||||
connect(syncProcess, &SyncProcess::destroyed, syncThread, &QThread::deleteLater);
|
||||
connect(syncProcess, &SyncProcess::fileCountChanged, progWidget, &ProgressWidget::setMaximum);
|
||||
connect(syncProcess, &SyncProcess::progressStep, progWidget, &ProgressWidget::setValue);
|
||||
connect(syncProcess, &SyncProcess::progressMessage, progWidget, &ProgressWidget::addMessage);
|
||||
connect(syncProcess, &SyncProcess::statusMessage, progWidget, &ProgressWidget::setInfo);
|
||||
connect(syncProcess, &SyncProcess::started, progressDlg, &ProgressDialog::setProcessStarted);
|
||||
connect(syncProcess, &SyncProcess::finished, progressDlg, &ProgressDialog::setProcessStopped);
|
||||
connect(syncProcess, &SyncProcess::finished, [=]() { QApplication::alert(this); });
|
||||
connect(progressDlg, &ProgressDialog::rejected, syncProcess, &SyncProcess::stop);
|
||||
connect(progressDlg, &ProgressDialog::rejected, syncProcess, &SyncProcess::deleteLater);
|
||||
|
||||
// go (finally)
|
||||
syncThread->start();
|
||||
emit startSync();
|
||||
}
|
||||
|
||||
void MainWindow::changelog()
|
||||
@@ -780,7 +1041,7 @@ void MainWindow::fwchangelog()
|
||||
|
||||
void MainWindow::customizeSplash()
|
||||
{
|
||||
customizeSplashDialog * dialog = new customizeSplashDialog(this);
|
||||
CustomizeSplashDialog * dialog = new CustomizeSplashDialog(this);
|
||||
dialog->exec();
|
||||
dialog->deleteLater();
|
||||
}
|
||||
@@ -861,7 +1122,7 @@ void MainWindow::readBackup()
|
||||
return;
|
||||
// TODO implementation
|
||||
}
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Radio Backup to File"), g.eepromDir(), tr(EXTERNAL_EEPROM_FILES_FILTER));
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Radio Backup to File"), g.eepromDir(), EXTERNAL_EEPROM_FILES_FILTER);
|
||||
if (!fileName.isEmpty()) {
|
||||
if (!readEepromFromRadio(fileName))
|
||||
return;
|
||||
@@ -870,7 +1131,7 @@ void MainWindow::readBackup()
|
||||
|
||||
void MainWindow::readFlash()
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(this,tr("Read Radio Firmware to File"), g.flashDir(),tr(FLASH_FILES_FILTER));
|
||||
QString fileName = QFileDialog::getSaveFileName(this,tr("Read Radio Firmware to File"), g.flashDir(), FLASH_FILES_FILTER);
|
||||
if (!fileName.isEmpty()) {
|
||||
readFirmwareFromRadio(fileName);
|
||||
}
|
||||
@@ -944,6 +1205,7 @@ void MainWindow::updateMenus()
|
||||
readEepromAct->setEnabled(true);
|
||||
writeBUToRadioAct->setEnabled(true);
|
||||
readBUToFileAct->setEnabled(true);
|
||||
editSplashAct->setDisabled(IS_HORUS(getCurrentBoard()));
|
||||
|
||||
foreach (QAction * act, fileWindowActions) {
|
||||
if (!act)
|
||||
|
||||
@@ -54,6 +54,7 @@ class MainWindow : public QMainWindow
|
||||
|
||||
signals:
|
||||
void firmwareChanged();
|
||||
void startSync();
|
||||
|
||||
protected:
|
||||
QString getCompanionUpdateBaseUrl();
|
||||
|
||||
@@ -702,7 +702,7 @@ void MdiChild::onFirmwareChanged()
|
||||
Firmware * previous = firmware;
|
||||
firmware = getCurrentFirmware();
|
||||
//qDebug() << "onFirmwareChanged" << previous->getName() << "=>" << firmware->getName();
|
||||
if (previous->getBoard() != firmware->getBoard()) {
|
||||
if (StorageFormat::getFourCC(previous->getBoard()) != StorageFormat::getFourCC(firmware->getBoard())) {
|
||||
convertStorage(previous->getBoard(), firmware->getBoard());
|
||||
setModified();
|
||||
}
|
||||
@@ -1414,11 +1414,11 @@ void MdiChild::setCurrentFile(const QString & fileName)
|
||||
isUntitled = false;
|
||||
setWindowModified(false);
|
||||
updateTitle();
|
||||
int MaxRecentFiles = g.historySize();
|
||||
|
||||
QStringList files = g.recentFiles();
|
||||
files.removeAll(fileName);
|
||||
files.prepend(fileName);
|
||||
while (files.size() > MaxRecentFiles)
|
||||
files.removeAll(curFile);
|
||||
files.prepend(curFile);
|
||||
while (files.size() > g.historySize())
|
||||
files.removeLast();
|
||||
g.recentFiles(files);
|
||||
}
|
||||
@@ -1480,7 +1480,7 @@ void MdiChild::writeEeprom() // write to Tx
|
||||
|
||||
bool MdiChild::loadBackup()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g.eepromDir(), tr(EEPROM_FILES_FILTER));
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Open backup Models and Settings file"), g.eepromDir(), EEPROM_FILES_FILTER);
|
||||
if (fileName.isEmpty())
|
||||
return false;
|
||||
QFile file(fileName);
|
||||
|
||||
@@ -12,9 +12,11 @@ set(modeledit_NAMES
|
||||
telemetry
|
||||
expodialog
|
||||
mixerdialog
|
||||
checklistdialog
|
||||
)
|
||||
|
||||
set(modeledit_SRCS
|
||||
switchitemmodel.cpp
|
||||
flightmodes.cpp
|
||||
inputs.cpp
|
||||
mixes.cpp
|
||||
|
||||
@@ -156,7 +156,7 @@ Channels::Channels(QWidget * parent, ModelData & model, GeneralSettings & genera
|
||||
curveCB->setProperty("index", i);
|
||||
int numcurves = firmware->getCapability(NumCurves);
|
||||
for (int j=-numcurves; j<=numcurves; j++) {
|
||||
curveCB->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(), j);
|
||||
curveCB->addItem(CurveReference(CurveReference::CURVE_REF_CUSTOM, j).toString(&model, false), j);
|
||||
}
|
||||
curveCB->setCurrentIndex(model.limitData[i].curve.value+numcurves);
|
||||
connect(curveCB, SIGNAL(currentIndexChanged(int)), this, SLOT(curveEdited()));
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "checklistdialog.h"
|
||||
#include "ui_checklistdialog.h"
|
||||
|
||||
#include "appdata.h"
|
||||
#include "helpers.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
extern AppData g;
|
||||
|
||||
ChecklistDialog::ChecklistDialog(QWidget *parent, const QString modelName):
|
||||
QDialog(parent),
|
||||
ui(new Ui::ChecklistDialog),
|
||||
mDirty(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(CompanionIcon("edit.png"));
|
||||
|
||||
mChecklistFolder = g.profile[g.id()].sdPath() + "/MODELS/";
|
||||
QString name = modelName;
|
||||
name.replace(" ", "_");
|
||||
mModelChecklist = QDir::toNativeSeparators(mChecklistFolder + name + ".txt");
|
||||
ui->file->setText("File: " + mModelChecklist);
|
||||
ui->pteCheck->setPlainText(readFile(mModelChecklist,QFile::exists(mModelChecklist)));
|
||||
|
||||
connect(ui->pteCheck, SIGNAL(textChanged()), this, SLOT(changed()));
|
||||
connect(ui->pbImport, SIGNAL(clicked()), this, SLOT(import()));
|
||||
connect(ui->pbCancel, SIGNAL(clicked()), this, SLOT(reject()));
|
||||
connect(ui->pbOK, SIGNAL(clicked()), this, SLOT(update()));
|
||||
}
|
||||
|
||||
ChecklistDialog::~ChecklistDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void ChecklistDialog::changed()
|
||||
{
|
||||
mDirty = true;
|
||||
}
|
||||
|
||||
void ChecklistDialog::import()
|
||||
{
|
||||
QString filename = QFileDialog::getOpenFileName(this, tr("Open Checklist"), mChecklistFolder, tr("Checklist Files (*.txt)"));
|
||||
if (!filename.isNull())
|
||||
ui->pteCheck->setPlainText(readFile(filename,true));
|
||||
mDirty = true;
|
||||
}
|
||||
|
||||
void ChecklistDialog::update()
|
||||
{
|
||||
if (mDirty) {
|
||||
QFile file(mModelChecklist);
|
||||
if (!file.open(QFile::WriteOnly | QFile::Text)) {
|
||||
QMessageBox::critical(this, tr("Model Checklist"), tr("Cannot open file for writing %1:\n%2.").arg(mModelChecklist, file.errorString()));
|
||||
}
|
||||
else {
|
||||
QTextStream out(&file);
|
||||
if (out.status()==QTextStream::Ok) {
|
||||
out << ui->pteCheck->toPlainText();
|
||||
if (!(out.status()==QTextStream::Ok)) {
|
||||
QMessageBox::critical(this, tr("Model Checklist"), tr("Cannot write to file %1:\n%2.").arg(mModelChecklist, file.errorString()));
|
||||
if (!file.flush()) {
|
||||
QMessageBox::critical(this, tr("Model Checklist"), tr("Cannot write file %1:\n%2.").arg(mModelChecklist, file.errorString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
emit accept();
|
||||
}
|
||||
|
||||
QString ChecklistDialog::readFile(const QString & filepath, const bool exists)
|
||||
{
|
||||
QString data = "";
|
||||
if (!filepath.isNull()) {
|
||||
QFile file(filepath);
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
if (exists) {
|
||||
QMessageBox::critical(this, tr("Model Checklist"), tr("Cannot open file %1:\n%2.").arg(QDir::toNativeSeparators(filepath), file.errorString()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
QTextStream in(&file);
|
||||
if (in.status()==QTextStream::Ok) {
|
||||
data = in.readAll();
|
||||
if (!(in.status()==QTextStream::Ok)) {
|
||||
QMessageBox::critical(this, tr("Model Checklist"), tr("Cannot read file %1:\n%2.").arg(QDir::toNativeSeparators(filepath), file.errorString()));
|
||||
data = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) OpenTX
|
||||
*
|
||||
* Based on code named
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CHECKLISTDIALOG_H_
|
||||
#define _CHECKLISTDIALOG_H_
|
||||
|
||||
#include <QtWidgets>
|
||||
|
||||
namespace Ui {
|
||||
class ChecklistDialog;
|
||||
}
|
||||
|
||||
class ChecklistDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChecklistDialog(QWidget *parent, const QString modelName);
|
||||
~ChecklistDialog();
|
||||
|
||||
private slots:
|
||||
void import();
|
||||
void update();
|
||||
void changed();
|
||||
|
||||
private:
|
||||
Ui::ChecklistDialog *ui;
|
||||
QString mModelChecklist;
|
||||
QString mChecklistFolder;
|
||||
QString readFile(const QString & filepath, const bool exists);
|
||||
bool mDirty;
|
||||
};
|
||||
|
||||
#endif // _CHECKLISTDIALOG_H_
|
||||
@@ -0,0 +1,156 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ChecklistDialog</class>
|
||||
<widget class="QDialog" name="ChecklistDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>630</width>
|
||||
<height>373</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Edit Checklist</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>3</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPlainTextEdit" name="pteCheck">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
<property name="tabChangesFocus">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="lineWrapMode">
|
||||
<enum>QPlainTextEdit::NoWrap</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMinimumSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbImport">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Import...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbCancel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbOK">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&OK</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Please note, the maximum width displayable is radio model limited. Also, renaming the model will break the link to this checklist file.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="file">
|
||||
<property name="text">
|
||||
<string>File: unknown</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>pteCheck</tabstop>
|
||||
<tabstop>pbOK</tabstop>
|
||||
<tabstop>pbCancel</tabstop>
|
||||
<tabstop>pbImport</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -143,8 +143,10 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
|
||||
palette.setBrush(QPalette::Active, QPalette::ButtonText, QBrush(Qt::white));
|
||||
#ifdef __APPLE__
|
||||
edit->setStyleSheet(QString("color: %1;").arg(colors[i].name()));
|
||||
#else
|
||||
#elif defined WIN32 || !defined __GNUC__
|
||||
edit->setStyleSheet(QString("background-color: %1; color: white;").arg(colors[i].name()));
|
||||
#else
|
||||
edit->setStyleSheet(QString("background-color: %1; color: white; padding: 2px 3px; border-style: outset; border-width: 1px; border-radius: 2px; border-color: inherit;").arg(colors[i].name()));
|
||||
#endif
|
||||
edit->setPalette(palette);
|
||||
edit->setText(tr("Curve %1").arg(i+1));
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "customfunctions.h"
|
||||
#include "switchitemmodel.h"
|
||||
#include "helpers.h"
|
||||
#include "appdata.h"
|
||||
|
||||
@@ -73,8 +74,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
|
||||
lock = true;
|
||||
int num_fsw = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions);
|
||||
|
||||
rawSwitchItemModel = Helpers::getRawSwitchItemModel(&generalSettings, model ? Helpers::SpecialFunctionsContext : Helpers::GlobalFunctionsContext);
|
||||
rawSwitchItemModel->setParent(this);
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, model, model ? SpecialFunctionsContext : GlobalFunctionsContext);
|
||||
rawSrcInputsItemModel = Helpers::getRawSourceItemModel(&generalSettings, model, POPULATE_NONE|POPULATE_SOURCES|POPULATE_VIRTUAL_INPUTS|POPULATE_TRIMS|POPULATE_SWITCHES);
|
||||
rawSrcInputsItemModel->setParent(this);
|
||||
rawSrcAllItemModel = Helpers::getRawSourceItemModel(&generalSettings, model, POPULATE_NONE|POPULATE_SOURCES|POPULATE_VIRTUAL_INPUTS|POPULATE_SWITCHES|POPULATE_GVARS|POPULATE_TRIMS|POPULATE_TELEMETRY|POPULATE_TELEMETRYEXT|POPULATE_SCRIPT_OUTPUTS);
|
||||
@@ -337,6 +337,7 @@ void CustomFunctionsPanel::playMusic()
|
||||
#define CUSTOM_FUNCTION_REPEAT (1<<7)
|
||||
#define CUSTOM_FUNCTION_PLAY (1<<8)
|
||||
#define CUSTOM_FUNCTION_BL_COLOR (1<<9)
|
||||
#define CUSTOM_FUNCTION_SHOW_FUNC (1<<10)
|
||||
|
||||
void CustomFunctionsPanel::customFunctionEdited()
|
||||
{
|
||||
@@ -357,7 +358,7 @@ void CustomFunctionsPanel::functionEdited()
|
||||
RawSwitch swtch = functions[index].swtch;
|
||||
functions[index].clear();
|
||||
functions[index].swtch = swtch;
|
||||
functions[index].func = (AssignFunc)fswtchFunc[index]->itemData(fswtchFunc[index]->currentIndex()).toInt();
|
||||
functions[index].func = (AssignFunc)fswtchFunc[index]->currentData().toInt();
|
||||
refreshCustomFunction(index);
|
||||
emit modified();
|
||||
lock = false;
|
||||
@@ -382,7 +383,8 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
cfn.adjustMode = (AssignFunc)fswtchGVmode[i]->currentIndex();
|
||||
}
|
||||
|
||||
if (cfn.swtch.toValue()) {
|
||||
if (!cfn.isEmpty()) {
|
||||
widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC;
|
||||
|
||||
if (func>=FuncOverrideCH1 && func<=FuncOverrideCH32) {
|
||||
if (model) {
|
||||
@@ -395,7 +397,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
cfn.param = fswtchParam[i]->value();
|
||||
}
|
||||
fswtchParam[i]->setValue(cfn.param);
|
||||
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_ENABLE;
|
||||
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_ENABLE;
|
||||
}
|
||||
}
|
||||
else if (func==FuncLogs) {
|
||||
@@ -409,23 +411,28 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
|
||||
}
|
||||
else if (func>=FuncAdjustGV1 && func<=FuncAdjustGVLast) {
|
||||
int gvidx = func - FuncAdjustGV1;
|
||||
if (modified)
|
||||
cfn.adjustMode = fswtchGVmode[i]->currentIndex();
|
||||
widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE;
|
||||
if (cfn.adjustMode==FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode==FUNC_ADJUST_GVAR_INCDEC) {
|
||||
if (modified)
|
||||
cfn.param = fswtchParam[i]->value();
|
||||
fswtchParam[i]->setDecimals(0);
|
||||
fswtchParam[i]->setSingleStep(1);
|
||||
cfn.param = fswtchParam[i]->value() * model->gvarData[gvidx].multiplierSet();
|
||||
if (IS_ARM(getCurrentBoard())) {
|
||||
fswtchParam[i]->setMinimum(-500);
|
||||
fswtchParam[i]->setMaximum(500);
|
||||
fswtchParam[i]->setDecimals(model->gvarData[gvidx].prec);
|
||||
fswtchParam[i]->setSingleStep(model->gvarData[gvidx].multiplierGet());
|
||||
fswtchParam[i]->setSuffix(model->gvarData[gvidx].unitToString());
|
||||
fswtchParam[i]->setMinimum(model->gvarData[gvidx].getMinPrec());
|
||||
fswtchParam[i]->setMaximum(model->gvarData[gvidx].getMaxPrec());
|
||||
fswtchParam[i]->setValue(cfn.param * model->gvarData[gvidx].multiplierGet());
|
||||
}
|
||||
else {
|
||||
fswtchParam[i]->setDecimals(0);
|
||||
fswtchParam[i]->setSingleStep(1);
|
||||
fswtchParam[i]->setMinimum(-125);
|
||||
fswtchParam[i]->setMaximum(125);
|
||||
fswtchParam[i]->setValue(cfn.param);
|
||||
}
|
||||
fswtchParam[i]->setValue(cfn.param);
|
||||
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM;
|
||||
}
|
||||
else {
|
||||
@@ -456,7 +463,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
if (modified)
|
||||
cfn.param = fswtchParamT[i]->currentData().toInt();
|
||||
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
|
||||
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM + CUSTOM_FUNCTION_ENABLE;
|
||||
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE;
|
||||
}
|
||||
else if (func==FuncPlaySound || func==FuncPlayHaptic || func==FuncPlayValue || func==FuncPlayPrompt || func==FuncPlayBoth || func==FuncBackgroundMusic) {
|
||||
if (func != FuncBackgroundMusic) {
|
||||
@@ -467,7 +474,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
if (modified)
|
||||
cfn.param = fswtchParamT[i]->currentData().toInt();
|
||||
populateFuncParamCB(fswtchParamT[i], func, cfn.param);
|
||||
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM + CUSTOM_FUNCTION_REPEAT;
|
||||
widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_REPEAT;
|
||||
}
|
||||
else if (func==FuncPlayPrompt || func==FuncPlayBoth) {
|
||||
if (firmware->getCapability(VoicesAsNumbers)) {
|
||||
@@ -475,10 +482,10 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
fswtchParam[i]->setSingleStep(1);
|
||||
fswtchParam[i]->setMinimum(0);
|
||||
if (func==FuncPlayPrompt) {
|
||||
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_REPEAT + CUSTOM_FUNCTION_GV_TOOGLE;
|
||||
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT | CUSTOM_FUNCTION_GV_TOOGLE;
|
||||
}
|
||||
else {
|
||||
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_REPEAT;
|
||||
widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_REPEAT;
|
||||
fswtchParamGV[i]->setChecked(false);
|
||||
}
|
||||
fswtchParam[i]->setMaximum(func==FuncPlayBoth ? 254 : 255);
|
||||
@@ -563,7 +570,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
|
||||
}
|
||||
|
||||
fswtchFunc[i]->setVisible(cfn.swtch.toValue());
|
||||
fswtchFunc[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SHOW_FUNC);
|
||||
fswtchParam[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_NUMERIC_PARAM);
|
||||
fswtchParamTime[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_TIME_PARAM);
|
||||
fswtchParamGV[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_TOOGLE);
|
||||
@@ -582,6 +589,8 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
|
||||
|
||||
void CustomFunctionsPanel::update()
|
||||
{
|
||||
rawSwitchItemModel->update();
|
||||
|
||||
lock = true;
|
||||
int num_fsw = model ? firmware->getCapability(CustomFunctions) : firmware->getCapability(GlobalFunctions);
|
||||
for (int i=0; i<num_fsw; i++) {
|
||||
@@ -599,9 +608,8 @@ void CustomFunctionsPanel::fswPaste()
|
||||
CustomFunctionData *fsw = &functions[selectedFunction];
|
||||
memcpy(fsw, fswData.constData(), sizeof(CustomFunctionData));
|
||||
lock = true;
|
||||
fswtchSwtch[selectedFunction]->setModel(rawSwitchItemModel);
|
||||
fswtchSwtch[selectedFunction]->setCurrentIndex(fswtchSwtch[selectedFunction]->findData(functions[selectedFunction].swtch.toValue()));
|
||||
populateFuncCB(fswtchFunc[selectedFunction], functions[selectedFunction].func);
|
||||
fswtchFunc[selectedFunction]->setCurrentIndex(fswtchFunc[selectedFunction]->findData(functions[selectedFunction].func));
|
||||
populateGVmodeCB(fswtchGVmode[selectedFunction], functions[selectedFunction].adjustMode);
|
||||
populateFuncParamCB(fswtchParamT[selectedFunction], functions[selectedFunction].func, functions[selectedFunction].param, functions[selectedFunction].adjustMode);
|
||||
refreshCustomFunction(selectedFunction);
|
||||
@@ -615,9 +623,8 @@ void CustomFunctionsPanel::fswDelete()
|
||||
functions[selectedFunction].clear();
|
||||
// TODO update switch and func
|
||||
lock = true;
|
||||
fswtchSwtch[selectedFunction]->setModel(rawSwitchItemModel);
|
||||
fswtchSwtch[selectedFunction]->setCurrentIndex(fswtchSwtch[selectedFunction]->findData(functions[selectedFunction].swtch.toValue()));
|
||||
populateFuncCB(fswtchFunc[selectedFunction], functions[selectedFunction].func);
|
||||
fswtchFunc[selectedFunction]->setCurrentIndex(fswtchFunc[selectedFunction]->findData(functions[selectedFunction].func));
|
||||
refreshCustomFunction(selectedFunction);
|
||||
lock = false;
|
||||
emit modified();
|
||||
@@ -650,10 +657,10 @@ void CustomFunctionsPanel::fsw_customContextMenuRequested(QPoint pos)
|
||||
bool hasData = mimeData->hasFormat("application/x-companion-fsw");
|
||||
|
||||
QMenu contextMenu;
|
||||
contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(fswCopy()),tr("Ctrl+C"));
|
||||
contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(fswCut()),tr("Ctrl+X"));
|
||||
contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(fswPaste()),tr("Ctrl+V"))->setEnabled(hasData);
|
||||
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(fswDelete()),tr("Delete"));
|
||||
contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(fswCopy()));
|
||||
contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(fswCut()));
|
||||
contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(fswPaste()))->setEnabled(hasData);
|
||||
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(fswDelete()));
|
||||
|
||||
contextMenu.exec(globalPos);
|
||||
}
|
||||
@@ -668,19 +675,17 @@ void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value)
|
||||
((i==FuncPlayHaptic) && !firmware->getCapability(Haptic)) ||
|
||||
((i==FuncPlayBoth) && !firmware->getCapability(HasBeeper)) ||
|
||||
((i==FuncLogs) && !firmware->getCapability(HasSDLogs)) ||
|
||||
((i==FuncSetTimer1 || i==FuncSetTimer2) && !IS_ARM(firmware->getBoard())) ||
|
||||
((i==FuncSetTimer3) && firmware->getCapability(Timers) < 3) ||
|
||||
((i==FuncScreenshot) && IS_HORUS(firmware->getBoard())) ||
|
||||
((i==FuncScreenshot) && !IS_TARANIS(firmware->getBoard())) ||
|
||||
((i>=FuncRangeCheckInternalModule && i<=FuncBindExternalModule) && (!model || !firmware->getCapability(DangerousFunctions))) ||
|
||||
((i>=FuncAdjustGV1 && i<=FuncAdjustGVLast) && !firmware->getCapability(Gvars))
|
||||
((i>=FuncAdjustGV1 && i<=FuncAdjustGVLast) && (!model || !firmware->getCapability(Gvars)))
|
||||
) {
|
||||
// skipped
|
||||
// b->addItem(CustomFunctionData(AssignFunc(i)).funcToString(), i);
|
||||
// QModelIndex index = b->model()->index(i, 0);
|
||||
// QVariant v(0);
|
||||
// b->model()->setData(index, v, Qt::UserRole - 1);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
b->addItem(CustomFunctionData(AssignFunc(i)).funcToString(), i);
|
||||
b->addItem(CustomFunctionData(AssignFunc(i)).funcToString(model), i);
|
||||
if (i == value) {
|
||||
b->setCurrentIndex(b->count()-1);
|
||||
}
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
#ifndef _CUSTOMFUNCTIONS_H_
|
||||
#define _CUSTOMFUNCTIONS_H_
|
||||
|
||||
#include <QMediaPlayer>
|
||||
#include "modeledit.h"
|
||||
#include "eeprominterface.h"
|
||||
#include <QMediaPlayer>
|
||||
|
||||
class RawSwitchFilterItemModel;
|
||||
|
||||
class RepeatComboBox: public QComboBox
|
||||
{
|
||||
@@ -74,7 +76,7 @@ class CustomFunctionsPanel : public GenericPanel
|
||||
void populateFuncCB(QComboBox *b, unsigned int value);
|
||||
void populateGVmodeCB(QComboBox *b, unsigned int value);
|
||||
void populateFuncParamCB(QComboBox *b, uint function, unsigned int value, unsigned int adjustmode=0);
|
||||
QStandardItemModel * rawSwitchItemModel;
|
||||
RawSwitchFilterItemModel * rawSwitchItemModel;
|
||||
QStandardItemModel * rawSrcInputsItemModel;
|
||||
QStandardItemModel * rawSrcAllItemModel;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "expodialog.h"
|
||||
#include "ui_expodialog.h"
|
||||
#include "switchitemmodel.h"
|
||||
#include "helpers.h"
|
||||
|
||||
ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, GeneralSettings & generalSettings,
|
||||
@@ -41,10 +42,11 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
|
||||
cb_fp[i] = tmp[i];
|
||||
}
|
||||
|
||||
setWindowTitle(tr("Edit %1").arg(modelPrinter.printInputName(ed->chn)));
|
||||
RawSourceType srcType = (firmware->getCapability(VirtualInputs) ? SOURCE_TYPE_VIRTUAL_INPUT : SOURCE_TYPE_STICK);
|
||||
setWindowTitle(tr("Edit %1").arg(RawSource(srcType, ed->chn).toString(&model, &generalSettings)));
|
||||
QRegExp rx(CHAR_FOR_NAMES_REGEX);
|
||||
|
||||
if (IS_HORUS_OR_TARANIS(getCurrentBoard())) {
|
||||
if (IS_ARM(getCurrentBoard())) {
|
||||
gvWeightGroup = new GVarGroup(ui->weightGV, ui->weightSB, ui->weightCB, ed->weight, model, 100, -100, 100);
|
||||
gvOffsetGroup = new GVarGroup(ui->offsetGV, ui->offsetSB, ui->offsetCB, ed->offset, model, 0, -100, 100);
|
||||
}
|
||||
@@ -60,7 +62,7 @@ ExpoDialog::ExpoDialog(QWidget *parent, ModelData & model, ExpoData *expoData, G
|
||||
curveGroup = new CurveGroup(ui->curveTypeCB, ui->curveGVarCB, ui->curveValueCB, ui->curveValueSB, ed->curve, model,
|
||||
firmware->getCapability(HasInputDiff) ? 0 : (HIDE_DIFF | HIDE_NEGATIVE_CURVES));
|
||||
|
||||
ui->switchesCB->setModel(Helpers::getRawSwitchItemModel(&generalSettings, Helpers::MixesContext));
|
||||
ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, MixesContext));
|
||||
ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(ed->swtch.toValue()));
|
||||
|
||||
ui->sideCB->setCurrentIndex(ed->mode-1);
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
|
||||
#include "flightmodes.h"
|
||||
#include "ui_flightmode.h"
|
||||
#include "switchitemmodel.h"
|
||||
#include "helpers.h"
|
||||
#include "customdebug.h"
|
||||
|
||||
FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseIdx, GeneralSettings & generalSettings, Firmware * firmware):
|
||||
ModelPanel(parent, model, generalSettings, firmware),
|
||||
@@ -28,7 +30,8 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI
|
||||
phaseIdx(phaseIdx),
|
||||
phase(model.flightModeData[phaseIdx]),
|
||||
reCount(firmware->getCapability(RotaryEncoders)),
|
||||
gvCount(firmware->getCapability(Gvars))
|
||||
gvCount(firmware->getCapability(Gvars)),
|
||||
rawSwitchItemModel(NULL)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@@ -50,7 +53,8 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI
|
||||
|
||||
// Phase switch
|
||||
if (phaseIdx > 0) {
|
||||
ui->swtch->setModel(Helpers::getRawSwitchItemModel(&generalSettings, Helpers::MixesContext));
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, MixesContext);
|
||||
ui->swtch->setModel(rawSwitchItemModel);
|
||||
ui->swtch->setCurrentIndex(ui->swtch->findData(phase.swtch.toValue()));
|
||||
connect(ui->swtch, SIGNAL(currentIndexChanged(int)), this, SLOT(phaseSwitch_currentIndexChanged(int)));
|
||||
}
|
||||
@@ -153,26 +157,56 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI
|
||||
// GVars
|
||||
if (gvCount > 0 && (firmware->getCapability(GvarsFlightModes) || phaseIdx == 0) ) {
|
||||
QGridLayout *gvLayout = new QGridLayout(ui->gvGB);
|
||||
|
||||
|
||||
// Column headers
|
||||
int headerCol = 1;
|
||||
QLabel *nameLabel = new QLabel(ui->gvGB);
|
||||
nameLabel->setText(tr("Name"));
|
||||
gvLayout->addWidget(nameLabel, 0, headerCol++, 1, 1);
|
||||
|
||||
if (firmware->getCapability(GvarsName)) {
|
||||
QLabel *nameLabel = new QLabel(ui->gvGB);
|
||||
nameLabel->setText(tr("Name"));
|
||||
gvLayout->addWidget(nameLabel, 0, headerCol++, 1, 1);
|
||||
}
|
||||
|
||||
if (phaseIdx > 0) {
|
||||
QLabel *sourceLabel = new QLabel(ui->gvGB);
|
||||
sourceLabel->setText(tr("Value source"));
|
||||
gvLayout->addWidget(sourceLabel, 0, headerCol++, 1, 1);
|
||||
}
|
||||
|
||||
QLabel *valueLabel = new QLabel(ui->gvGB);
|
||||
valueLabel->setText(tr("Value"));
|
||||
gvLayout->addWidget(valueLabel, 0, headerCol++, 1, 1);
|
||||
|
||||
|
||||
if (IS_HORUS_OR_TARANIS(board) && phaseIdx == 0) {
|
||||
QLabel *unitLabel = new QLabel(ui->gvGB);
|
||||
unitLabel->setText(tr("Unit"));
|
||||
gvLayout->addWidget(unitLabel, 0, headerCol++, 1, 1);
|
||||
|
||||
QLabel *precLabel = new QLabel(ui->gvGB);
|
||||
precLabel->setText(tr("Prec"));
|
||||
gvLayout->addWidget(precLabel, 0, headerCol++, 1, 1);
|
||||
|
||||
QLabel *minLabel = new QLabel(ui->gvGB);
|
||||
minLabel->setText(tr("Min"));
|
||||
gvLayout->addWidget(minLabel, 0, headerCol++, 1, 1);
|
||||
|
||||
QLabel *maxLabel = new QLabel(ui->gvGB);
|
||||
maxLabel->setText(tr("Max"));
|
||||
gvLayout->addWidget(maxLabel, 0, headerCol++, 1, 1);
|
||||
|
||||
QLabel *popupLabel = new QLabel(ui->gvGB);
|
||||
popupLabel->setText(tr("Popup enabled"));
|
||||
gvLayout->addWidget(popupLabel, 0, headerCol++, 1, 1);
|
||||
}
|
||||
|
||||
for (int i=0; i<gvCount; i++) {
|
||||
int col = 0;
|
||||
// GVar label
|
||||
QLabel *label = new QLabel(ui->gvGB);
|
||||
label->setText(tr("GVAR%1").arg(i+1));
|
||||
label->setProperty("index", i);
|
||||
label->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(label, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(gvLabel_customContextMenuRequested(const QPoint &)));
|
||||
gvLayout->addWidget(label, i+1, col++, 1, 1);
|
||||
// GVar name
|
||||
int nameLen = firmware->getCapability(GvarsName);
|
||||
@@ -188,25 +222,49 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI
|
||||
gvUse[i] = new QComboBox(ui->gvGB);
|
||||
gvUse[i]->setProperty("index", i);
|
||||
Helpers::populateGvarUseCB(gvUse[i], phaseIdx);
|
||||
if (phase.gvars[i] > 1024) {
|
||||
gvUse[i]->setCurrentIndex(phase.gvars[i] - 1024);
|
||||
if (phase.gvars[i] > GVAR_MAX_VALUE) {
|
||||
gvUse[i]->setCurrentIndex(phase.gvars[i] - GVAR_MAX_VALUE);
|
||||
}
|
||||
connect(gvUse[i], SIGNAL(currentIndexChanged(int)), this, SLOT(phaseGVUse_currentIndexChanged(int)));
|
||||
gvLayout->addWidget(gvUse[i], i+1, col++, 1, 1);
|
||||
}
|
||||
// GVar value
|
||||
gvValues[i] = new QSpinBox(ui->gvGB);
|
||||
gvValues[i] = new QDoubleSpinBox(ui->gvGB);
|
||||
gvValues[i]->setProperty("index", i);
|
||||
connect(gvValues[i], SIGNAL(editingFinished()), this, SLOT(phaseGVValue_editingFinished()));
|
||||
gvValues[i]->setMinimum(-1024);
|
||||
gvValues[i]->setMaximum(1024);
|
||||
gvLayout->addWidget(gvValues[i], i+1, col++, 1, 1);
|
||||
|
||||
// Popups
|
||||
if (IS_TARANIS(board) && phaseIdx == 0) {
|
||||
if (IS_HORUS_OR_TARANIS(board) && phaseIdx == 0) {
|
||||
// GVar unit
|
||||
gvUnit[i] = new QComboBox(ui->gvGB);
|
||||
gvUnit[i]->setProperty("index", i);
|
||||
populateGvarUnitCB(gvUnit[i]);
|
||||
connect(gvUnit[i], SIGNAL(currentIndexChanged(int)), this, SLOT(phaseGVUnit_currentIndexChanged(int)));
|
||||
gvLayout->addWidget(gvUnit[i], i+1, col++, 1, 1);
|
||||
|
||||
// GVar precision
|
||||
gvPrec[i] = new QComboBox(ui->gvGB);
|
||||
gvPrec[i]->setProperty("index", i);
|
||||
populateGvarPrecCB(gvPrec[i]);
|
||||
connect(gvPrec[i], SIGNAL(currentIndexChanged(int)), this, SLOT(phaseGVPrec_currentIndexChanged(int)));
|
||||
gvLayout->addWidget(gvPrec[i], i+1, col++, 1, 1);
|
||||
|
||||
// GVar min
|
||||
gvMin[i] = new QDoubleSpinBox(ui->gvGB);
|
||||
gvMin[i]->setProperty("index", i);
|
||||
connect(gvMin[i], SIGNAL(editingFinished()), this, SLOT(phaseGVMin_editingFinished()));
|
||||
gvLayout->addWidget(gvMin[i], i+1, col++, 1, 1);
|
||||
|
||||
// GVar max
|
||||
gvMax[i] = new QDoubleSpinBox(ui->gvGB);
|
||||
gvMax[i]->setProperty("index", i);
|
||||
connect(gvMax[i], SIGNAL(editingFinished()), this, SLOT(phaseGVMax_editingFinished()));
|
||||
gvLayout->addWidget(gvMax[i], i+1, col++, 1, 1);
|
||||
|
||||
// Popups
|
||||
gvPopups[i] = new QCheckBox(ui->gvGB);
|
||||
gvPopups[i]->setProperty("index", i);
|
||||
gvPopups[i]->setText(tr("Popup enabled"));
|
||||
//gvPopups[i]->setText(tr("Popup enabled"));
|
||||
connect(gvPopups[i], SIGNAL(toggled(bool)), this, SLOT(phaseGVPopupToggled(bool)));
|
||||
gvLayout->addWidget(gvPopups[i], i+1, col++, 1, 1);
|
||||
}
|
||||
@@ -214,6 +272,7 @@ FlightModePanel::FlightModePanel(QWidget * parent, ModelData & model, int phaseI
|
||||
}
|
||||
else {
|
||||
ui->gvGB->hide();
|
||||
gvCount = 0;
|
||||
}
|
||||
|
||||
disableMouseScrolling();
|
||||
@@ -228,6 +287,10 @@ FlightModePanel::~FlightModePanel()
|
||||
|
||||
void FlightModePanel::update()
|
||||
{
|
||||
if (rawSwitchItemModel) {
|
||||
rawSwitchItemModel->update();
|
||||
}
|
||||
|
||||
ui->name->setText(phase.name);
|
||||
|
||||
int scale = firmware->getCapability(SlowScale);
|
||||
@@ -247,17 +310,8 @@ void FlightModePanel::update()
|
||||
trimUpdate(i);
|
||||
}
|
||||
|
||||
if (ui->gvGB->isVisible()) {
|
||||
for (int i=0; i<gvCount; i++) {
|
||||
if (firmware->getCapability(GvarsName) > 0) {
|
||||
gvNames[i]->setText(model->gvars_names[i]);
|
||||
}
|
||||
gvValues[i]->setDisabled(model->isGVarLinked(phaseIdx, i));
|
||||
gvValues[i]->setValue(model->getGVarFieldValue(phaseIdx, i));
|
||||
if (IS_TARANIS(getCurrentBoard()) && phaseIdx == 0) {
|
||||
gvPopups[i]->setChecked(model->gvars_popups[i]);
|
||||
}
|
||||
}
|
||||
for (int i=0; i<gvCount; i++) {
|
||||
updateGVar(i);
|
||||
}
|
||||
|
||||
for (int i=0; i<reCount; i++) {
|
||||
@@ -274,6 +328,49 @@ void FlightModePanel::update()
|
||||
reValues[i]->setValue(phasere->rotaryEncoders[i]);
|
||||
}
|
||||
}
|
||||
void FlightModePanel::updateGVar(int index)
|
||||
{
|
||||
lock = true;
|
||||
if (firmware->getCapability(GvarsName) > 0) {
|
||||
gvNames[index]->setText(model->gvarData[index].name);
|
||||
}
|
||||
gvValues[index]->setDisabled(model->isGVarLinked(phaseIdx, index));
|
||||
setGVSB(gvValues[index], model->gvarData[index].getMin(), model->gvarData[index].getMax(), model->getGVarFieldValue(phaseIdx, index));
|
||||
if (IS_HORUS_OR_TARANIS(getCurrentBoard()) && phaseIdx == 0) {
|
||||
gvUnit[index]->setCurrentIndex(model->gvarData[index].unit);
|
||||
gvPrec[index]->setCurrentIndex(model->gvarData[index].prec);
|
||||
setGVSB(gvMin[index], GVAR_MIN_VALUE, model->gvarData[index].getMax(), model->gvarData[index].getMin());
|
||||
setGVSB(gvMax[index], model->gvarData[index].getMin(), GVAR_MAX_VALUE, model->gvarData[index].getMax());
|
||||
gvPopups[index]->setChecked(model->gvarData[index].popup);
|
||||
}
|
||||
lock = false;
|
||||
}
|
||||
|
||||
void FlightModePanel::setGVSB(QDoubleSpinBox * sb, int min, int max, int val)
|
||||
{
|
||||
int idx = sb->property("index").toInt();
|
||||
float mul = model->gvarData[idx].multiplierGet();
|
||||
sb->setDecimals(model->gvarData[idx].prec);
|
||||
sb->setSingleStep(mul);
|
||||
sb->setSuffix(model->gvarData[idx].unitToString());
|
||||
sb->setMinimum(min * mul);
|
||||
sb->setMaximum(max * mul);
|
||||
sb->setValue(val * mul);
|
||||
}
|
||||
|
||||
void FlightModePanel::populateGvarUnitCB(QComboBox * cb)
|
||||
{
|
||||
cb->clear();
|
||||
cb->addItem(QObject::tr(""));
|
||||
cb->addItem(QObject::tr("%"));
|
||||
}
|
||||
|
||||
void FlightModePanel::populateGvarPrecCB(QComboBox * cb)
|
||||
{
|
||||
cb->clear();
|
||||
cb->addItem(QObject::tr("0._"));
|
||||
cb->addItem(QObject::tr("0.0"));
|
||||
}
|
||||
|
||||
void FlightModePanel::phaseName_editingFinished()
|
||||
{
|
||||
@@ -341,9 +438,9 @@ void FlightModePanel::trimUpdate(unsigned int trim)
|
||||
void FlightModePanel::phaseGVValue_editingFinished()
|
||||
{
|
||||
if (!lock) {
|
||||
QSpinBox *spinBox = qobject_cast<QSpinBox*>(sender());
|
||||
QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox*>(sender());
|
||||
int gvar = spinBox->property("index").toInt();
|
||||
phase.gvars[gvar] = spinBox->value();
|
||||
phase.gvars[gvar] = spinBox->value() * model->gvarData[gvar].multiplierSet();
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
@@ -353,8 +450,8 @@ void FlightModePanel::GVName_editingFinished()
|
||||
if (!lock) {
|
||||
QLineEdit *lineedit = qobject_cast<QLineEdit*>(sender());
|
||||
int gvar = lineedit->property("index").toInt();
|
||||
memset(&model->gvars_names[gvar], 0, sizeof(model->gvars_names[gvar]));
|
||||
strcpy(model->gvars_names[gvar], lineedit->text().toLatin1());
|
||||
memset(&model->gvarData[gvar].name, 0, sizeof(model->gvarData[gvar].name));
|
||||
strcpy(model->gvarData[gvar].name, lineedit->text().toLatin1());
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
@@ -369,28 +466,98 @@ void FlightModePanel::phaseGVUse_currentIndexChanged(int index)
|
||||
phase.gvars[gvar] = 0;
|
||||
}
|
||||
else {
|
||||
phase.gvars[gvar] = 1024 + index;
|
||||
phase.gvars[gvar] = GVAR_MAX_VALUE + index;
|
||||
}
|
||||
update();
|
||||
updateGVar(gvar);
|
||||
emit modified();
|
||||
lock = false;
|
||||
}
|
||||
}
|
||||
|
||||
void FlightModePanel::phaseGVUnit_currentIndexChanged(int index)
|
||||
{
|
||||
if (!lock) {
|
||||
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||
int gvar = comboBox->property("index").toInt();
|
||||
model->gvarData[gvar].unit = index;
|
||||
emit modified();
|
||||
updateGVar(gvar);
|
||||
}
|
||||
}
|
||||
|
||||
void FlightModePanel::phaseGVPrec_currentIndexChanged(int index)
|
||||
{
|
||||
if (!lock) {
|
||||
QComboBox *comboBox = qobject_cast<QComboBox*>(sender());
|
||||
int gvar = comboBox->property("index").toInt();
|
||||
model->gvarData[gvar].prec = index;
|
||||
emit modified();
|
||||
updateGVar(gvar);
|
||||
}
|
||||
}
|
||||
|
||||
void FlightModePanel::phaseGVMin_editingFinished()
|
||||
{
|
||||
if (!lock) {
|
||||
QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox*>(sender());
|
||||
int gvar = spinBox->property("index").toInt();
|
||||
model->gvarData[gvar].setMin(spinBox->value());
|
||||
if (!model->isGVarLinked(phaseIdx, gvar)) {
|
||||
if (model->getGVarFieldValuePrec(phaseIdx, gvar) < spinBox->value()) {
|
||||
phase.gvars[gvar] = model->gvarData[gvar].getMin();
|
||||
}
|
||||
}
|
||||
for (int x=1; x<firmware->getCapability(FlightModes); x++) {
|
||||
if (!model->isGVarLinked(x, gvar)) {
|
||||
if (model->flightModeData[x].gvars[gvar] < model->gvarData[gvar].getMin()) {
|
||||
model->flightModeData[x].gvars[gvar] = model->gvarData[gvar].getMin();
|
||||
}
|
||||
}
|
||||
}
|
||||
emit modified();
|
||||
updateGVar(gvar);
|
||||
}
|
||||
}
|
||||
|
||||
void FlightModePanel::phaseGVMax_editingFinished()
|
||||
{
|
||||
if (!lock) {
|
||||
QDoubleSpinBox *spinBox = qobject_cast<QDoubleSpinBox*>(sender());
|
||||
int gvar = spinBox->property("index").toInt();
|
||||
model->gvarData[gvar].setMax(spinBox->value());
|
||||
if (!model->isGVarLinked(phaseIdx, gvar)) {
|
||||
if (model->getGVarFieldValuePrec(phaseIdx, gvar) > spinBox->value()) {
|
||||
phase.gvars[gvar] = model->gvarData[gvar].getMax();
|
||||
}
|
||||
}
|
||||
for (int x=1; x<firmware->getCapability(FlightModes); x++) {
|
||||
if (!model->isGVarLinked(x, gvar)) {
|
||||
if (model->flightModeData[x].gvars[gvar] > model->gvarData[gvar].getMax()) {
|
||||
model->flightModeData[x].gvars[gvar] = model->gvarData[gvar].getMax();
|
||||
}
|
||||
}
|
||||
}
|
||||
emit modified();
|
||||
updateGVar(gvar);
|
||||
}
|
||||
}
|
||||
|
||||
void FlightModePanel::phaseGVPopupToggled(bool checked)
|
||||
{
|
||||
QCheckBox *cb = qobject_cast<QCheckBox*>(sender());
|
||||
int gvar = cb->property("index").toInt();
|
||||
model->gvars_popups[gvar] = checked;
|
||||
emit modified();
|
||||
if (!lock) {
|
||||
QCheckBox *cb = qobject_cast<QCheckBox*>(sender());
|
||||
int gvar = cb->property("index").toInt();
|
||||
model->gvarData[gvar].popup = checked;
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
void FlightModePanel::phaseREValue_editingFinished()
|
||||
{
|
||||
if (!lock) {
|
||||
QSpinBox *spinBox = qobject_cast<QSpinBox*>(sender());
|
||||
int gvar = spinBox->property("index").toInt();
|
||||
phase.rotaryEncoders[gvar] = spinBox->value();
|
||||
int re = spinBox->property("index").toInt();
|
||||
phase.rotaryEncoders[re] = spinBox->value();
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
@@ -474,11 +641,11 @@ void FlightModePanel::phaseTrimSlider_valueChanged()
|
||||
|
||||
void FlightModePanel::name_customContextMenuRequested(const QPoint & pos)
|
||||
{
|
||||
QLabel *label = (QLabel *)sender();
|
||||
QPoint globalPos = label->mapToGlobal(pos);
|
||||
QMenu contextMenu;
|
||||
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Clear"),this,SLOT(fmClear()),tr("Clear"));
|
||||
contextMenu.exec(globalPos);
|
||||
QLabel *label = (QLabel *)sender();
|
||||
QPoint globalPos = label->mapToGlobal(pos);
|
||||
QMenu contextMenu;
|
||||
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Clear"),this,SLOT(fmClear()),tr("Clear"));
|
||||
contextMenu.exec(globalPos);
|
||||
}
|
||||
|
||||
void FlightModePanel::fmClear()
|
||||
@@ -489,8 +656,7 @@ void FlightModePanel::fmClear()
|
||||
if (phaseIdx == 0) {
|
||||
if (IS_HORUS_OR_TARANIS(getCurrentBoard())) {
|
||||
for (int i=0; i < gvCount; ++i) {
|
||||
memset(&model->gvars_names[i], 0, sizeof(model->gvars_names[i]));
|
||||
model->gvars_popups[i] = 0;
|
||||
model->gvarData[i].clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -501,11 +667,11 @@ void FlightModePanel::fmClear()
|
||||
pswtch->setCurrentIndex(pswtch->findText(item.toString()));
|
||||
if (gvCount > 0 && (firmware->getCapability(GvarsFlightModes))) {
|
||||
for (int i=0; i<gvCount; i++) {
|
||||
gvUse[i]->setCurrentIndex((phase.gvars[i] > 1024 ? (phase.gvars[i] - 1024) : 0));
|
||||
gvUse[i]->setCurrentIndex((phase.gvars[i] > GVAR_MAX_VALUE ? (phase.gvars[i] - GVAR_MAX_VALUE) : 0));
|
||||
}
|
||||
}
|
||||
for (int i=0; i<reCount; i++) {
|
||||
reUse[i]->setCurrentIndex((phase.rotaryEncoders[i] > 1024 ? (phase.rotaryEncoders[i] - 1024) : 0));
|
||||
reUse[i]->setCurrentIndex((phase.rotaryEncoders[i] > GVAR_MAX_VALUE ? (phase.rotaryEncoders[i] - GVAR_MAX_VALUE) : 0));
|
||||
}
|
||||
lock = false;
|
||||
}
|
||||
@@ -515,6 +681,36 @@ void FlightModePanel::fmClear()
|
||||
}
|
||||
}
|
||||
|
||||
void FlightModePanel::gvLabel_customContextMenuRequested(const QPoint & pos)
|
||||
{
|
||||
QLabel *label = (QLabel *)sender();
|
||||
gvIdx = label->property("index").toInt();
|
||||
QPoint globalPos = label->mapToGlobal(pos);
|
||||
QMenu contextMenu;
|
||||
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Clear"),this,SLOT(gvClear()),tr("Clear"));
|
||||
contextMenu.exec(globalPos);
|
||||
}
|
||||
|
||||
void FlightModePanel::gvClear()
|
||||
{
|
||||
if (phaseIdx == 0) {
|
||||
if (IS_HORUS_OR_TARANIS(getCurrentBoard())) {
|
||||
model->gvarData[gvIdx].clear();
|
||||
phase.gvars[gvIdx] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
lock = true;
|
||||
if (gvCount > 0 && (firmware->getCapability(GvarsFlightModes))) {
|
||||
phase.gvars[gvIdx] = GVAR_MAX_VALUE + 1;
|
||||
gvUse[gvIdx]->setCurrentIndex(1);
|
||||
}
|
||||
lock = false;
|
||||
}
|
||||
update();
|
||||
emit modified();
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
|
||||
FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
|
||||
@@ -524,7 +720,7 @@ FlightModesPanel::FlightModesPanel(QWidget * parent, ModelData & model, GeneralS
|
||||
QGridLayout * gridLayout = new QGridLayout(this);
|
||||
tabWidget = new QTabWidget(this);
|
||||
for (int i=0; i<modesCount; i++) {
|
||||
FlightModePanel *tab = new FlightModePanel(tabWidget, model, i, generalSettings, firmware);
|
||||
FlightModePanel * tab = new FlightModePanel(tabWidget, model, i, generalSettings, firmware);
|
||||
tab->setProperty("index", i);
|
||||
panels << tab;
|
||||
connect(tab, SIGNAL(modified()), this, SLOT(onPhaseModified()));
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "modeledit.h"
|
||||
#include "eeprominterface.h"
|
||||
|
||||
class RawSwitchFilterItemModel;
|
||||
|
||||
namespace Ui {
|
||||
class FlightMode;
|
||||
}
|
||||
@@ -53,10 +55,16 @@ class FlightModePanel : public ModelPanel
|
||||
void phaseGVValue_editingFinished();
|
||||
void phaseGVUse_currentIndexChanged(int index);
|
||||
void phaseGVPopupToggled(bool checked);
|
||||
void phaseGVUnit_currentIndexChanged(int index);
|
||||
void phaseGVPrec_currentIndexChanged(int index);
|
||||
void phaseGVMin_editingFinished();
|
||||
void phaseGVMax_editingFinished();
|
||||
void phaseREValue_editingFinished();
|
||||
void phaseREUse_currentIndexChanged(int index);
|
||||
void name_customContextMenuRequested(const QPoint & pos);
|
||||
void fmClear();
|
||||
void gvLabel_customContextMenuRequested(const QPoint & pos);
|
||||
void gvClear();
|
||||
|
||||
private:
|
||||
Ui::FlightMode *ui;
|
||||
@@ -64,19 +72,28 @@ class FlightModePanel : public ModelPanel
|
||||
FlightModeData & phase;
|
||||
int reCount;
|
||||
int gvCount;
|
||||
int gvIdx;
|
||||
QVector<QLabel *> trimsLabel;
|
||||
QLineEdit * gvNames[CPN_MAX_GVARS];
|
||||
QSpinBox * gvValues[CPN_MAX_GVARS];
|
||||
QDoubleSpinBox * gvValues[CPN_MAX_GVARS];
|
||||
QCheckBox * gvPopups[CPN_MAX_GVARS];
|
||||
QComboBox * gvUse[CPN_MAX_GVARS];
|
||||
QComboBox * gvUnit[CPN_MAX_GVARS];
|
||||
QComboBox * gvPrec[CPN_MAX_GVARS];
|
||||
QDoubleSpinBox * gvMin[CPN_MAX_GVARS];
|
||||
QDoubleSpinBox * gvMax[CPN_MAX_GVARS];
|
||||
QSpinBox * reValues[CPN_MAX_ENCODERS];
|
||||
QComboBox * reUse[CPN_MAX_ENCODERS];
|
||||
QVector<QComboBox *> trimsUse;
|
||||
QVector<QSpinBox *> trimsValue;
|
||||
QVector<QSlider *> trimsSlider;
|
||||
RawSwitchFilterItemModel * rawSwitchItemModel;
|
||||
|
||||
void trimUpdate(unsigned int trim);
|
||||
|
||||
void updateGVar(int index);
|
||||
void setGVSB(QDoubleSpinBox * spinBox, int min, int max, int val);
|
||||
void populateGvarUnitCB(QComboBox * cb);
|
||||
void populateGvarPrecCB(QComboBox * cb);
|
||||
};
|
||||
|
||||
class FlightModesPanel : public ModelPanel
|
||||
|
||||
@@ -75,27 +75,24 @@ void InputsPanel::update()
|
||||
// i -> mixer number
|
||||
QByteArray qba;
|
||||
ExposlistWidget->clear();
|
||||
firstLine = true;
|
||||
int curDest = -1;
|
||||
|
||||
for (int i=0; i<CPN_MAX_EXPOS; i++) {
|
||||
ExpoData *md = &model->expoData[i];
|
||||
|
||||
if (md->mode==0) break;
|
||||
if (!md->mode)
|
||||
break;
|
||||
|
||||
QString str;
|
||||
|
||||
while (curDest<(int)md->chn-1) {
|
||||
while (curDest < (int)md->chn-1) {
|
||||
curDest++;
|
||||
AddInputLine(-curDest-1);
|
||||
}
|
||||
if (AddInputLine(i)) {
|
||||
curDest++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
while (curDest<inputsCount-1) {
|
||||
while (curDest < inputsCount-1) {
|
||||
curDest++;
|
||||
AddInputLine(-curDest-1);
|
||||
}
|
||||
@@ -122,20 +119,17 @@ bool InputsPanel::AddInputLine(int dest)
|
||||
QString str = getInputText(dest, &new_ch);
|
||||
QListWidgetItem *itm = new QListWidgetItem(str);
|
||||
QByteArray qba(1, (quint8)dest);
|
||||
unsigned destId = abs(dest);
|
||||
bool hasSibs = false;
|
||||
if (dest >= 0) {
|
||||
//add input data
|
||||
ExpoData *md = &model->expoData[dest];
|
||||
qba.append((const char*)md, sizeof(ExpoData));
|
||||
destId = md->chn + 1;
|
||||
hasSibs = (dest < CPN_MAX_EXPOS && model->expoData[dest+1].chn == md->chn);
|
||||
}
|
||||
itm->setData(Qt::UserRole, qba);
|
||||
#if MIX_ROW_HEIGHT_INCREASE > 0
|
||||
if (new_ch && !firstLine) {
|
||||
//increase size of this row
|
||||
itm->setData(GroupHeaderRole, 1);
|
||||
}
|
||||
#endif
|
||||
ExposlistWidget->addItem(itm);
|
||||
firstLine = false;
|
||||
ExposlistWidget->addItem(itm, destId, new_ch, hasSibs);
|
||||
//qDebug() << "InputsPanel::AddInputLine(): dest" << dest << "text" << str;
|
||||
return new_ch;
|
||||
}
|
||||
@@ -153,26 +147,26 @@ bool InputsPanel::AddInputLine(int dest)
|
||||
QString InputsPanel::getInputText(int dest, bool * new_ch)
|
||||
{
|
||||
QString str;
|
||||
if (new_ch) *new_ch = 0;
|
||||
|
||||
if (new_ch)
|
||||
*new_ch = false;
|
||||
|
||||
if (dest < 0) {
|
||||
str = modelPrinter.printInputName(-dest-1);
|
||||
if (new_ch) *new_ch = 1;
|
||||
if (new_ch)
|
||||
*new_ch = true;
|
||||
}
|
||||
else {
|
||||
ExpoData & input = model->expoData[dest];
|
||||
int nameChars = (firmware->getCapability(VirtualInputs) ? 10 : 4);
|
||||
|
||||
if ((dest == 0) || (model->expoData[dest-1].chn != input.chn)) {
|
||||
if (new_ch) *new_ch = 1;
|
||||
if (firmware->getCapability(VirtualInputs))
|
||||
str += QString("%1").arg(modelPrinter.printInputName(input.chn), -10, ' ');
|
||||
else
|
||||
str = modelPrinter.printInputName(input.chn);
|
||||
if (new_ch)
|
||||
*new_ch = true;
|
||||
str = QString("%1").arg(modelPrinter.printInputName(input.chn), -nameChars, QChar(' '));
|
||||
}
|
||||
else {
|
||||
if (firmware->getCapability(VirtualInputs))
|
||||
str = " ";
|
||||
else
|
||||
str = " ";
|
||||
str = QString(nameChars, QChar(' '));
|
||||
}
|
||||
str.replace(" ", " ");
|
||||
str += modelPrinter.printInputLine(input);
|
||||
@@ -300,13 +294,17 @@ void InputsPanel::exposCopy()
|
||||
|
||||
void InputsPanel::mimeExpoDropped(int index, const QMimeData *data, Qt::DropAction action)
|
||||
{
|
||||
int idx = ExposlistWidget->item(index > 0 ? index-1 : 0)->data(Qt::UserRole).toByteArray().at(0);
|
||||
int idx = ExposlistWidget->item(index)->data(Qt::UserRole).toByteArray().at(0);
|
||||
if (action==Qt::CopyAction) {
|
||||
pasteExpoMimeData(data, idx);
|
||||
}
|
||||
else if (action==Qt::MoveAction) {
|
||||
QList<int> list = createExpoListFromSelected();
|
||||
exposDeleteList(list);
|
||||
foreach (const int del, list) {
|
||||
if (del < idx)
|
||||
--idx;
|
||||
}
|
||||
pasteExpoMimeData(data, idx);
|
||||
}
|
||||
}
|
||||
@@ -391,6 +389,7 @@ void InputsPanel::expoAdd()
|
||||
if (!gm_insertExpo(index))
|
||||
return;
|
||||
model->expoData[index].chn = model->expoData[index-1].chn;
|
||||
expoInserted=true;
|
||||
}
|
||||
gm_openExpo(index);
|
||||
}
|
||||
@@ -416,6 +415,8 @@ void InputsPanel::expolistWidget_customContextMenuRequested(QPoint pos)
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction(CompanionIcon("moveup.png"), tr("Move Up"),this,SLOT(moveExpoUp()),tr("Ctrl+Up"));
|
||||
contextMenu.addAction(CompanionIcon("movedown.png"), tr("Move Down"),this,SLOT(moveExpoDown()),tr("Ctrl+Down"));
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addActions(ExposlistWidget->actions());
|
||||
|
||||
contextMenu.exec(globalPos);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,6 @@ class InputsPanel : public ModelPanel
|
||||
private:
|
||||
bool expoInserted;
|
||||
MixersListWidget *ExposlistWidget;
|
||||
bool firstLine;
|
||||
int inputsCount;
|
||||
ModelPrinter modelPrinter;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "logicalswitches.h"
|
||||
#include "switchitemmodel.h"
|
||||
#include "helpers.h"
|
||||
|
||||
LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model, GeneralSettings & generalSettings, Firmware * firmware):
|
||||
@@ -28,8 +29,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
|
||||
Stopwatch s1("LogicalSwitchesPanel");
|
||||
|
||||
int channelsMax = model.getChannelsMax(true);
|
||||
rawSwitchItemModel = Helpers::getRawSwitchItemModel(&generalSettings, Helpers::LogicalSwitchesContext);
|
||||
rawSwitchItemModel->setParent(this);
|
||||
rawSwitchItemModel = new RawSwitchFilterItemModel(&generalSettings, &model, LogicalSwitchesContext);
|
||||
int srcFlags = POPULATE_NONE | POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_TRIMS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (firmware->getCapability(GvarsInCS) ? POPULATE_GVARS : 0);
|
||||
rawSourceItemModel = Helpers::getRawSourceItemModel(&generalSettings, &model, srcFlags);
|
||||
rawSourceItemModel->setParent(this);
|
||||
@@ -48,7 +48,7 @@ LogicalSwitchesPanel::LogicalSwitchesPanel(QWidget * parent, ModelData & model,
|
||||
// The label
|
||||
QLabel * label = new QLabel(this);
|
||||
label->setProperty("index", i);
|
||||
label->setText(tr("L%1").arg(i+1));
|
||||
label->setText(RawSwitch(SWITCH_TYPE_VIRTUAL, i+1).toString());
|
||||
label->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
label->setMouseTracking(true);
|
||||
label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
|
||||
@@ -468,7 +468,7 @@ void LogicalSwitchesPanel::populateAndSwitchCB(QComboBox *b, const RawSwitch & v
|
||||
b->addItem(item.toString(), item.toValue());
|
||||
if (item == value) b->setCurrentIndex(b->count()-1);
|
||||
|
||||
for (int i=1; i<=firmware->getCapability(SwitchesPositions); i++) {
|
||||
for (int i=1; i <= Boards::getCapability(firmware->getBoard(), Board::SwitchPositions); i++) {
|
||||
item = RawSwitch(SWITCH_TYPE_SWITCH, i);
|
||||
b->addItem(item.toString(), item.toValue());
|
||||
if (item == value) b->setCurrentIndex(b->count()-1);
|
||||
@@ -510,6 +510,7 @@ void LogicalSwitchesPanel::cswPaste()
|
||||
LogicalSwitchData *csw = &model->logicalSw[selectedSwitch];
|
||||
memcpy(csw, cswData.constData(), sizeof(LogicalSwitchData));
|
||||
emit modified();
|
||||
rawSwitchItemModel->update();
|
||||
updateLine(selectedSwitch);
|
||||
}
|
||||
}
|
||||
@@ -549,10 +550,10 @@ void LogicalSwitchesPanel::csw_customContextMenuRequested(QPoint pos)
|
||||
bool hasData = mimeData->hasFormat("application/x-companion-csw");
|
||||
|
||||
QMenu contextMenu;
|
||||
contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(cswCopy()),tr("Ctrl+C"));
|
||||
contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(cswCut()),tr("Ctrl+X"));
|
||||
contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(cswPaste()),tr("Ctrl+V"))->setEnabled(hasData);
|
||||
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(cswDelete()),tr("Delete"));
|
||||
contextMenu.addAction(CompanionIcon("copy.png"), tr("&Copy"),this,SLOT(cswCopy()));
|
||||
contextMenu.addAction(CompanionIcon("cut.png"), tr("&Cut"),this,SLOT(cswCut()));
|
||||
contextMenu.addAction(CompanionIcon("paste.png"), tr("&Paste"),this,SLOT(cswPaste()))->setEnabled(hasData);
|
||||
contextMenu.addAction(CompanionIcon("clear.png"), tr("&Delete"),this,SLOT(cswDelete()));
|
||||
|
||||
contextMenu.exec(globalPos);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
#define _LOGICALSWITCHES_H_
|
||||
|
||||
#include "modeledit.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "radiodata.h"
|
||||
|
||||
class RawSwitchFilterItemModel;
|
||||
|
||||
class LogicalSwitchesPanel : public ModelPanel
|
||||
{
|
||||
@@ -58,7 +60,7 @@ class LogicalSwitchesPanel : public ModelPanel
|
||||
QDoubleSpinBox * cswitchDelay[CPN_MAX_LOGICAL_SWITCHES];
|
||||
QComboBox * cswitchSource1[CPN_MAX_LOGICAL_SWITCHES];
|
||||
QComboBox * cswitchSource2[CPN_MAX_LOGICAL_SWITCHES];
|
||||
QStandardItemModel * rawSwitchItemModel;
|
||||
RawSwitchFilterItemModel * rawSwitchItemModel;
|
||||
QStandardItemModel * rawSourceItemModel;
|
||||
void setSwitchWidgetVisibility(int i);
|
||||
int selectedSwitch;
|
||||
|
||||
@@ -20,10 +20,11 @@
|
||||
|
||||
#include "mixerdialog.h"
|
||||
#include "ui_mixerdialog.h"
|
||||
#include "eeprominterface.h"
|
||||
#include "radiodata.h"
|
||||
#include "switchitemmodel.h"
|
||||
#include "helpers.h"
|
||||
|
||||
MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, GeneralSettings & generalSettings, Firmware * firmware) :
|
||||
MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData * mixdata, GeneralSettings & generalSettings, Firmware * firmware) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::MixerDialog),
|
||||
model(model),
|
||||
@@ -40,7 +41,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, G
|
||||
cb_fp[i] = tmp[i];
|
||||
}
|
||||
|
||||
this->setWindowTitle(tr("DEST -> CH%1").arg(md->destCh));
|
||||
this->setWindowTitle(tr("DEST -> %1").arg(RawSource(SOURCE_TYPE_CH, md->destCh-1).toString(&model, &generalSettings)));
|
||||
|
||||
ui->sourceCB->setModel(Helpers::getRawSourceItemModel(&generalSettings, &model, POPULATE_NONE | POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_SWITCHES | POPULATE_TRIMS));
|
||||
ui->sourceCB->setCurrentIndex(ui->sourceCB->findData(md->srcRaw.toValue()));
|
||||
@@ -103,7 +104,7 @@ MixerDialog::MixerDialog(QWidget *parent, ModelData & model, MixData *mixdata, G
|
||||
}
|
||||
}
|
||||
|
||||
ui->switchesCB->setModel(Helpers::getRawSwitchItemModel(&generalSettings, Helpers::MixesContext));
|
||||
ui->switchesCB->setModel(new RawSwitchFilterItemModel(&generalSettings, &model, MixesContext));
|
||||
ui->switchesCB->setCurrentIndex(ui->switchesCB->findData(md->swtch.toValue()));
|
||||
ui->warningCB->setCurrentIndex(md->mixWarn);
|
||||
ui->mltpxCB->setCurrentIndex(md->mltpx);
|
||||
|
||||
@@ -20,140 +20,256 @@
|
||||
|
||||
#include "mixerslistwidget.h"
|
||||
|
||||
#define GRP_IS_PARENT 0x01
|
||||
#define GRP_HAS_SIBLING 0x02
|
||||
#define GRP_HAS_DATA 0x04
|
||||
|
||||
#define GroupIdRole (Qt::UserRole+1) // destination Input/Channel, for alternate row colors
|
||||
#define GroupHeaderRole (Qt::UserRole+2) // bitfield of row metadata (see addItem())
|
||||
|
||||
static QFont defaultFont;
|
||||
static bool fontInit = false;
|
||||
|
||||
MixersListWidget::MixersListWidget(QWidget * parent, bool expo) :
|
||||
QListWidget(parent),
|
||||
expo(expo)
|
||||
QListWidget(parent),
|
||||
expo(expo)
|
||||
{
|
||||
setFont(QFont("Courier New",12));
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
setDragEnabled(true);
|
||||
setAcceptDrops(true);
|
||||
setDropIndicatorShown(true);
|
||||
setItemDelegate(new MixersDelegate(parent)); //set custom paint handler
|
||||
if (!fontInit) {
|
||||
fontInit = true;
|
||||
defaultFont = font();
|
||||
defaultFont.setFamily("Courier");
|
||||
defaultFont.setStyleHint(QFont::TypeWriter);
|
||||
defaultFont.setPointSize(defaultFont.pointSize() + 3);
|
||||
}
|
||||
|
||||
setFont(defaultFont);
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
setDragEnabled(true);
|
||||
setAcceptDrops(true);
|
||||
setDragDropMode(QAbstractItemView::DragDrop);
|
||||
setDropIndicatorShown(true);
|
||||
setItemDelegate(new MixersDelegate(this)); // set custom paint handler
|
||||
setStyle(new MixerItemViewProxyStyle(style())); // custom element style painter
|
||||
|
||||
itemMimeFmt = (expo ? "application/x-companion-expo-item" : "application/x-companion-mix-item");
|
||||
|
||||
QAction * zin = new QAction(tr("Increase font size"), this);
|
||||
zin->setShortcut(QKeySequence::ZoomIn);
|
||||
zin->setData(1);
|
||||
addAction(zin);
|
||||
QAction * zout = new QAction(tr("Decrease font size"), this);
|
||||
zout->setShortcut(QKeySequence::ZoomOut);
|
||||
zout->setData(-1);
|
||||
addAction(zout);
|
||||
QAction * zrst = new QAction(tr("Default font size"), this);
|
||||
zrst->setShortcut(tr("Ctrl+0"));
|
||||
zrst->setData(0);
|
||||
addAction(zrst);
|
||||
connect(zin, &QAction::triggered, this, &MixersListWidget::zoomView);
|
||||
connect(zout, &QAction::triggered, this, &MixersListWidget::zoomView);
|
||||
connect(zrst, &QAction::triggered, this, &MixersListWidget::zoomView);
|
||||
}
|
||||
|
||||
void MixersListWidget::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
emit keyWasPressed(event);
|
||||
emit keyWasPressed(event);
|
||||
}
|
||||
|
||||
void MixersListWidget::addItem(QListWidgetItem * item, const unsigned & rowId, bool topLevel, bool hasSib)
|
||||
{
|
||||
Qt::ItemFlags f = item->flags();
|
||||
f |= Qt::ItemIsDropEnabled;
|
||||
|
||||
quint8 hdrRole = 0;
|
||||
if (topLevel)
|
||||
hdrRole |= GRP_IS_PARENT;
|
||||
if (hasSib)
|
||||
hdrRole |= GRP_HAS_SIBLING;
|
||||
if (item->data(Qt::UserRole).toByteArray().at(0) > -1)
|
||||
hdrRole |= GRP_HAS_DATA;
|
||||
else
|
||||
f &= ~Qt::ItemIsDragEnabled; // prevent drag of empty items
|
||||
|
||||
item->setData(GroupIdRole, rowId);
|
||||
item->setData(GroupHeaderRole, hdrRole);
|
||||
item->setFlags(f);
|
||||
|
||||
QListWidget::addItem(item);
|
||||
//qDebug() << rowId << topLevel << hasSib << item->data(GroupHeaderRole).toUInt();
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Override to give us different mime type for mixers and inputs
|
||||
*/
|
||||
QStringList MixersListWidget::mimeTypes () const
|
||||
{
|
||||
QStringList types;
|
||||
if (expo) types << "application/x-companion-expo-item";
|
||||
else types << "application/x-companion-mix-item";
|
||||
return types;
|
||||
return QStringList() << itemMimeFmt;
|
||||
}
|
||||
|
||||
void MixersListWidget::dropEvent(QDropEvent * event)
|
||||
{
|
||||
QList<int> list;
|
||||
foreach(QListWidgetItem *item, selectedItems()) {
|
||||
int idx= item->data(Qt::UserRole).toByteArray().at(0);
|
||||
if(idx >= 0) list << idx;
|
||||
if (event->proposedAction() == Qt::IgnoreAction)
|
||||
return;
|
||||
|
||||
if (event->mimeData() && event->mimeData()->hasFormat(itemMimeFmt)) {
|
||||
if (event->source() != this) {
|
||||
// force a copy action if dragging from another window
|
||||
event->setDropAction(Qt::CopyAction);
|
||||
event->accept();
|
||||
}
|
||||
if (list.count()<1) return;
|
||||
event->acceptProposedAction();
|
||||
dropMimeData(indexAt(event->pos()).row(),event->mimeData(),event->dropAction());
|
||||
else {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
dropMimeData(indexAt(event->pos()).row(), event->mimeData(), event->dropAction());
|
||||
}
|
||||
}
|
||||
|
||||
bool MixersListWidget::dropMimeData(int index, const QMimeData * data, Qt::DropAction action )
|
||||
{
|
||||
// qDebug() << "MixersListWidget::dropMimeData() index:" << index << "formats" << data->formats();
|
||||
QByteArray dropData = data->data(expo ? "application/x-companion-expo-item" : "application/x-companion-mix-item");
|
||||
if (dropData.isNull() ) return false;
|
||||
QDataStream stream(&dropData, QIODevice::ReadOnly);
|
||||
QByteArray qba;
|
||||
// qDebug() << "index:" << index << action << "formats" << data->formats();
|
||||
QByteArray dropData = data->data(itemMimeFmt);
|
||||
if (dropData.isEmpty() )
|
||||
return false;
|
||||
|
||||
while (!stream.atEnd()) {
|
||||
int r,c;
|
||||
QMap<int, QVariant> v;
|
||||
stream >> r >> c >> v;
|
||||
QList<QVariant> lsVars;
|
||||
lsVars = v.values();
|
||||
qba.append(lsVars.at(1).toByteArray().mid(1));
|
||||
// qDebug() << "MixersListWidget::dropMimeData() added" << lsVars.count() << "items, data:" << lsVars;
|
||||
}
|
||||
QDataStream stream(&dropData, QIODevice::ReadOnly);
|
||||
QByteArray qba;
|
||||
|
||||
if(qba.length()>0) {
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(expo ? "application/x-companion-expo" : "application/x-companion-mix", qba);
|
||||
emit mimeDropped(index, mimeData, action);
|
||||
delete mimeData; //is this correct? is mimeData freed elswere??
|
||||
}
|
||||
while (!stream.atEnd()) {
|
||||
int r,c;
|
||||
QMap<int, QVariant> v;
|
||||
stream >> r >> c >> v;
|
||||
qba.append(v.values().at(1).toByteArray().mid(1));
|
||||
}
|
||||
|
||||
return true;
|
||||
if(qba.size()) {
|
||||
QMimeData mimeData;
|
||||
mimeData.setData(QString(itemMimeFmt).remove("-item"), qba);
|
||||
emit mimeDropped(index, &mimeData, action);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MixersListWidget::zoomView()
|
||||
{
|
||||
static int origSz = QFontInfo(font()).pixelSize();
|
||||
int fsz = origSz;
|
||||
int step = qobject_cast<QAction *>(sender())->data().toInt();
|
||||
if (step)
|
||||
fsz = QFontInfo(font()).pixelSize() + step;
|
||||
if (fsz < 8)
|
||||
return;
|
||||
|
||||
QFont fnt(font());
|
||||
fnt.setPixelSize(fsz);
|
||||
setFont(fnt);
|
||||
defaultFont = fnt;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MixersDelegate
|
||||
*/
|
||||
|
||||
/**
|
||||
@brief Paints our HTML formated list item text
|
||||
*/
|
||||
void MixersDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
|
||||
painter->save();
|
||||
QTextDocument doc;
|
||||
SetupDocument(doc, options, index);
|
||||
options.text.clear();
|
||||
|
||||
//setup html document
|
||||
QTextDocument doc;
|
||||
SetupDocument(doc, options);
|
||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||
if (options.widget)
|
||||
ctx.palette = options.widget->palette();
|
||||
|
||||
options.text = "";
|
||||
options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);
|
||||
QBrush brush = ((index.data(GroupIdRole).toUInt() % 2) ? ctx.palette.base() : ctx.palette.alternateBase());
|
||||
options.backgroundBrush = brush;
|
||||
|
||||
if ( index.model()->data(index, GroupHeaderRole).toInt() > 0 ) {
|
||||
//paint with added space
|
||||
painter->translate(options.rect.left(), options.rect.top() + MIX_ROW_HEIGHT_INCREASE);
|
||||
QRect clip(0, 0, options.rect.width(), options.rect.height() - MIX_ROW_HEIGHT_INCREASE);
|
||||
doc.drawContents(painter, clip);
|
||||
}
|
||||
else {
|
||||
painter->translate(options.rect.left(), options.rect.top());
|
||||
QRect clip(0, 0, options.rect.width(), options.rect.height());
|
||||
doc.drawContents(painter, clip);
|
||||
}
|
||||
painter->restore();
|
||||
if (!(index.model()->data(index, GroupHeaderRole).toUInt() & GRP_HAS_DATA)) {
|
||||
// lighter text for empty lines
|
||||
ctx.palette.setBrush(QPalette::Text, ctx.palette.mid());
|
||||
}
|
||||
#ifndef Q_OS_WIN
|
||||
// Linux and OS X show a solid dark blue color on selected items
|
||||
else if ((options.state & QStyle::State_Selected)) {
|
||||
ctx.palette.setBrush(QPalette::Text, ctx.palette.highlightedText());
|
||||
}
|
||||
#endif
|
||||
|
||||
QStyle * style = (options.widget ? options.widget->style() : QApplication::style());
|
||||
style->drawControl(QStyle::CE_ItemViewItem, &options, painter, options.widget);
|
||||
|
||||
QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &options);
|
||||
QRectF clipRect = textRect.translated(-textRect.topLeft());
|
||||
ctx.clip = clipRect;
|
||||
painter->save();
|
||||
painter->translate(textRect.topLeft());
|
||||
painter->setClipRect(clipRect);
|
||||
doc.documentLayout()->draw(painter, ctx);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Returns needed size for our HTML formated list item text
|
||||
*/
|
||||
QSize MixersDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
|
||||
QSize MixersDelegate::sizeHint (const QStyleOptionViewItem & option, const QModelIndex & index) const
|
||||
{
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
|
||||
//setup html document
|
||||
QTextDocument doc;
|
||||
SetupDocument(doc, options);
|
||||
|
||||
//qDebug() << "MixersDelegate::sizeHint() UserRole-> " << index.model()->data(index, Qt::UserRole + 2);
|
||||
int height = doc.size().height();
|
||||
if ( index.model()->data(index, Qt::UserRole + 2).toInt() > 0 ) {
|
||||
//qDebug() << "MixersDelegate::sizeHint() detected channel head";
|
||||
height = doc.size().height() + MIX_ROW_HEIGHT_INCREASE;
|
||||
}
|
||||
//qDebug() << "MixersDelegate::sizeHint() options.rect " << options.rect;
|
||||
//qDebug() << "MixersDelegate::sizeHint() result " << QSize(doc.idealWidth(), height) << options.rect.width();
|
||||
return QSize(doc.idealWidth(), height);
|
||||
QTextDocument doc;
|
||||
SetupDocument(doc, options, index);
|
||||
return QSize(doc.idealWidth(), doc.size().height());
|
||||
}
|
||||
|
||||
void MixersDelegate::SetupDocument(QTextDocument & doc, const QStyleOptionViewItem & options) const
|
||||
void MixersDelegate::SetupDocument(QTextDocument & doc, const QStyleOptionViewItem & options, const QModelIndex & index) const
|
||||
{
|
||||
//setup html document
|
||||
doc.setHtml(options.text);
|
||||
doc.setDefaultFont(options.font);
|
||||
//setup html document
|
||||
quint8 hdrRole = index.model()->data(index, GroupHeaderRole).toUInt();
|
||||
|
||||
//minimize margins (default margins look ugly)
|
||||
QTextFrame *tf = doc.rootFrame();
|
||||
QTextFrameFormat tff = tf->frameFormat();
|
||||
tff.setMargin(0);
|
||||
tf->setFrameFormat(tff);
|
||||
doc.setDefaultFont(options.font);
|
||||
doc.setHtml(options.text);
|
||||
|
||||
// adjust margins to visually group items per input/channel
|
||||
QTextFrame *tf = doc.rootFrame();
|
||||
QTextFrameFormat tff = tf->frameFormat();
|
||||
|
||||
if (!(hdrRole & GRP_HAS_DATA)) {
|
||||
tff.setTopMargin(0.75f);
|
||||
tff.setBottomMargin(0.75f);
|
||||
}
|
||||
else {
|
||||
if (!(hdrRole & GRP_IS_PARENT))
|
||||
tff.setTopMargin(0.5f);
|
||||
if (hdrRole & GRP_HAS_SIBLING)
|
||||
tff.setBottomMargin(0.5f);
|
||||
}
|
||||
tf->setFrameFormat(tff);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MixerItemViewProxyStyle
|
||||
*/
|
||||
|
||||
void MixerItemViewProxyStyle::drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption * option, QPainter * painter, const QWidget * widget) const
|
||||
{
|
||||
painter->save();
|
||||
if (element == QStyle::PE_IndicatorItemViewItemDrop) {
|
||||
painter->setRenderHint(QPainter::HighQualityAntialiasing, true);
|
||||
// set a wider stroke for the drop indicator
|
||||
QPen pen(painter->pen());
|
||||
pen.setWidthF(2.25f);
|
||||
painter->setPen(pen);
|
||||
}
|
||||
QProxyStyle::drawPrimitive(element, option, painter, widget);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||