Compare commits
627 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2176a654cd | |||
| 2176788d1c | |||
| 6389fa2d81 | |||
| 8a0b64dd00 | |||
| 79ac207532 | |||
| c33e12b66f | |||
| 5d0dfb80d4 | |||
| 7ebab92f16 | |||
| 1a851f7c33 | |||
| 74ee8bea5d | |||
| dec1748978 | |||
| 4ef47e1040 | |||
| 42f242ce42 | |||
| c4914a64bb | |||
| 4aa05dfcf2 | |||
| 255ff5d789 | |||
| 75f5186dec | |||
| 0cf6d80705 | |||
| 2d96c6ad22 | |||
| ef7ec13861 | |||
| 8008e09918 | |||
| 75ace76c6a | |||
| 9de58a29e3 | |||
| 56aff41b7e | |||
| a8417a7e23 | |||
| 582c9b7f08 | |||
| 2eb6ca75a8 | |||
| 4918ac6307 | |||
| acc03e91f3 | |||
| 8e1466a35a | |||
| 5b73af668f | |||
| deb035c7fe | |||
| 2075a99c9b | |||
| 74b1f603df | |||
| ed1eb1c018 | |||
| 4bed2e57cb | |||
| 0629f502b5 | |||
| fd93873cc1 | |||
| dbd58dbbc6 | |||
| b2edf61588 | |||
| 96b6975deb | |||
| 9449dab0b7 | |||
| 6da9dbcc53 | |||
| d1bdea21b4 | |||
| 5ea0f3253f | |||
| b1e5c02e0c | |||
| f48d97ab04 | |||
| 8f85e04d61 | |||
| 1eab9b34fe | |||
| 13a3c44b61 | |||
| f6b106598c | |||
| f6aed13605 | |||
| 62dd8e67df | |||
| ba7620e0ee | |||
| 931f6a35dd | |||
| d3394733b1 | |||
| 0f5d175b09 | |||
| c93111bf4b | |||
| adb0f0a46f | |||
| 60454c0c39 | |||
| de35de9e00 | |||
| d5d91ae592 | |||
| 9c852af5b7 | |||
| 24fcfd125c | |||
| 1ad42519d6 | |||
| 3052dcc95a | |||
| 17089d8316 | |||
| ce919632be | |||
| f3168c3603 | |||
| a6ca88b5ac | |||
| 8625a59d4c | |||
| cb4289fd19 | |||
| 9ac5f837f7 | |||
| 033ab9ac71 | |||
| 228fe71eb4 | |||
| 80462cf559 | |||
| e5df16ba2b | |||
| b0f4d56de1 | |||
| 7bc0f8731f | |||
| b4b49a4296 | |||
| 507054e9cd | |||
| 342b8b157b | |||
| 74fc8f6db0 | |||
| 04bb3dfe9d | |||
| 7fb15269d1 | |||
| 49772d2539 | |||
| 0f4bd34bce | |||
| 2451cbddec | |||
| b7363225da | |||
| a9c0756da4 | |||
| 2652068933 | |||
| 022105cdba | |||
| 2fa05ed245 | |||
| 124be52411 | |||
| 6f8272718d | |||
| bac1fb18f0 | |||
| 391204ea0d | |||
| 810f3efcbb | |||
| e4a80d887a | |||
| 45d496bd01 | |||
| 20a5b2d4c4 | |||
| cc2637b310 | |||
| 3fc404cd25 | |||
| e016fa913f | |||
| e1c6f4f58f | |||
| c50888fc79 | |||
| 7c0a911e9f | |||
| 0562776b7a | |||
| 9cf79ffb5a | |||
| 63b0ef65e0 | |||
| 62bf6a9d57 | |||
| 4ad6244d8d | |||
| b2f72020bd | |||
| d73f96e3d8 | |||
| f8210e4a2a | |||
| 1ccaf45740 | |||
| d268ccea5b | |||
| 10efb6e55a | |||
| 171c44507a | |||
| 9514f057dc | |||
| e154857aca | |||
| 59c06bcaf1 | |||
| 17f02b2ff0 | |||
| 6316b78a5e | |||
| e53269c37f | |||
| a43adf7d4f | |||
| 16d24d4b43 | |||
| 4a3ae82748 | |||
| 60fe2ce30e | |||
| b294530716 | |||
| 0652267d00 | |||
| b857374aa2 | |||
| 480ce08d39 | |||
| 63f33a42e3 | |||
| f6d1baa50a | |||
| 0df1ec8765 | |||
| 19e128041b | |||
| 76f8b3df22 | |||
| e1e791fc75 | |||
| bbf59a731d | |||
| 803bcbbea0 | |||
| 6f384c8802 | |||
| d6eb66c738 | |||
| 7078381175 | |||
| 0ffef66cb6 | |||
| dfc17244d4 | |||
| ecb9f607ed | |||
| 35126ba22c | |||
| 5cdf03ff6d | |||
| d128b30279 | |||
| cadea90109 | |||
| 90d1695bbc | |||
| 713cb032b5 | |||
| 24ed144200 | |||
| ebc584b2a7 | |||
| dcef21676d | |||
| ff2da496af | |||
| 9d5f85634c | |||
| 7efda5fbbd | |||
| 60696a895c | |||
| 8b26f50003 | |||
| bf78ac7a6c | |||
| f9e9ed53f9 | |||
| d727063036 | |||
| 26f69bccef | |||
| 95f991b5de | |||
| 2a4b72246b | |||
| e62c9d89b1 | |||
| 3926173dfe | |||
| 9098a7c128 | |||
| d77de385f0 | |||
| 7bcd3e2262 | |||
| 2f35d97b27 | |||
| 152dc56df4 | |||
| 32930319ea | |||
| 2e54232181 | |||
| 8648017b42 | |||
| f974c8259e | |||
| f6f99e45b9 | |||
| 414fca0664 | |||
| 2641a0d98e | |||
| 53e8d68878 | |||
| 7a6d0c3432 | |||
| b049902925 | |||
| a8289c3223 | |||
| e46d742d6c | |||
| 24d996c8c4 | |||
| 8b2cdc434b | |||
| a7c4f15fea | |||
| 05b0cc9e76 | |||
| 495aaa4c56 | |||
| b57ba269a6 | |||
| 4948eb0d45 | |||
| e5e6b9e820 | |||
| 1c2b236c86 | |||
| 6ca66a04da | |||
| 2595be63a1 | |||
| c31b36975d | |||
| 73a2fcd301 | |||
| 00b0a7c811 | |||
| 2ef93cad44 | |||
| d3aa304556 | |||
| 228927b4e9 | |||
| 6fc393c7db | |||
| 361fdcce1b | |||
| 12cf696097 | |||
| e7ae6cd190 | |||
| 61dfe4ef07 | |||
| d3099ecf75 | |||
| c183e3f342 | |||
| a5ded3341a | |||
| bb15c56a2d | |||
| c61931996a | |||
| cb6c91be06 | |||
| bfcdec47c1 | |||
| c0445ed857 | |||
| 4e79d1ecdd | |||
| 4306af3ef3 | |||
| a01f9f99f4 | |||
| 08186f4131 | |||
| bdc9807dee | |||
| d77180d9b5 | |||
| b0bcaa971e | |||
| 4294202074 | |||
| 1e013274c2 | |||
| 39c7024f12 | |||
| 375f3a7164 | |||
| 370bdef8d0 | |||
| 7b1e75e6ed | |||
| 5c1a089981 | |||
| cfb59094fe | |||
| 7d30a2bc54 | |||
| 472879e95a | |||
| 7027d02f94 | |||
| 561441b48a | |||
| fe5c7a60ab | |||
| 1a3dc72af8 | |||
| c919694f37 | |||
| 6fbdf8f0e2 | |||
| 4060ec3038 | |||
| 32626970a0 | |||
| bc0a53a226 | |||
| b6a044111b | |||
| 3c4286c98b | |||
| 6d996e31b8 | |||
| ec4faad589 | |||
| 13820bc002 | |||
| 6ad9f25e7d | |||
| a348fde7d1 | |||
| d25017dd5b | |||
| 9b965f367a | |||
| adca34ac6a | |||
| 51a4a92ec4 | |||
| ae8ea3b938 | |||
| b57d77dd0b | |||
| d5cbb56160 | |||
| e97c2a6864 | |||
| 41447e9b44 | |||
| 7aa368c2c5 | |||
| 6a00eaa4a3 | |||
| 9240566167 | |||
| 9eaa5f90e0 | |||
| 214f785c97 | |||
| ae0534cbb4 | |||
| f3c5c458c6 | |||
| d6fd5598ab | |||
| c41b334f0a | |||
| c3a6bf3d40 | |||
| cb7aa5143b | |||
| 8942abfc64 | |||
| e5ef973d52 | |||
| 0bd45f691e | |||
| 117c70ed7d | |||
| d09f88d53b | |||
| 06f17d9415 | |||
| c1d8e979f3 | |||
| 16f286735d | |||
| 45c7490180 | |||
| 1566b357cb | |||
| 7d9222926a | |||
| b957d5176e | |||
| e76a520c19 | |||
| f0d205fed9 | |||
| 42811d0602 | |||
| b54c03f89e | |||
| 5596790a6e | |||
| e55263be00 | |||
| 441c2b50b9 | |||
| 0a3f5b65bf | |||
| 93c29ad15e | |||
| 8f565ef7f0 | |||
| d97de297af | |||
| 18ac4c2288 | |||
| 0c6eb6dec3 | |||
| 4a274709e7 | |||
| c6e4f18d99 | |||
| 0e5155ae2f | |||
| aa78abc649 | |||
| 1c62fc868d | |||
| f9c2f03a44 | |||
| dfd11b7596 | |||
| 98796f6250 | |||
| b728251bcc | |||
| d894faaeaa | |||
| 8b114c81c5 | |||
| 97ffb60f23 | |||
| 41b7182661 | |||
| 19e5a231a7 | |||
| 01fcb2276b | |||
| 19b4e98ee7 | |||
| 77c76bbc8a | |||
| 00bb1636da | |||
| 50ec496c54 | |||
| 2b8ad1b65c | |||
| 5c5f077a4a | |||
| b05f6f1614 | |||
| 0180cb380f | |||
| 882e48b457 | |||
| fa56b17c88 | |||
| 6b1c2da867 | |||
| 84eacd13a1 | |||
| b6bd1a9373 | |||
| 7e39411910 | |||
| 2f3659e7ac | |||
| c0567aa011 | |||
| 9b310ab955 | |||
| 5226855158 | |||
| ee19354484 | |||
| e967020ebe | |||
| 7b0d45402a | |||
| 714250d9f6 | |||
| b4e3ce1166 | |||
| 1958cafbdf | |||
| 248de56fb0 | |||
| 89349c1084 | |||
| e2c0c6362f | |||
| 7cc55d2d3a | |||
| e5d5335701 | |||
| 888a35bbde | |||
| ad9109cad4 | |||
| 232d0e8b6b | |||
| 0d94532df9 | |||
| 799302cd6d | |||
| c33b3fd314 | |||
| dc50b7b065 | |||
| 00a82905ec | |||
| f35ed59868 | |||
| 3cd87c2a44 | |||
| 6cbc10db81 | |||
| 4c28070449 | |||
| bf4f6cff3c | |||
| 5db9a6af9d | |||
| b968bac318 | |||
| 7ea907c343 | |||
| b71d66de94 | |||
| 06043b4a14 | |||
| d836d7187e | |||
| b0ecb5b62d | |||
| 09febce4ce | |||
| c5621ff44b | |||
| d58f3114cc | |||
| e1caaed3cf | |||
| 11959f5023 | |||
| 197e5f920d | |||
| e1300a9342 | |||
| 524d2572aa | |||
| 340bab73f5 | |||
| 8d1529cc48 | |||
| c501a73251 | |||
| 6b1c02526f | |||
| d8d7284c35 | |||
| a5a8b93a2e | |||
| a72fd0ebdd | |||
| d5bd1f5aea | |||
| 17c27d1176 | |||
| df698b9433 | |||
| 2ea59ac83a | |||
| 4264e5bee3 | |||
| 411bcc58c5 | |||
| f02cd717bc | |||
| 91f40ac779 | |||
| 04ffee8e82 | |||
| 54253ba8a3 | |||
| ddd533ee9c | |||
| 46133c76b2 | |||
| d4e9ace354 | |||
| 88dd914a31 | |||
| ca68d32a47 | |||
| 3c86dbe28c | |||
| 400bac868e | |||
| 7e765db562 | |||
| a993e179ab | |||
| 5253ff35f1 | |||
| cba0ec4de5 | |||
| ed0354dd06 | |||
| d255d6aeeb | |||
| 94abd0ee79 | |||
| 6a3cd9c0d7 | |||
| 81be16d058 | |||
| 3efdc963d8 | |||
| a4525bf88c | |||
| d7c7ff3dad | |||
| 987aec3fd6 | |||
| d5661c24bd | |||
| c3ee1111f9 | |||
| 9c1509b8c3 | |||
| 1020cdd7a6 | |||
| bff2f53996 | |||
| d5bf831f60 | |||
| 6c423be36f | |||
| 3c33e2c046 | |||
| 253ff41819 | |||
| 24d95b410d | |||
| db5aacf984 | |||
| 111a56dd8a | |||
| d1d0d61b4f | |||
| 640f279abe | |||
| 874191bd8d | |||
| 2066af9f28 | |||
| ef7b3c1715 | |||
| 6eb96851f9 | |||
| a42ef9de77 | |||
| fb23fe3084 | |||
| 57f0150a23 | |||
| 9b31a986b6 | |||
| 8fa46a1f9e | |||
| d805f5ceff | |||
| b4242e562d | |||
| 2effa810c1 | |||
| a78af6acc2 | |||
| fc084c84f4 | |||
| a846ab7443 | |||
| 9f53272d34 | |||
| aa53aac7be | |||
| db984fcad9 | |||
| 607713cdae | |||
| 7de0a61de3 | |||
| 1838460c38 | |||
| 3a4e00d0f5 | |||
| a9bd82150b | |||
| de5c3733d0 | |||
| 3ff662e710 | |||
| 669571799b | |||
| 81a98fc0d3 | |||
| f10157fb24 | |||
| 7d94508257 | |||
| 262a8607d0 | |||
| fd44a9552a | |||
| 8e2d6d8cb2 | |||
| 13b73cb51f | |||
| 5f730ba360 | |||
| 79dbbadf2d | |||
| cd150c265f | |||
| 7a50a91eab | |||
| b5561ee5d4 | |||
| 8dcda7fe35 | |||
| 9b679cc8dd | |||
| 674f8cc936 | |||
| 51a43ef45b | |||
| acc55d588a | |||
| d4990b30e9 | |||
| 920a8d34ea | |||
| c8dfcf4b39 | |||
| aa93632707 | |||
| cc55262cbc | |||
| f887b62a85 | |||
| 5b20781080 | |||
| 98a1efc123 | |||
| a628c1f5e4 | |||
| 6588e8fabf | |||
| 52d349538e | |||
| aad2b3a492 | |||
| 93180abf7b | |||
| e30c8d8949 | |||
| a90c5d71ad | |||
| 54f56813a5 | |||
| 8d29229c0f | |||
| dc498128be | |||
| 6d5b71b663 | |||
| 122fcbb40b | |||
| 4fc28bb65e | |||
| a7f92a3187 | |||
| dd16b68623 | |||
| df24d87245 | |||
| 6000e04c78 | |||
| 87181a8ecb | |||
| 7d0731754c | |||
| 962e63ab52 | |||
| 9f4b43f3f2 | |||
| ef722200c9 | |||
| 784f47fa86 | |||
| 90cdc28707 | |||
| 62844b321c | |||
| 8a6c7f5538 | |||
| 8c3eeb5201 | |||
| 5998fabadd | |||
| 97be02356f | |||
| e59867d479 | |||
| 8e1bcaed37 | |||
| f3c864c178 | |||
| 947923509e | |||
| 4e0f77c0f4 | |||
| 6f0505f19c | |||
| 98bf66cb25 | |||
| f9b641b24d | |||
| 3894314ab2 | |||
| edc9d38680 | |||
| ce5f72207e | |||
| ff8d009022 | |||
| 589c33ec05 | |||
| 28fe5b0df5 | |||
| 5a3dfe598f | |||
| d0c132ccd4 | |||
| 826541548c | |||
| e3adc76a72 | |||
| 2ae2d7ee1a | |||
| e28b50e8d6 | |||
| 9c78d86f58 | |||
| a6b23a751e | |||
| 34d5f1f9fe | |||
| 43ad15dc0e | |||
| d20147c79f | |||
| 7cc014cf9e | |||
| 9e735fc940 | |||
| 4fecf6c50d | |||
| c31c14e46b | |||
| 349dbb98a6 | |||
| f4fa5bb0fc | |||
| 4cdf75dc72 | |||
| 53eb39e033 | |||
| 57ae43890c | |||
| 1c59574cbf | |||
| 7ddef03aba | |||
| 4258738b89 | |||
| 594864e117 | |||
| a5698ce480 | |||
| 1a2c9011e6 | |||
| 600ac72a3d | |||
| 1118eed080 | |||
| e42c66bd0e | |||
| ff8fae377c | |||
| 6931252ed9 | |||
| ef8e549d86 | |||
| a5470029a8 | |||
| 13fb23d59d | |||
| a3197578d6 | |||
| ebc14b35f5 | |||
| b0235a2805 | |||
| d0069e0e1d | |||
| 878f136951 | |||
| bf364bf74c | |||
| 03c2850c59 | |||
| 4eddc7131d | |||
| 14be1935e8 | |||
| f08029354a | |||
| c18600b67f | |||
| 2acc0a6844 | |||
| 8ffba3a52f | |||
| 0fb2f35b10 | |||
| f8270b9cec | |||
| d3311ee231 | |||
| 21eb2c8dad | |||
| a11fd7a792 | |||
| a2ad9f8b10 | |||
| 9a0e2f3395 | |||
| cd9196ddb9 | |||
| c10fe673a2 | |||
| 105f8a1720 | |||
| 050f47daf1 | |||
| 683abd2029 | |||
| d08f937932 | |||
| 2f51742311 | |||
| b926d2f0bd | |||
| 89d1d36e79 | |||
| 999cd8cd11 | |||
| fd8b281731 | |||
| d8481b4528 | |||
| 6d93fa046c | |||
| c75672fd44 | |||
| 5484796745 | |||
| 4ed45e0515 | |||
| 9956c04526 | |||
| b74af71312 | |||
| 44640422f2 | |||
| be91f378ac | |||
| bdca18cc9f | |||
| 76cb15f545 | |||
| 4f9e754a51 | |||
| 955774a91a | |||
| e8a9485d5e | |||
| 0736c141b9 | |||
| 204549f55b | |||
| 82a5f307ed | |||
| 7a4650a1a9 | |||
| 518980d9ed | |||
| 5cc1e2e42d | |||
| c599385c8b | |||
| 1d37d3fdf7 | |||
| f3db64af05 | |||
| 3217372720 | |||
| 7a50654f3b | |||
| 9893921d76 | |||
| 5574f35473 | |||
| fd42e493c0 | |||
| 7843e6a709 | |||
| 4c129ec208 | |||
| 1bf44561da | |||
| ad612864ce | |||
| 1707436cad | |||
| b011d508f8 | |||
| f67a477f65 | |||
| 3573b97bfc | |||
| 37a42a3fb7 | |||
| 2d13ddc70c | |||
| 0be01f3c24 | |||
| eb492724c7 | |||
| 3b05d03220 | |||
| 4c04233a20 | |||
| 2b6d2fc117 | |||
| f64ef39687 | |||
| c1fb392333 | |||
| de60d5467c | |||
| c1274e24b0 | |||
| 7f593d3999 | |||
| 3a6a6097a7 | |||
| 69989e4e64 | |||
| 88999b34d3 |
+5
-3
@@ -14,7 +14,7 @@ default:
|
||||
##########################################################################
|
||||
# The variable CI_COMMIT_BEFORE_SHA is not available in normal merge requests
|
||||
# so we must build the commit hash ourselves, see:
|
||||
# https://gitlab.com/gitlab-org/gitlab/issues/12850
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/12850
|
||||
test_formatting:
|
||||
stage: test
|
||||
needs: []
|
||||
@@ -23,8 +23,10 @@ test_formatting:
|
||||
allow_failure: true
|
||||
before_script:
|
||||
# We must manually add the KiCad remote to ensure it is named sensibly
|
||||
- git remote add product https://gitlab.com/kicad/code/kicad.git
|
||||
- git remote add source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git
|
||||
- git remote add product https://gitlab.com/kicad/code/kicad.git ||
|
||||
git remote set-url product https://gitlab.com/kicad/code/kicad.git
|
||||
- git remote add source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git ||
|
||||
git remote set-url source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git
|
||||
- git fetch -n product
|
||||
- git fetch -n source
|
||||
# Get the SHAs of the commits
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ build_doxygen_docker:
|
||||
- docker
|
||||
before_script:
|
||||
- docker info
|
||||
- docker login -u gitlab-ci-token -p "$CI_BUILD_TOKEN" "$CI_REGISTRY"
|
||||
- docker login -u gitlab-ci-token -p "$CI_JOB_TOKEN" "$CI_REGISTRY"
|
||||
script:
|
||||
- docker build -t "${CI_REGISTRY_IMAGE}/doxygen:$CI_COMMIT_BRANCH" -f ./doxygen/doxygen.Dockerfile .
|
||||
- docker push "${CI_REGISTRY_IMAGE}/doxygen:$CI_COMMIT_BRANCH"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
##########################################################################
|
||||
# Test the formatting in a merge request using clang-format
|
||||
##########################################################################
|
||||
# The variable CI_COMMIT_BEFORE_SHA is not available in normal merge requests
|
||||
# so we must build the commit hash ourselves, see:
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/12850
|
||||
test_formatting:
|
||||
stage: test
|
||||
needs: []
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
allow_failure: true
|
||||
before_script:
|
||||
# We must manually add the KiCad remote to ensure it is named sensibly
|
||||
- git remote add product https://gitlab.com/kicad/code/kicad.git
|
||||
- git remote add source ${CI_MERGE_REQUEST_SOURCE_PROJECT_URL}.git
|
||||
- git fetch -n product
|
||||
- git fetch -n source
|
||||
# Get the SHAs of the commits
|
||||
- "TARGET_HEAD_SHA=$(git rev-parse product/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME})"
|
||||
- "SOURCE_HEAD_SHA=$(git rev-parse source/${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME})"
|
||||
- "MERGE_BASE_SHA=$(git merge-base ${TARGET_HEAD_SHA} ${SOURCE_HEAD_SHA})"
|
||||
script:
|
||||
- echo "Testing formatting from commit ${MERGE_BASE_SHA}"
|
||||
- ./tools/check_coding.sh --diff --ci --commit ${MERGE_BASE_SHA}
|
||||
@@ -28,7 +28,7 @@
|
||||
# GitLab supports displaying the results in the GUI through JUNIT artifacts
|
||||
# (https://docs.gitlab.com/ee/ci/junit_test_reports.html)
|
||||
# so we upload the JUNIT results. Note that there is a bug with how paths
|
||||
# are processed in the junit report (https://gitlab.com/gitlab-org/gitlab/issues/23835)
|
||||
# are processed in the junit report (https://gitlab.com/gitlab-org/gitlab/-/issues/23835)
|
||||
# so we can't use a glob and have to list out each hierarchy separately.
|
||||
artifacts:
|
||||
reports:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
|
||||
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -294,6 +294,16 @@ void S3D_PLUGIN_MANAGER::checkPluginName( const wxString& aPath,
|
||||
++bl;
|
||||
}
|
||||
|
||||
// prevent loading non-plugin dlls
|
||||
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
|
||||
{
|
||||
if( !path.GetName().StartsWith( "s3d_plugin" )
|
||||
&& !path.GetName().StartsWith( "libs3d_plugin" ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aPluginList.push_back( wxpath );
|
||||
|
||||
wxLogTrace( MASK_3D_PLUGINMGR, wxT( " * [INFO] found 3D plugin '%s'\n" ), wxpath.GetData() );
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <pgm_base.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <wx/log.h>
|
||||
#include <pcbnew_settings.h>
|
||||
#include <advanced_config.h>
|
||||
|
||||
|
||||
@@ -92,8 +93,7 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "BOARD_ADAPTER::BOARD_ADAPTER" ) );
|
||||
|
||||
if( PgmOrNull() )
|
||||
m_colors = Pgm().GetSettingsManager().GetColorSettings();
|
||||
ReloadColorSettings();
|
||||
|
||||
m_boardPos = VECTOR2I();
|
||||
m_boardSize = VECTOR2I();
|
||||
@@ -208,6 +208,15 @@ BOARD_ADAPTER::~BOARD_ADAPTER()
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::ReloadColorSettings() noexcept
|
||||
{
|
||||
wxASSERT( PgmOrNull() );
|
||||
|
||||
PCBNEW_SETTINGS* settings = Pgm().GetSettingsManager().GetAppSettings<PCBNEW_SETTINGS>();
|
||||
m_colors = Pgm().GetSettingsManager().GetColorSettings( settings->m_ColorTheme );
|
||||
}
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const
|
||||
{
|
||||
wxASSERT( aLayer < PCB_LAYER_ID_COUNT );
|
||||
@@ -251,7 +260,8 @@ bool BOARD_ADAPTER::Is3dLayerEnabled( PCB_LAYER_ID aLayer ) const
|
||||
|
||||
case B_Cu:
|
||||
case F_Cu:
|
||||
return !m_board || m_board->IsLayerVisible( aLayer ) || m_Cfg->m_Render.realistic;
|
||||
return !m_board || m_board->IsLayerVisible( aLayer ) || m_Cfg->m_Render.realistic
|
||||
|| m_board->IsFootprintHolder();
|
||||
|
||||
default:
|
||||
// the layer is an internal copper layer, used the visibility
|
||||
@@ -647,11 +657,6 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
|
||||
}
|
||||
|
||||
|
||||
extern bool BuildFootprintPolygonOutlines( BOARD* aBoard, SHAPE_POLY_SET& aOutlines,
|
||||
int aErrorMax, int aChainingEpsilon,
|
||||
OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr );
|
||||
|
||||
|
||||
bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg )
|
||||
{
|
||||
m_board_poly.RemoveAllContours();
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
void SetBoard( BOARD* aBoard ) noexcept { m_board = aBoard; }
|
||||
const BOARD* GetBoard() const noexcept { return m_board; }
|
||||
|
||||
void SetColorSettings( COLOR_SETTINGS* aSettings ) noexcept { m_colors = aSettings; }
|
||||
void ReloadColorSettings() noexcept;
|
||||
|
||||
/**
|
||||
* Function to be called by the render when it need to reload the settings for the board.
|
||||
@@ -348,7 +348,7 @@ private:
|
||||
PCB_LAYER_ID aLayerId );
|
||||
|
||||
void addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aDstContainer,
|
||||
const BOARD_ITEM* aOwner );
|
||||
const BOARD_ITEM* aItem );
|
||||
|
||||
void addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aContainer,
|
||||
const BOARD_ITEM* aOwner );
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
|
||||
void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContainer,
|
||||
const BOARD_ITEM* aOwner )
|
||||
const BOARD_ITEM* aItem )
|
||||
{
|
||||
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
|
||||
TEXT_ATTRIBUTES attrs = aText->GetAttributes();
|
||||
@@ -74,34 +74,25 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
|
||||
if( !font )
|
||||
font = KIFONT::FONT::GetFont( wxEmptyString, aText->IsBold(), aText->IsItalic() );
|
||||
|
||||
if( aOwner && aOwner->IsKnockout() )
|
||||
if( aItem && aItem->IsKnockout() )
|
||||
{
|
||||
SHAPE_POLY_SET knockouts;
|
||||
|
||||
CALLBACK_GAL callback_gal( empty_opts,
|
||||
// Polygon callback
|
||||
[&]( const SHAPE_LINE_CHAIN& aPoly )
|
||||
{
|
||||
knockouts.AddOutline( aPoly );
|
||||
} );
|
||||
|
||||
attrs.m_StrokeWidth = aText->GetEffectiveTextPenWidth();
|
||||
attrs.m_Angle = aText->GetDrawRotation();
|
||||
|
||||
callback_gal.SetIsFill( font->IsOutline() );
|
||||
callback_gal.SetIsStroke( font->IsStroke() );
|
||||
callback_gal.SetLineWidth( attrs.m_StrokeWidth );
|
||||
font->Draw( &callback_gal, aText->GetShownText(), aText->GetDrawPos(), attrs );
|
||||
|
||||
int maxError = m_board->GetDesignSettings().m_MaxError;
|
||||
SHAPE_POLY_SET finalPoly;
|
||||
int margin = attrs.m_StrokeWidth * 1.5 +
|
||||
GetKnockoutTextMargin( attrs.m_Size, attrs.m_StrokeWidth );
|
||||
|
||||
aText->TransformBoundingBoxToPolygon( &finalPoly, margin );
|
||||
finalPoly.BooleanSubtract( knockouts, SHAPE_POLY_SET::PM_FAST );
|
||||
finalPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||
if( aItem->Type() == PCB_FP_TEXT_T )
|
||||
{
|
||||
static_cast<const FP_TEXT*>( aItem )->TransformTextToPolySet( finalPoly, 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
}
|
||||
else if( aItem->Type() == PCB_TEXT_T )
|
||||
{
|
||||
static_cast<const PCB_TEXT*>( aItem )->TransformTextToPolySet( finalPoly, 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
}
|
||||
|
||||
ConvertPolygonToTriangles( finalPoly, *aContainer, m_biuTo3Dunits, *aOwner );
|
||||
// Do not call finalPoly.Fracture() here: ConvertPolygonToTriangles() call it
|
||||
// if needed, and Fracture() called twice can create bad results and is useless
|
||||
ConvertPolygonToTriangles( finalPoly, *aContainer, m_biuTo3Dunits, *aItem );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -120,24 +111,24 @@ void BOARD_ADAPTER::addText( const EDA_TEXT* aText, CONTAINER_2D_BASE* aContaine
|
||||
{
|
||||
// Cannot add segments that have the same start and end point
|
||||
aContainer->Add( new FILLED_CIRCLE_2D( pt1_3DU, penWidth_3DU / 2,
|
||||
*aOwner ) );
|
||||
*aItem ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
aContainer->Add( new ROUND_SEGMENT_2D( pt1_3DU, pt2_3DU, penWidth_3DU,
|
||||
*aOwner ) );
|
||||
*aItem ) );
|
||||
}
|
||||
},
|
||||
// Triangulation callback
|
||||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
|
||||
{
|
||||
aContainer->Add( new TRIANGLE_2D( TO_SFVEC2F( aPt1 ), TO_SFVEC2F( aPt2 ),
|
||||
TO_SFVEC2F( aPt3 ), *aOwner ) );
|
||||
TO_SFVEC2F( aPt3 ), *aItem ) );
|
||||
} );
|
||||
|
||||
attrs.m_Angle = aText->GetDrawRotation();
|
||||
|
||||
font->Draw( &callback_gal, aText->GetShownText(), aText->GetDrawPos(), attrs );
|
||||
font->Draw( &callback_gal, aText->GetShownText( true ), aText->GetDrawPos(), attrs );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -649,7 +649,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
{
|
||||
PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
|
||||
|
||||
text->TransformTextToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE );
|
||||
text->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -657,7 +657,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
{
|
||||
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
|
||||
|
||||
textbox->TransformTextToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE );
|
||||
textbox->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -958,7 +958,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
{
|
||||
PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
|
||||
|
||||
text->TransformTextToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE );
|
||||
text->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -966,7 +966,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
||||
{
|
||||
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
|
||||
|
||||
textbox->TransformTextToPolySet( *layerPoly, layer, 0, maxError, ERROR_INSIDE );
|
||||
textbox->TransformTextToPolySet( *layerPoly, 0, maxError, ERROR_INSIDE );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <3d_rendering/raytracing/render_3d_raytrace.h>
|
||||
#include <3d_rendering/opengl/render_3d_opengl.h>
|
||||
#include <3d_viewer_id.h>
|
||||
#include <advanced_config.h>
|
||||
#include <board.h>
|
||||
#include <reporter.h>
|
||||
#include <gl_context_mgr.h>
|
||||
@@ -140,7 +141,7 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const int* aAttribList,
|
||||
// long calculation time)
|
||||
m_3d_render = m_3d_render_opengl;
|
||||
|
||||
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
|
||||
m_boardAdapter.ReloadColorSettings();
|
||||
|
||||
wxASSERT( a3DCachePointer != nullptr );
|
||||
m_boardAdapter.Set3dCacheManager( a3DCachePointer );
|
||||
@@ -303,7 +304,7 @@ void EDA_3D_CANVAS::ReloadRequest( BOARD* aBoard , S3D_CACHE* aCachePointer )
|
||||
if( aBoard != nullptr )
|
||||
m_boardAdapter.SetBoard( aBoard );
|
||||
|
||||
m_boardAdapter.SetColorSettings( Pgm().GetSettingsManager().GetColorSettings() );
|
||||
m_boardAdapter.ReloadColorSettings();
|
||||
|
||||
if( m_3d_render )
|
||||
m_3d_render->ReloadRequest();
|
||||
@@ -531,13 +532,11 @@ void EDA_3D_CANVAS::DoRePaint()
|
||||
render_pivot( curtime_delta_s, scale );
|
||||
}
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_render3dmousePivot )
|
||||
if( m_render3dmousePivot && ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
{
|
||||
const float scale = glm::min( m_camera.GetZoom(), 1.0f );
|
||||
render3dmousePivot( scale );
|
||||
}
|
||||
#endif
|
||||
|
||||
// "Swaps the double-buffer of this window, making the back-buffer the
|
||||
// front-buffer and vice versa, so that the output of the previous OpenGL
|
||||
|
||||
@@ -178,8 +178,6 @@ public:
|
||||
*/
|
||||
void SetRenderPivot( bool aValue ) { m_render_pivot = aValue; }
|
||||
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
/**
|
||||
* Get a value indicating whether to render the 3dmouse pivot.
|
||||
*/
|
||||
@@ -209,7 +207,6 @@ public:
|
||||
{
|
||||
m_3dmousePivotPos = aPos;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -278,14 +275,12 @@ private:
|
||||
*/
|
||||
void render_pivot( float t, float aScale );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
/**
|
||||
* Render the 3dmouse pivot cursor.
|
||||
*
|
||||
* @param aScale scale to apply on the cursor.
|
||||
*/
|
||||
void render3dmousePivot( float aScale );
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @return true if OpenGL initialization succeeded.
|
||||
@@ -331,10 +326,8 @@ private:
|
||||
|
||||
BOARD_ITEM* m_currentRollOverItem;
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
bool m_render3dmousePivot = false; // Render the 3dmouse pivot
|
||||
SFVEC3F m_3dmousePivotPos; // The position of the 3dmouse pivot
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
|
||||
@@ -120,7 +120,6 @@ void EDA_3D_CANVAS::render_pivot( float t, float aScale )
|
||||
}
|
||||
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
void EDA_3D_CANVAS::render3dmousePivot( float aScale )
|
||||
{
|
||||
wxASSERT( aScale >= 0.0f );
|
||||
@@ -160,4 +159,3 @@ void EDA_3D_CANVAS::render3dmousePivot( float aScale )
|
||||
glDisable( GL_BLEND );
|
||||
glDisable( GL_POINT_SMOOTH );
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
add_library(3d-viewer_navlib STATIC
|
||||
"nl_3d_viewer_plugin.cpp"
|
||||
"nl_3d_viewer_plugin_impl.cpp"
|
||||
@@ -23,9 +22,4 @@ if( KICAD_USE_3DCONNEXION )
|
||||
$<TARGET_PROPERTY:3DxWare::Navlib,INTERFACE_LINK_LIBRARIES>
|
||||
3DxWare::Navlib
|
||||
)
|
||||
else()
|
||||
add_library(3d-viewer_navlib STATIC
|
||||
"nl_3d_viewer_plugin.cpp"
|
||||
)
|
||||
endif(KICAD_USE_3DCONNEXION)
|
||||
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
*/
|
||||
|
||||
#include "nl_3d_viewer_plugin.h"
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
#include "nl_3d_viewer_plugin_impl.h"
|
||||
#include <advanced_config.h>
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport ) :
|
||||
m_impl( new NL_3D_VIEWER_PLUGIN_IMPL( aViewport ) )
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport )
|
||||
{
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_impl = new NL_3D_VIEWER_PLUGIN_IMPL( aViewport );
|
||||
}
|
||||
|
||||
|
||||
@@ -38,22 +38,6 @@ NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
|
||||
{
|
||||
m_impl->SetFocus( focus );
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_impl->SetFocus( focus );
|
||||
}
|
||||
#else
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::NL_3D_VIEWER_PLUGIN( EDA_3D_CANVAS* aViewport ) : m_impl( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void NL_3D_VIEWER_PLUGIN::SetFocus( bool focus )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NL_3D_VIEWER_PLUGIN::~NL_3D_VIEWER_PLUGIN()
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <board.h>
|
||||
#include <footprint.h>
|
||||
#include "../../3d_math.h"
|
||||
#include "convert_basic_shapes_to_polygon.h"
|
||||
#include <trigo.h>
|
||||
#include <project.h>
|
||||
#include <profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
@@ -775,6 +776,9 @@ void RENDER_3D_OPENGL::generateViasAndPads()
|
||||
{
|
||||
const PCB_VIA* via = static_cast<const PCB_VIA*>( track );
|
||||
|
||||
if( via->GetViaType() == VIATYPE::THROUGH )
|
||||
continue; // handle with pad holes so castellation is taken into account
|
||||
|
||||
const float holediameter = via->GetDrillValue() * m_boardAdapter.BiuTo3dUnits();
|
||||
const int nrSegments = m_boardAdapter.GetCircleSegmentCount( via->GetDrillValue() );
|
||||
const float hole_inner_radius = holediameter / 2.0f;
|
||||
@@ -804,14 +808,33 @@ void RENDER_3D_OPENGL::generateViasAndPads()
|
||||
}
|
||||
|
||||
|
||||
if( m_boardAdapter.GetHoleCount() > 0 )
|
||||
if( m_boardAdapter.GetHoleCount() > 0 || m_boardAdapter.GetViaCount() > 0 )
|
||||
{
|
||||
SHAPE_POLY_SET tht_outer_holes_poly; // Stores the outer poly of the copper holes (the pad)
|
||||
SHAPE_POLY_SET tht_inner_holes_poly; // Stores the inner poly of the copper holes (the hole)
|
||||
SHAPE_POLY_SET tht_outer_holes_poly; // Stores the outer poly of the copper holes
|
||||
SHAPE_POLY_SET tht_inner_holes_poly; // Stores the inner poly of the copper holes
|
||||
|
||||
tht_outer_holes_poly.RemoveAllContours();
|
||||
tht_inner_holes_poly.RemoveAllContours();
|
||||
|
||||
// Insert through-via holes (vertical cylinders)
|
||||
for( const PCB_TRACK* track : m_boardAdapter.GetBoard()->Tracks() )
|
||||
{
|
||||
if( track->Type() == PCB_VIA_T )
|
||||
{
|
||||
const PCB_VIA* via = static_cast<const PCB_VIA*>( track );
|
||||
|
||||
if( via->GetViaType() == VIATYPE::THROUGH )
|
||||
{
|
||||
TransformCircleToPolygon( tht_outer_holes_poly, via->GetPosition(),
|
||||
via->GetDrill() / 2 + platingThickness,
|
||||
ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
|
||||
TransformCircleToPolygon( tht_inner_holes_poly, via->GetPosition(),
|
||||
via->GetDrill() / 2, ARC_HIGH_DEF, ERROR_INSIDE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert pads holes (vertical cylinders)
|
||||
for( const FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
|
||||
{
|
||||
@@ -903,7 +926,9 @@ void RENDER_3D_OPENGL::Load3dModelsIfNeeded()
|
||||
load3dModels( &activityReporter );
|
||||
}
|
||||
else
|
||||
{
|
||||
load3dModels( nullptr );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -802,11 +802,14 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
{
|
||||
setLayerMaterial( layer_id );
|
||||
|
||||
OPENGL_RENDER_LIST* throughHolesOuter =
|
||||
m_boardAdapter.m_Cfg->m_Render.clip_silk_on_via_annulus
|
||||
&& m_boardAdapter.m_Cfg->m_Render.realistic
|
||||
&& ( layer_id == B_SilkS || layer_id == F_SilkS ) ? m_outerThroughHoleRings
|
||||
: m_outerThroughHoles;
|
||||
OPENGL_RENDER_LIST* throughHolesOuter = m_outerThroughHoles;
|
||||
|
||||
if( m_boardAdapter.m_Cfg->m_Render.clip_silk_on_via_annulus
|
||||
&& m_boardAdapter.m_Cfg->m_Render.realistic
|
||||
&& ( layer_id == B_SilkS || layer_id == F_SilkS ) )
|
||||
{
|
||||
throughHolesOuter = m_outerThroughHoleRings;
|
||||
}
|
||||
|
||||
if( throughHolesOuter )
|
||||
{
|
||||
@@ -824,11 +827,20 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
- pLayerDispList->GetZBot() );
|
||||
}
|
||||
|
||||
if( !skipRenderHoles
|
||||
&& m_boardAdapter.m_Cfg->m_Render.subtract_mask_from_silk
|
||||
&& m_boardAdapter.m_Cfg->m_Render.realistic
|
||||
&& ( ( layer_id == B_SilkS && m_layers.find( B_Mask ) != m_layers.end() )
|
||||
|| ( layer_id == F_SilkS && m_layers.find( F_Mask ) != m_layers.end() ) ) )
|
||||
if( skipRenderHoles )
|
||||
{
|
||||
// Do not render Paste layers when skipRenderHoles is enabled
|
||||
// otherwise it will cause z-fight issues
|
||||
if( layer_id != B_Paste && layer_id != F_Paste )
|
||||
{
|
||||
pLayerDispList->DrawAllCameraCulledSubtractLayer( drawMiddleSegments,
|
||||
anti_board );
|
||||
}
|
||||
}
|
||||
else if( m_boardAdapter.m_Cfg->m_Render.subtract_mask_from_silk
|
||||
&& m_boardAdapter.m_Cfg->m_Render.realistic
|
||||
&& ( ( layer_id == B_SilkS && m_layers.find( B_Mask ) != m_layers.end() )
|
||||
|| ( layer_id == F_SilkS && m_layers.find( F_Mask ) != m_layers.end() ) ) )
|
||||
{
|
||||
const PCB_LAYER_ID layerMask_id = (layer_id == B_SilkS) ? B_Mask : F_Mask;
|
||||
|
||||
@@ -838,25 +850,16 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
pLayerDispListMask,
|
||||
throughHolesOuter, anti_board );
|
||||
}
|
||||
else if( throughHolesOuter )
|
||||
{
|
||||
pLayerDispList->DrawAllCameraCulledSubtractLayer( drawMiddleSegments, nullptr,
|
||||
throughHolesOuter,
|
||||
anti_board );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !skipRenderHoles && throughHolesOuter
|
||||
&& ( layer_id == B_SilkS || layer_id == F_SilkS ) )
|
||||
{
|
||||
pLayerDispList->DrawAllCameraCulledSubtractLayer( drawMiddleSegments, nullptr,
|
||||
throughHolesOuter,
|
||||
anti_board );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do not render Paste layers when skipRenderHoles is enabled
|
||||
// otherwise it will cause z-fight issues
|
||||
if( !( skipRenderHoles && ( layer_id == B_Paste || layer_id == F_Paste ) ) )
|
||||
{
|
||||
pLayerDispList->DrawAllCameraCulledSubtractLayer( drawMiddleSegments,
|
||||
anti_board );
|
||||
}
|
||||
}
|
||||
pLayerDispList->DrawAllCameraCulledSubtractLayer( drawMiddleSegments,
|
||||
anti_board );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -931,10 +931,33 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
{
|
||||
float ratio =
|
||||
std::max( 1.0f, m_objectContainer.GetBBox().GetMaxDimension() / RANGE_SCALE_3D );
|
||||
m_camera.SetMaxZoom( CAMERA::DEFAULT_MAX_ZOOM * ratio );
|
||||
|
||||
m_camera.SetMinZoom( static_cast<float>( MIN_DISTANCE_IU * m_boardAdapter.BiuTo3dUnits()
|
||||
/ -m_camera.GetCameraInitPos().z ) );
|
||||
float max_zoom = CAMERA::DEFAULT_MAX_ZOOM * ratio;
|
||||
float min_zoom = static_cast<float>( MIN_DISTANCE_IU * m_boardAdapter.BiuTo3dUnits()
|
||||
/ -m_camera.GetCameraInitPos().z );
|
||||
|
||||
if( min_zoom > max_zoom )
|
||||
std::swap( min_zoom, max_zoom );
|
||||
|
||||
float zoom_ratio = max_zoom / min_zoom;
|
||||
|
||||
// Set the minimum number of zoom 'steps' between max and min.
|
||||
int steps = 3 * 3;
|
||||
steps -= static_cast<int>( ceil( log( zoom_ratio ) / log( 1.26f ) ) );
|
||||
steps = std::max( steps, 0 );
|
||||
|
||||
// Resize max and min zoom to accomplish the number of steps.
|
||||
float increased_zoom = pow( 1.26f, steps / 2 );
|
||||
max_zoom *= increased_zoom;
|
||||
min_zoom /= increased_zoom;
|
||||
|
||||
if( steps & 1 )
|
||||
min_zoom /= 1.26f;
|
||||
|
||||
min_zoom = std::min( min_zoom, 1.0f );
|
||||
|
||||
m_camera.SetMaxZoom( max_zoom );
|
||||
m_camera.SetMinZoom( min_zoom );
|
||||
}
|
||||
|
||||
// Create an accelerator
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <3d_viewer/tools/eda_3d_actions.h>
|
||||
#include <3d_viewer/tools/eda_3d_controller.h>
|
||||
#include <3d_viewer/tools/eda_3d_conditions.h>
|
||||
#include <advanced_config.h>
|
||||
#include <bitmaps.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <core/arraydim.h>
|
||||
@@ -56,9 +57,7 @@
|
||||
#include <widgets/wx_infobar.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
#include <3d_navlib/nl_3d_viewer_plugin.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Flag to enable 3D viewer main frame window debug tracing.
|
||||
@@ -166,16 +165,18 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
|
||||
m_canvas->SetInfoBar( m_infoBar );
|
||||
m_canvas->SetStatusBar( status_bar );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
try
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
{
|
||||
m_spaceMouse = new NL_3D_VIEWER_PLUGIN( m_canvas );
|
||||
try
|
||||
{
|
||||
m_spaceMouse = new NL_3D_VIEWER_PLUGIN( m_canvas );
|
||||
}
|
||||
catch( const std::system_error& e )
|
||||
{
|
||||
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
|
||||
}
|
||||
}
|
||||
catch( const std::system_error& e )
|
||||
{
|
||||
wxLogTrace( wxT( "KI_TRACE_NAVLIB" ), e.what() );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fixes bug in Windows (XP and possibly others) where the canvas requires the focus
|
||||
// in order to receive mouse events. Otherwise, the user has to click somewhere on
|
||||
@@ -193,12 +194,7 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
|
||||
|
||||
EDA_3D_VIEWER_FRAME::~EDA_3D_VIEWER_FRAME()
|
||||
{
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse != nullptr )
|
||||
{
|
||||
delete m_spaceMouse;
|
||||
}
|
||||
#endif
|
||||
delete m_spaceMouse;
|
||||
|
||||
Prj().GetProjectFile().m_Viewports3D = GetUserViewports();
|
||||
|
||||
@@ -334,12 +330,11 @@ void EDA_3D_VIEWER_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent )
|
||||
{
|
||||
KIWAY_PLAYER::handleIconizeEvent( aEvent );
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse != nullptr && aEvent.IsIconized() )
|
||||
if( m_spaceMouse != nullptr && aEvent.IsIconized()
|
||||
&& ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
{
|
||||
m_spaceMouse->SetFocus( false );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -655,12 +650,8 @@ void EDA_3D_VIEWER_FRAME::OnActivate( wxActivateEvent &aEvent )
|
||||
m_canvas->SetFocus();
|
||||
}
|
||||
|
||||
#if defined( KICAD_USE_3DCONNEXION )
|
||||
if( m_spaceMouse != nullptr )
|
||||
{
|
||||
if( m_spaceMouse != nullptr && ADVANCED_CFG::GetCfg().m_Use3DConnexionDriver )
|
||||
m_spaceMouse->SetFocus( aEvent.GetActive() );
|
||||
}
|
||||
#endif
|
||||
|
||||
aEvent.Skip(); // required under wxMAC
|
||||
}
|
||||
|
||||
@@ -122,8 +122,6 @@ target_link_libraries( 3d-viewer
|
||||
|
||||
add_subdirectory( 3d_cache )
|
||||
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in 3d-viewer" )
|
||||
add_subdirectory( 3d_navlib )
|
||||
target_link_libraries( 3d-viewer PRIVATE 3d-viewer_navlib)
|
||||
endif()
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in 3d-viewer" )
|
||||
add_subdirectory( 3d_navlib )
|
||||
target_link_libraries( 3d-viewer PRIVATE 3d-viewer_navlib)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-39-g3487c3cb)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -26,7 +26,7 @@ PANEL_3D_RAYTRACING_OPTIONS_BASE::PANEL_3D_RAYTRACING_OPTIONS_BASE( wxWindow* pa
|
||||
|
||||
m_cbRaytracing_proceduralTextures = new wxCheckBox( this, wxID_ANY, _("Procedural textures (slow)"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_cbRaytracing_proceduralTextures->SetValue(true);
|
||||
gSizer1->Add( m_cbRaytracing_proceduralTextures, 0, wxALL, 5 );
|
||||
gSizer1->Add( m_cbRaytracing_proceduralTextures, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
m_cbRaytracing_addFloor = new wxCheckBox( this, wxID_ANY, _("Add floor (slow)"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_cbRaytracing_addFloor->SetValue(true);
|
||||
@@ -347,6 +347,7 @@ PANEL_3D_RAYTRACING_OPTIONS_BASE::PANEL_3D_RAYTRACING_OPTIONS_BASE( wxWindow* pa
|
||||
|
||||
this->SetSizer( bSizerMain );
|
||||
this->Layout();
|
||||
bSizerMain->Fit( this );
|
||||
}
|
||||
|
||||
PANEL_3D_RAYTRACING_OPTIONS_BASE::~PANEL_3D_RAYTRACING_OPTIONS_BASE()
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">PANEL_3D_RAYTRACING_OPTIONS_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">834,514</property>
|
||||
<property name="size">-1,-1</property>
|
||||
<property name="subclass">RESETTABLE_PANEL; widgets/resettable_panel.h; forward_declare</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
@@ -190,7 +190,7 @@
|
||||
<property name="vgap">0</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxCheckBox" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-39-g3487c3cb)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -103,7 +103,7 @@ class PANEL_3D_RAYTRACING_OPTIONS_BASE : public RESETTABLE_PANEL
|
||||
|
||||
public:
|
||||
|
||||
PANEL_3D_RAYTRACING_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 834,514 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
|
||||
PANEL_3D_RAYTRACING_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
|
||||
|
||||
~PANEL_3D_RAYTRACING_OPTIONS_BASE();
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
|
||||
#include "panel_preview_3d_model.h"
|
||||
#include <dialogs/dialog_unit_entry.h>
|
||||
#include <3d_canvas/eda_3d_canvas.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tool_dispatcher.h>
|
||||
@@ -46,24 +47,26 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
FOOTPRINT* aFootprint,
|
||||
std::vector<FP_3DMODEL>* aParentModelList ) :
|
||||
PANEL_PREVIEW_3D_MODEL_BASE( aParent, wxID_ANY ),
|
||||
m_parentFrame( aFrame ),
|
||||
m_previewPane( nullptr ),
|
||||
m_infobar( nullptr ),
|
||||
m_boardAdapter(),
|
||||
m_currentCamera( m_trackBallCamera ),
|
||||
m_trackBallCamera( 2 * RANGE_SCALE_3D ),
|
||||
m_boardThickness( aFrame, nullptr, m_boardThicknessCtrl, m_boardThicknessUnits )
|
||||
m_trackBallCamera( 2 * RANGE_SCALE_3D )
|
||||
{
|
||||
m_userUnits = aFrame->GetUserUnits();
|
||||
m_userUnits = m_parentFrame->GetUserUnits();
|
||||
|
||||
m_dummyBoard = new BOARD();
|
||||
|
||||
m_dummyBoard->SetProject( &aFrame->Prj(), true );
|
||||
|
||||
// This board will only be used to hold a footprint for viewing
|
||||
m_dummyBoard->SetBoardUse( BOARD_USE::FPHOLDER );
|
||||
|
||||
BOARD_DESIGN_SETTINGS parent_bds = aFrame->GetDesignSettings();
|
||||
BOARD_DESIGN_SETTINGS dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
BOARD_DESIGN_SETTINGS& dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
dummy_bds.SetBoardThickness( parent_bds.GetBoardThickness() );
|
||||
dummy_bds.SetEnabledLayers( LSET::FrontMask() | LSET::BackMask() );
|
||||
BOARD_STACKUP& dummy_board_stackup = m_dummyBoard->GetDesignSettings().GetStackupDescriptor();
|
||||
dummy_board_stackup.RemoveAll();
|
||||
dummy_board_stackup.BuildDefaultStackupList( &dummy_bds, 2 );
|
||||
@@ -81,6 +84,7 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
m_bpvBottom->SetBitmap( KiBitmap( BITMAPS::axis3d_bottom ) );
|
||||
m_bpvISO->SetBitmap( KiBitmap( BITMAPS::ortho ) );
|
||||
m_bpUpdate->SetBitmap( KiBitmap( BITMAPS::reload ) );
|
||||
m_bpSettings->SetBitmap( KiBitmap( BITMAPS::options_3drender ) );
|
||||
|
||||
// Set the min and max values of spin buttons (mandatory on Linux)
|
||||
// They are not used, so they are set to min and max 32 bits int values
|
||||
@@ -101,6 +105,15 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
|
||||
m_dummyFootprint = new FOOTPRINT( *aFootprint );
|
||||
m_dummyFootprint->SetParentGroup( nullptr );
|
||||
|
||||
// Ensure the footprint is shown like in Fp editor: rot 0, not flipped
|
||||
// to avoid mistakes when setting the3D shape position/rotation
|
||||
if( m_dummyFootprint->IsFlipped() )
|
||||
m_dummyFootprint->Flip( m_dummyFootprint->GetPosition(), false );
|
||||
|
||||
m_dummyFootprint->SetOrientation( ANGLE_0 );
|
||||
|
||||
|
||||
m_dummyBoard->Add( m_dummyFootprint );
|
||||
|
||||
// Create the 3D canvas
|
||||
@@ -162,6 +175,7 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
m_bpvBottom->SetMinSize( m_bpvBottom->GetSize() + borderFix );
|
||||
m_bpvISO->SetMinSize( m_bpvISO->GetSize() + borderFix );
|
||||
m_bpUpdate->SetMinSize( m_bpUpdate->GetSize() + borderFix );
|
||||
m_bpSettings->SetMinSize( m_bpSettings->GetSize() + borderFix );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -325,9 +339,6 @@ void PANEL_PREVIEW_3D_MODEL::SetSelectedModel( int idx )
|
||||
|
||||
m_opacity->SetValue( 100 );
|
||||
}
|
||||
|
||||
BOARD_DESIGN_SETTINGS dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
m_boardThickness.ChangeValue( dummy_bds.GetBoardThickness() );
|
||||
}
|
||||
|
||||
|
||||
@@ -380,16 +391,27 @@ void PANEL_PREVIEW_3D_MODEL::onOpacitySlider( wxCommandEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::updateBoardThickness( wxCommandEvent& event )
|
||||
void PANEL_PREVIEW_3D_MODEL::View3DSettings( wxCommandEvent& event )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS dummy_bds = m_dummyBoard->GetDesignSettings();
|
||||
dummy_bds.SetBoardThickness( m_boardThickness.GetValue() );
|
||||
BOARD_DESIGN_SETTINGS bds = m_dummyBoard->GetDesignSettings();
|
||||
int thickness = bds.GetBoardThickness();
|
||||
|
||||
BOARD_STACKUP& dummy_board_stackup = m_dummyBoard->GetDesignSettings().GetStackupDescriptor();
|
||||
dummy_board_stackup.RemoveAll();
|
||||
dummy_board_stackup.BuildDefaultStackupList( &dummy_bds, 2 );
|
||||
WX_UNIT_ENTRY_DIALOG dlg( m_parentFrame, _( "Board Thickness: " ),
|
||||
_( "Preview Settings" ), thickness );
|
||||
|
||||
if( dlg.ShowModal() != wxID_OK )
|
||||
return;
|
||||
|
||||
bds.SetBoardThickness( (int) dlg.GetValue() );
|
||||
|
||||
BOARD_STACKUP& boardStackup = m_dummyBoard->GetDesignSettings().GetStackupDescriptor();
|
||||
boardStackup.RemoveAll();
|
||||
boardStackup.BuildDefaultStackupList( &bds, 2 );
|
||||
|
||||
UpdateDummyFootprint( true );
|
||||
|
||||
m_previewPane->ReloadRequest();
|
||||
m_previewPane->Refresh();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -135,8 +135,6 @@ private:
|
||||
|
||||
void onOpacitySlider( wxCommandEvent& event ) override;
|
||||
|
||||
void updateBoardThickness( wxCommandEvent& event ) override;
|
||||
|
||||
void doIncrementScale( wxSpinEvent& aEvent, double aSign );
|
||||
void doIncrementRotation( wxSpinEvent& aEvent, double aSign );
|
||||
void doIncrementOffset( wxSpinEvent& aEvent, double aSign );
|
||||
@@ -174,6 +172,8 @@ private:
|
||||
m_previewPane->Refresh();
|
||||
}
|
||||
|
||||
void View3DSettings( wxCommandEvent& event ) override;
|
||||
|
||||
void View3DRight( wxCommandEvent& event ) override
|
||||
{
|
||||
m_previewPane->SetView3D( ID_VIEW3D_RIGHT );
|
||||
@@ -190,6 +190,7 @@ private:
|
||||
}
|
||||
|
||||
private:
|
||||
PCB_BASE_FRAME* m_parentFrame;
|
||||
EDA_3D_CANVAS* m_previewPane;
|
||||
WX_INFOBAR* m_infobar;
|
||||
BOARD_ADAPTER m_boardAdapter;
|
||||
@@ -202,7 +203,6 @@ private:
|
||||
std::vector<FP_3DMODEL>* m_parentModelList;
|
||||
int m_selected; /// Index into m_parentInfoList
|
||||
|
||||
UNIT_BINDER m_boardThickness;
|
||||
EDA_UNITS m_userUnits;
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
sbSizerScale = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Scale") ), wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizerScale;
|
||||
fgSizerScale = new wxFlexGridSizer( 0, 3, 3, 3 );
|
||||
fgSizerScale = new wxFlexGridSizer( 0, 3, 2, 3 );
|
||||
fgSizerScale->AddGrowableCol( 1 );
|
||||
fgSizerScale->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerScale->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
@@ -66,7 +66,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
sbSizerRotation = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Rotation") ), wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizerRotate;
|
||||
fgSizerRotate = new wxFlexGridSizer( 0, 3, 3, 3 );
|
||||
fgSizerRotate = new wxFlexGridSizer( 0, 3, 2, 3 );
|
||||
fgSizerRotate->AddGrowableCol( 1 );
|
||||
fgSizerRotate->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerRotate->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
@@ -111,7 +111,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
sbSizerOffset = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Offset") ), wxVERTICAL );
|
||||
|
||||
wxFlexGridSizer* fgSizerOffset;
|
||||
fgSizerOffset = new wxFlexGridSizer( 0, 3, 3, 3 );
|
||||
fgSizerOffset = new wxFlexGridSizer( 0, 3, 2, 3 );
|
||||
fgSizerOffset->AddGrowableCol( 1 );
|
||||
fgSizerOffset->SetFlexibleDirection( wxBOTH );
|
||||
fgSizerOffset->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
@@ -159,20 +159,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
sbSizer4->Add( m_opacity, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
|
||||
bSizerLeft->Add( sbSizer4, 1, wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
wxStaticBoxSizer* sbSizerBoardThickness;
|
||||
sbSizerBoardThickness = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Board Thickness") ), wxHORIZONTAL );
|
||||
|
||||
m_boardThicknessCtrl = new wxTextCtrl( sbSizerBoardThickness->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
sbSizerBoardThickness->Add( m_boardThicknessCtrl, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_boardThicknessUnits = new wxStaticText( sbSizerBoardThickness->GetStaticBox(), wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_boardThicknessUnits->Wrap( -1 );
|
||||
sbSizerBoardThickness->Add( m_boardThicknessUnits, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
|
||||
bSizerLeft->Add( sbSizerBoardThickness, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
|
||||
bSizerLeft->Add( sbSizer4, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizerLeft, 0, 0, 5 );
|
||||
@@ -195,7 +182,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
m_SizerPanelView = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
|
||||
bSizerRight->Add( m_SizerPanelView, 1, wxEXPAND|wxBOTTOM, 8 );
|
||||
bSizerRight->Add( m_SizerPanelView, 1, wxEXPAND|wxBOTTOM, 5 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizerRight, 1, wxRIGHT|wxLEFT|wxEXPAND, 5 );
|
||||
@@ -212,7 +199,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
bSizer3DButtons->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_bpvLeft = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
|
||||
bSizer3DButtons->Add( m_bpvLeft, 0, wxALIGN_LEFT|wxALIGN_RIGHT|wxBOTTOM, 5 );
|
||||
bSizer3DButtons->Add( m_bpvLeft, 0, wxBOTTOM, 5 );
|
||||
|
||||
m_bpvRight = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
|
||||
bSizer3DButtons->Add( m_bpvRight, 0, wxBOTTOM, 5 );
|
||||
@@ -237,6 +224,9 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
|
||||
bSizer3DButtons->Add( m_bpUpdate, 0, wxBOTTOM, 5 );
|
||||
|
||||
m_bpSettings = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
bSizer3DButtons->Add( m_bpSettings, 0, 0, 5 );
|
||||
|
||||
|
||||
bSizermain->Add( bSizer3DButtons, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
|
||||
|
||||
@@ -283,8 +273,6 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
m_spinZoffset->Connect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinZoffset->Connect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onIncrementOffset ), NULL, this );
|
||||
m_opacity->Connect( wxEVT_SLIDER, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onOpacitySlider ), NULL, this );
|
||||
m_boardThicknessCtrl->Connect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onMouseWheelBoardThickness ), NULL, this );
|
||||
m_boardThicknessCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::updateBoardThickness ), NULL, this );
|
||||
m_bpvISO->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DISO ), NULL, this );
|
||||
m_bpvLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DLeft ), NULL, this );
|
||||
m_bpvRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DRight ), NULL, this );
|
||||
@@ -293,6 +281,7 @@ PANEL_PREVIEW_3D_MODEL_BASE::PANEL_PREVIEW_3D_MODEL_BASE( wxWindow* parent, wxWi
|
||||
m_bpvTop->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DTop ), NULL, this );
|
||||
m_bpvBottom->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DBottom ), NULL, this );
|
||||
m_bpUpdate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DUpdate ), NULL, this );
|
||||
m_bpSettings->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DSettings ), NULL, this );
|
||||
}
|
||||
|
||||
PANEL_PREVIEW_3D_MODEL_BASE::~PANEL_PREVIEW_3D_MODEL_BASE()
|
||||
@@ -335,8 +324,6 @@ PANEL_PREVIEW_3D_MODEL_BASE::~PANEL_PREVIEW_3D_MODEL_BASE()
|
||||
m_spinZoffset->Disconnect( wxEVT_SCROLL_LINEDOWN, wxSpinEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onDecrementOffset ), NULL, this );
|
||||
m_spinZoffset->Disconnect( wxEVT_SCROLL_LINEUP, wxSpinEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onIncrementOffset ), NULL, this );
|
||||
m_opacity->Disconnect( wxEVT_SLIDER, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onOpacitySlider ), NULL, this );
|
||||
m_boardThicknessCtrl->Disconnect( wxEVT_MOUSEWHEEL, wxMouseEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::onMouseWheelBoardThickness ), NULL, this );
|
||||
m_boardThicknessCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::updateBoardThickness ), NULL, this );
|
||||
m_bpvISO->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DISO ), NULL, this );
|
||||
m_bpvLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DLeft ), NULL, this );
|
||||
m_bpvRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DRight ), NULL, this );
|
||||
@@ -345,5 +332,6 @@ PANEL_PREVIEW_3D_MODEL_BASE::~PANEL_PREVIEW_3D_MODEL_BASE()
|
||||
m_bpvTop->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DTop ), NULL, this );
|
||||
m_bpvBottom->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DBottom ), NULL, this );
|
||||
m_bpUpdate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DUpdate ), NULL, this );
|
||||
m_bpSettings->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_PREVIEW_3D_MODEL_BASE::View3DSettings ), NULL, this );
|
||||
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="rows">0</property>
|
||||
<property name="vgap">3</property>
|
||||
<property name="vgap">2</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
|
||||
@@ -686,7 +686,7 @@
|
||||
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="rows">0</property>
|
||||
<property name="vgap">3</property>
|
||||
<property name="vgap">2</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
|
||||
@@ -1279,7 +1279,7 @@
|
||||
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
|
||||
<property name="permission">none</property>
|
||||
<property name="rows">0</property>
|
||||
<property name="vgap">3</property>
|
||||
<property name="vgap">2</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT</property>
|
||||
@@ -1847,7 +1847,7 @@
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
|
||||
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxStaticBoxSizer" expanded="1">
|
||||
<property name="id">wxID_ANY</property>
|
||||
@@ -1925,147 +1925,6 @@
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticBoxSizer" expanded="1">
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Board Thickness</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">sbSizerBoardThickness</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="parent">1</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxTextCtrl" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="maxlength"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_boardThicknessCtrl</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnMouseWheel">onMouseWheelBoardThickness</event>
|
||||
<event name="OnText">updateBoardThickness</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">mm</property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_boardThicknessUnits</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
@@ -2150,7 +2009,7 @@
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">8</property>
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxBOTTOM</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
@@ -2257,7 +2116,7 @@
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_LEFT|wxALIGN_RIGHT|wxBOTTOM</property>
|
||||
<property name="flag">wxBOTTOM</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBitmapButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
@@ -2783,6 +2642,80 @@
|
||||
<event name="OnButtonClick">View3DUpdate</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag"></property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBitmapButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="auth_needed">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="bitmap"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="current"></property>
|
||||
<property name="default">0</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="disabled"></property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="focus"></property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">MyButton</property>
|
||||
<property name="margins"></property>
|
||||
<property name="markup">0</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_bpSettings</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="position"></property>
|
||||
<property name="pressed"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick">View3DSettings</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
@@ -66,8 +66,6 @@ class PANEL_PREVIEW_3D_MODEL_BASE : public wxPanel
|
||||
wxTextCtrl* zoff;
|
||||
wxSpinButton* m_spinZoffset;
|
||||
wxSlider* m_opacity;
|
||||
wxTextCtrl* m_boardThicknessCtrl;
|
||||
wxStaticText* m_boardThicknessUnits;
|
||||
wxStaticText* m_previewLabel;
|
||||
wxBoxSizer* m_SizerPanelView;
|
||||
wxBitmapButton* m_bpvISO;
|
||||
@@ -78,6 +76,7 @@ class PANEL_PREVIEW_3D_MODEL_BASE : public wxPanel
|
||||
wxBitmapButton* m_bpvTop;
|
||||
wxBitmapButton* m_bpvBottom;
|
||||
wxBitmapButton* m_bpUpdate;
|
||||
wxBitmapButton* m_bpSettings;
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void onMouseWheelScale( wxMouseEvent& event ) { event.Skip(); }
|
||||
@@ -91,8 +90,6 @@ class PANEL_PREVIEW_3D_MODEL_BASE : public wxPanel
|
||||
virtual void onDecrementOffset( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onIncrementOffset( wxSpinEvent& event ) { event.Skip(); }
|
||||
virtual void onOpacitySlider( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onMouseWheelBoardThickness( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void updateBoardThickness( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DISO( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DLeft( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DRight( wxCommandEvent& event ) { event.Skip(); }
|
||||
@@ -101,6 +98,7 @@ class PANEL_PREVIEW_3D_MODEL_BASE : public wxPanel
|
||||
virtual void View3DTop( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DBottom( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DUpdate( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void View3DSettings( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@@ -53,6 +53,13 @@ set( CMAKE_EXPORT_COMPILE_COMMANDS ON )
|
||||
set( KICAD_CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" )
|
||||
set( CMAKE_MODULE_PATH "${KICAD_CMAKE_MODULE_PATH}" )
|
||||
|
||||
# Create a flag to identify the non-Apple unix systems
|
||||
if( UNIX AND NOT APPLE )
|
||||
set( UNIX_NOT_APPLE ON )
|
||||
else()
|
||||
set( UNIX_NOT_APPLE OFF )
|
||||
endif()
|
||||
|
||||
# On Windows, binaries created by link option -g3 are very large (more than 1Gb for pcbnew,
|
||||
# and more than 3Gb for the full kicad suite)
|
||||
# This option create binaries using link option -g1 that create much smaller files, but
|
||||
@@ -93,6 +100,17 @@ option( KICAD_I18N_UNIX_STRICT_PATH
|
||||
"Use standard Unix locale lookup path (default OFF)."
|
||||
OFF )
|
||||
|
||||
# Options to build with flatpak platform defaults (only on Linux)
|
||||
cmake_dependent_option( KICAD_BUILD_FLATPAK
|
||||
"Build KiCad with metadata, launchers, icons, and MIME info following flatpak conventions"
|
||||
OFF "UNIX_NOT_APPLE"
|
||||
OFF )
|
||||
|
||||
cmake_dependent_option( KICAD_BUILD_NIGHTLY_FLATPAK
|
||||
"Build a Nightly flatpak (requires KICAD_BUILD_FLATPAK=ON)"
|
||||
OFF "UNIX_NOT_APPLE"
|
||||
OFF )
|
||||
|
||||
# Not supported by all platforms (for instance mingw)
|
||||
option( KICAD_SANITIZE_ADDRESS
|
||||
"Build KiCad with sanitizer options. WARNING: Not compatible with gold linker"
|
||||
@@ -483,6 +501,12 @@ if( MSVC )
|
||||
string( APPEND CMAKE_CXX_FLAGS " /EHs" )
|
||||
endif()
|
||||
|
||||
if( KICAD_SANITIZE_ADDRESS )
|
||||
add_definitions( -DKICAD_SANITIZE_ADDRESS )
|
||||
add_definitions( -D_DISABLE_VECTOR_ANNOTATION )
|
||||
string( APPEND CMAKE_CXX_FLAGS " /fsanitize=address" )
|
||||
endif()
|
||||
|
||||
foreach( type EXE SHARED MODULE)
|
||||
# /DEBUG: create PDB
|
||||
string( APPEND CMAKE_${type}_LINKER_FLAGS " /DEBUG /MANIFEST:NO" )
|
||||
|
||||
@@ -147,6 +147,7 @@ END_EVENT_TABLE()
|
||||
BM2CMP_FRAME::BM2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
BM2CMP_FRAME_BASE( aParent )
|
||||
{
|
||||
m_ident = FRAME_BM2CMP; // Initialized to wxID_ANY by wxFormBuilder
|
||||
SetKiway( this, aKiway );
|
||||
|
||||
for( wxString unit : { _( "mm" ), _( "Inch" ), _( "DPI" ) } )
|
||||
|
||||
@@ -37,7 +37,7 @@ unset(_Python_NAMES)
|
||||
|
||||
set(_PYTHON1_VERSIONS 1.6 1.5)
|
||||
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
|
||||
set(_PYTHON3_VERSIONS 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
set(_PYTHON3_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
|
||||
# Disabling the "search every possible place" code for now
|
||||
# see https://gitlab.com/kicad/code/kicad/-/issues/8553
|
||||
|
||||
@@ -44,7 +44,7 @@ cmake_find_frameworks(Python)
|
||||
|
||||
set(_PYTHON1_VERSIONS 1.6 1.5)
|
||||
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
|
||||
set(_PYTHON3_VERSIONS 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
set(_PYTHON3_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
|
||||
|
||||
if(PythonLibs_FIND_VERSION)
|
||||
if(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "7.0.2" )
|
||||
set( KICAD_SEMANTIC_VERSION "7.0.7" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -216,6 +216,7 @@ set( COMMON_WIDGET_SRCS
|
||||
widgets/wx_panel.cpp
|
||||
widgets/wx_progress_reporters.cpp
|
||||
widgets/wx_splitter_window.cpp
|
||||
widgets/wx_treebook.cpp
|
||||
)
|
||||
|
||||
set( COMMON_DRAWING_SHEET_SRCS
|
||||
@@ -352,7 +353,6 @@ set( COMMON_SRCS
|
||||
lib_tree_model.cpp
|
||||
lib_tree_model_adapter.cpp
|
||||
locale_io.cpp
|
||||
lockfile.cpp
|
||||
lset.cpp
|
||||
marker_base.cpp
|
||||
markup_parser.cpp
|
||||
@@ -620,12 +620,9 @@ target_link_libraries( pcbcommon PUBLIC
|
||||
threadpool
|
||||
)
|
||||
|
||||
if( KICAD_USE_3DCONNEXION )
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in pcbcommon" )
|
||||
add_subdirectory( ../pcbnew/navlib ./navlib)
|
||||
target_link_libraries( pcbcommon PUBLIC pcbnew_navlib)
|
||||
endif()
|
||||
|
||||
message( STATUS "Including 3Dconnexion SpaceMouse navigation support in pcbcommon" )
|
||||
add_subdirectory( ../pcbnew/navlib ./navlib)
|
||||
target_link_libraries( pcbcommon PUBLIC pcbnew_navlib)
|
||||
|
||||
add_dependencies( pcbcommon delaunator )
|
||||
|
||||
|
||||
@@ -62,6 +62,16 @@ namespace AC_STACK
|
||||
namespace AC_KEYS
|
||||
{
|
||||
|
||||
/**
|
||||
* Should the schematic use the new incremental connectivity algorithm
|
||||
*/
|
||||
static const wxChar IncrementalConnectivity[] = wxT( "IncrementalConnectivity" );
|
||||
|
||||
/**
|
||||
* Decide whether to attempt usage of the 3DConnexion mouse
|
||||
*/
|
||||
static const wxChar Use3DConnexionDriver[] = wxT( "3DConnexionDriver" );
|
||||
|
||||
/**
|
||||
* When filling zones, we add an extra amount of clearance to each zone to ensure that rounding
|
||||
* errors do not overrun minimum clearance distances. This is the extra in mm.
|
||||
@@ -321,6 +331,15 @@ ADVANCED_CFG::ADVANCED_CFG()
|
||||
|
||||
m_UseClipper2 = true;
|
||||
|
||||
#ifdef _WIN32
|
||||
// spacemouse is largely stable on Windows
|
||||
m_Use3DConnexionDriver = true;
|
||||
#else
|
||||
m_Use3DConnexionDriver = false;
|
||||
#endif
|
||||
|
||||
m_IncrementalConnectivity = false;
|
||||
|
||||
loadFromConfigFile();
|
||||
}
|
||||
|
||||
@@ -463,6 +482,12 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::UseClipper2,
|
||||
&m_UseClipper2, m_UseClipper2 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::Use3DConnexionDriver,
|
||||
&m_Use3DConnexionDriver, m_Use3DConnexionDriver ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::IncrementalConnectivity,
|
||||
&m_IncrementalConnectivity, m_IncrementalConnectivity ) );
|
||||
|
||||
|
||||
|
||||
// Special case for trace mask setting...we just grab them and set them immediately
|
||||
|
||||
+37
-4
@@ -41,7 +41,8 @@ BITMAP_BASE::BITMAP_BASE( const VECTOR2I& pos )
|
||||
m_ppi = 300; // the bitmap definition. the default is 300PPI
|
||||
m_pixelSizeIu = 254000.0 / m_ppi; // a pixel size value OK for bitmaps using 300 PPI
|
||||
// for Eeschema which uses currently 254000PPI
|
||||
m_isMirrored = false;
|
||||
m_isMirroredX = false;
|
||||
m_isMirroredY = false;
|
||||
m_rotation = ANGLE_0;
|
||||
}
|
||||
|
||||
@@ -51,7 +52,8 @@ BITMAP_BASE::BITMAP_BASE( const BITMAP_BASE& aSchBitmap )
|
||||
m_scale = aSchBitmap.m_scale;
|
||||
m_ppi = aSchBitmap.m_ppi;
|
||||
m_pixelSizeIu = aSchBitmap.m_pixelSizeIu;
|
||||
m_isMirrored = aSchBitmap.m_isMirrored;
|
||||
m_isMirroredX = aSchBitmap.m_isMirroredX;
|
||||
m_isMirroredY = aSchBitmap.m_isMirroredY;
|
||||
m_rotation = aSchBitmap.m_rotation;
|
||||
|
||||
m_image = nullptr;
|
||||
@@ -115,7 +117,8 @@ void BITMAP_BASE::ImportData( BITMAP_BASE* aItem )
|
||||
m_scale = aItem->m_scale;
|
||||
m_ppi = aItem->m_ppi;
|
||||
m_pixelSizeIu = aItem->m_pixelSizeIu;
|
||||
m_isMirrored = aItem->m_isMirrored;
|
||||
m_isMirroredX = aItem->m_isMirroredX;
|
||||
m_isMirroredY = aItem->m_isMirroredY;
|
||||
m_rotation = aItem->m_rotation;
|
||||
}
|
||||
|
||||
@@ -400,8 +403,25 @@ void BITMAP_BASE::Mirror( bool aVertically )
|
||||
{
|
||||
if( m_image )
|
||||
{
|
||||
// wxImage::Mirror() clear some parameters of the original image.
|
||||
// We need to restore them, especially resolution and unit, to be
|
||||
// sure image parameters saved in file are the right parameters, not
|
||||
// the defualt values
|
||||
int resX = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
|
||||
int resY = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONY );
|
||||
int unit = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT );
|
||||
|
||||
*m_image = m_image->Mirror( not aVertically );
|
||||
m_isMirrored = !m_isMirrored;
|
||||
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONUNIT , unit);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONX, resX);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONY, resY);
|
||||
|
||||
if( aVertically )
|
||||
m_isMirroredY = !m_isMirroredY;
|
||||
else
|
||||
m_isMirroredX = !m_isMirroredX;
|
||||
|
||||
rebuildBitmap( false );
|
||||
}
|
||||
}
|
||||
@@ -411,7 +431,20 @@ void BITMAP_BASE::Rotate( bool aRotateCCW )
|
||||
{
|
||||
if( m_image )
|
||||
{
|
||||
// wxImage::Rotate90() clear some parameters of the original image.
|
||||
// We need to restore them, especially resolution and unit, to be
|
||||
// sure image parameters saved in file are the right parameters, not
|
||||
// the defualt values
|
||||
int resX = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
|
||||
int resY = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONY );
|
||||
int unit = m_image->GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT );
|
||||
|
||||
*m_image = m_image->Rotate90( aRotateCCW );
|
||||
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONUNIT , unit);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONX, resX);
|
||||
m_image->SetOption( wxIMAGE_OPTION_RESOLUTIONY, resY);
|
||||
|
||||
m_rotation += ( aRotateCCW ? -ANGLE_90 : ANGLE_90 );
|
||||
rebuildBitmap( false );
|
||||
}
|
||||
|
||||
@@ -49,8 +49,9 @@ void CALLBACK_GAL::DrawGlyph( const KIFONT::GLYPH& aGlyph, int aNth, int aTotal
|
||||
int strokeWidth = GetLineWidth();
|
||||
SHAPE_POLY_SET poly;
|
||||
|
||||
// Use ERROR_INSIDE because it avoids Clipper and is therefore much faster.
|
||||
TransformOvalToPolygon( poly, pointList[ ii - 1 ], pointList[ ii ],
|
||||
strokeWidth, strokeWidth / 48, ERROR_OUTSIDE );
|
||||
strokeWidth, strokeWidth / 180, ERROR_INSIDE );
|
||||
|
||||
m_outlineCallback( poly.Outline( 0 ) );
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#include <database/database_connection.h>
|
||||
#include <database/database_cache.h>
|
||||
#include <profile.h>
|
||||
|
||||
|
||||
const char* const traceDatabase = "KICAD_DATABASE";
|
||||
@@ -89,7 +90,7 @@ DATABASE_CONNECTION::DATABASE_CONNECTION( const std::string& aDataSourceName,
|
||||
m_pass = aPassword;
|
||||
m_timeout = aTimeoutSeconds;
|
||||
|
||||
m_cache = std::make_unique<DATABASE_CACHE>( 10, 1 );
|
||||
init();
|
||||
|
||||
if( aConnectNow )
|
||||
Connect();
|
||||
@@ -103,7 +104,7 @@ DATABASE_CONNECTION::DATABASE_CONNECTION( const std::string& aConnectionString,
|
||||
m_connectionString = aConnectionString;
|
||||
m_timeout = aTimeoutSeconds;
|
||||
|
||||
m_cache = std::make_unique<DATABASE_CACHE>( 10, 1 );
|
||||
init();
|
||||
|
||||
if( aConnectNow )
|
||||
Connect();
|
||||
@@ -117,6 +118,12 @@ DATABASE_CONNECTION::~DATABASE_CONNECTION()
|
||||
}
|
||||
|
||||
|
||||
void DATABASE_CONNECTION::init()
|
||||
{
|
||||
m_cache = std::make_unique<DB_CACHE_TYPE>( 10, 1 );
|
||||
}
|
||||
|
||||
|
||||
void DATABASE_CONNECTION::SetCacheParams( int aMaxSize, int aMaxAge )
|
||||
{
|
||||
if( !m_cache )
|
||||
@@ -159,12 +166,10 @@ bool DATABASE_CONNECTION::Connect()
|
||||
return false;
|
||||
}
|
||||
|
||||
m_tables.clear();
|
||||
|
||||
if( IsConnected() )
|
||||
{
|
||||
syncTables();
|
||||
cacheColumns();
|
||||
getQuoteChar();
|
||||
}
|
||||
|
||||
return IsConnected();
|
||||
}
|
||||
@@ -201,54 +206,32 @@ bool DATABASE_CONNECTION::IsConnected() const
|
||||
}
|
||||
|
||||
|
||||
bool DATABASE_CONNECTION::syncTables()
|
||||
bool DATABASE_CONNECTION::CacheTableInfo( const std::string& aTable,
|
||||
const std::set<std::string>& aColumns )
|
||||
{
|
||||
if( !m_conn )
|
||||
return false;
|
||||
|
||||
m_tables.clear();
|
||||
|
||||
try
|
||||
{
|
||||
nanodbc::catalog catalog( *m_conn );
|
||||
nanodbc::catalog::tables tables = catalog.find_tables();
|
||||
nanodbc::catalog::tables tables = catalog.find_tables( fromUTF8( aTable ) );
|
||||
|
||||
while( tables.next() )
|
||||
{
|
||||
std::string key = toUTF8( tables.table_name() );
|
||||
m_tables[key] = toUTF8( tables.table_type() );
|
||||
}
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while syncing tables: %s" ), m_lastError );
|
||||
return false;
|
||||
}
|
||||
tables.next();
|
||||
std::string key = toUTF8( tables.table_name() );
|
||||
m_tables[key] = toUTF8( tables.table_type() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DATABASE_CONNECTION::cacheColumns()
|
||||
{
|
||||
if( !m_conn )
|
||||
return false;
|
||||
|
||||
m_columnCache.clear();
|
||||
|
||||
for( const auto& tableIter : m_tables )
|
||||
{
|
||||
try
|
||||
{
|
||||
nanodbc::catalog catalog( *m_conn );
|
||||
nanodbc::catalog::columns columns =
|
||||
catalog.find_columns( NANODBC_TEXT( "" ), fromUTF8( tableIter.first ) );
|
||||
catalog.find_columns( NANODBC_TEXT( "" ), tables.table_name() );
|
||||
|
||||
while( columns.next() )
|
||||
{
|
||||
std::string columnKey = toUTF8( columns.column_name() );
|
||||
m_columnCache[tableIter.first][columnKey] = columns.data_type();
|
||||
|
||||
if( aColumns.count( columnKey ) )
|
||||
m_columnCache[key][columnKey] = columns.data_type();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -256,10 +239,16 @@ bool DATABASE_CONNECTION::cacheColumns()
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while syncing columns for table %s: %s" ),
|
||||
tableIter.first, m_lastError );
|
||||
key, m_lastError );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while caching table info: %s" ), m_lastError );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -291,6 +280,35 @@ bool DATABASE_CONNECTION::getQuoteChar()
|
||||
}
|
||||
|
||||
|
||||
std::string DATABASE_CONNECTION::columnsFor( const std::string& aTable )
|
||||
{
|
||||
if( !m_columnCache.count( aTable ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "columnsFor: requested table %s missing from cache!" ),
|
||||
aTable );
|
||||
return "*";
|
||||
}
|
||||
|
||||
if( m_columnCache[aTable].empty() )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "columnsFor: requested table %s has no columns mapped!" ),
|
||||
aTable );
|
||||
return "*";
|
||||
}
|
||||
|
||||
std::string ret;
|
||||
|
||||
for( const auto& [ columnName, columnType ] : m_columnCache[aTable] )
|
||||
ret += fmt::format( "{}{}{}, ", m_quoteChar, columnName, m_quoteChar );
|
||||
|
||||
// strip tailing ', '
|
||||
ret.resize( ret.length() - 2 );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//next step, make SelectOne take from the SelectAll cache if the SelectOne cache is missing.
|
||||
//To do this, need to build a map of PK->ROW for the cache result.
|
||||
bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
const std::pair<std::string, std::string>& aWhere,
|
||||
DATABASE_CONNECTION::ROW& aResult )
|
||||
@@ -311,6 +329,18 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
}
|
||||
|
||||
const std::string& tableName = tableMapIter->first;
|
||||
DB_CACHE_TYPE::CACHE_VALUE cacheEntry;
|
||||
|
||||
if( m_cache->Get( tableName, cacheEntry ) )
|
||||
{
|
||||
if( cacheEntry.count( aWhere.second ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: `%s` with parameter `%s` - cache hit" ),
|
||||
tableName, aWhere.second );
|
||||
aResult = cacheEntry.at( aWhere.second );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_columnCache.count( tableName ) )
|
||||
{
|
||||
@@ -332,19 +362,15 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
|
||||
std::string cacheKey = fmt::format( "{}{}{}", tableName, columnName, aWhere.second );
|
||||
|
||||
std::string queryStr = fmt::format( "SELECT * FROM {}{}{} WHERE {}{}{} = ?",
|
||||
std::string queryStr = fmt::format( "SELECT {} FROM {}{}{} WHERE {}{}{} = ?",
|
||||
columnsFor( tableName ),
|
||||
m_quoteChar, tableName, m_quoteChar,
|
||||
m_quoteChar, columnName, m_quoteChar );
|
||||
|
||||
nanodbc::statement statement( *m_conn );
|
||||
nanodbc::string query = fromUTF8( queryStr );
|
||||
|
||||
if( m_cache->Get( cacheKey, aResult ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: `%s` with parameter `%s` - cache hit" ),
|
||||
toUTF8( query ), aWhere.second );
|
||||
return true;
|
||||
}
|
||||
PROF_TIMER timer;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -384,14 +410,17 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
return false;
|
||||
}
|
||||
|
||||
timer.Stop();
|
||||
|
||||
|
||||
if( !results.first() )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: no results returned from query" ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: %ld results returned from query" ),
|
||||
results.rows() );
|
||||
wxLogTrace( traceDatabase, wxT( "SelectOne: %ld results returned from query in %0.1f ms" ),
|
||||
results.rows(), timer.msecs() );
|
||||
|
||||
aResult.clear();
|
||||
|
||||
@@ -411,13 +440,12 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cache->Put( cacheKey, aResult );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, std::vector<ROW>& aResults )
|
||||
bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::string& aKey,
|
||||
std::vector<ROW>& aResults )
|
||||
{
|
||||
if( !m_conn )
|
||||
{
|
||||
@@ -434,13 +462,27 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, std::vector<ROW>
|
||||
return false;
|
||||
}
|
||||
|
||||
DB_CACHE_TYPE::CACHE_VALUE cacheEntry;
|
||||
|
||||
if( m_cache->Get( aTable, cacheEntry ) )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - cache hit" ), aTable );
|
||||
|
||||
for( auto &[ key, row ] : cacheEntry )
|
||||
aResults.emplace_back( row );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nanodbc::statement statement( *m_conn );
|
||||
|
||||
nanodbc::string query = fromUTF8( fmt::format( "SELECT * FROM {}{}{}", m_quoteChar,
|
||||
tableMapIter->first, m_quoteChar ) );
|
||||
nanodbc::string query = fromUTF8( fmt::format( "SELECT {} FROM {}{}{}", columnsFor( aTable ),
|
||||
m_quoteChar, aTable, m_quoteChar ) );
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s`" ), toUTF8( query ) );
|
||||
|
||||
PROF_TIMER timer;
|
||||
|
||||
try
|
||||
{
|
||||
statement.prepare( query );
|
||||
@@ -475,6 +517,8 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, std::vector<ROW>
|
||||
return false;
|
||||
}
|
||||
|
||||
timer.Stop();
|
||||
|
||||
try
|
||||
{
|
||||
while( results.next() )
|
||||
@@ -498,5 +542,17 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, std::vector<ROW>
|
||||
return false;
|
||||
}
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "SelectAll from %s completed in %0.1f ms" ), aTable,
|
||||
timer.msecs() );
|
||||
|
||||
for( const ROW& row : aResults )
|
||||
{
|
||||
wxASSERT( row.count( aKey ) );
|
||||
std::string keyStr = std::any_cast<std::string>( row.at( aKey ) );
|
||||
cacheEntry[keyStr] = row;
|
||||
}
|
||||
|
||||
m_cache->Put( aTable, cacheEntry );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,6 +74,11 @@ DATABASE_LIB_SETTINGS::DATABASE_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
table.symbols_col = entry["symbols"].get<std::string>();
|
||||
table.footprints_col = entry["footprints"].get<std::string>();
|
||||
|
||||
// Sanitize library display names; currently only `/` is removed because we use it
|
||||
// as a separator and allow it in symbol names.
|
||||
table.name.erase( std::remove( table.name.begin(), table.name.end(), '/' ),
|
||||
table.name.end() );
|
||||
|
||||
if( entry.contains( "properties" ) && entry["properties"].is_object() )
|
||||
{
|
||||
const nlohmann::json& pj = entry["properties"];
|
||||
|
||||
+56
-32
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2012-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2012-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -67,10 +67,6 @@ public:
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( DIALOG_SHIM, wxDialog )
|
||||
// If dialog has a grid and the grid has an active cell editor
|
||||
// Esc key closes cell editor, otherwise Esc key closes the dialog.
|
||||
EVT_GRID_EDITOR_SHOWN( DIALOG_SHIM::OnGridEditorShown )
|
||||
EVT_GRID_EDITOR_HIDDEN( DIALOG_SHIM::OnGridEditorHidden )
|
||||
EVT_CHAR_HOOK( DIALOG_SHIM::OnCharHook )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
@@ -325,30 +321,38 @@ bool DIALOG_SHIM::Enable( bool enable )
|
||||
// Recursive descent doing a SelectAll() in wxTextCtrls.
|
||||
// MacOS User Interface Guidelines state that when tabbing to a text control all its
|
||||
// text should be selected. Since wxWidgets fails to implement this, we do it here.
|
||||
static void selectAllInTextCtrls( wxWindowList& children )
|
||||
void DIALOG_SHIM::selectAllInTextCtrls( wxWindowList& children )
|
||||
{
|
||||
for( wxWindow* child : children )
|
||||
{
|
||||
if( wxTextCtrl* childTextCtrl = dynamic_cast<wxTextCtrl*>( child ) )
|
||||
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( child ) )
|
||||
{
|
||||
m_beforeEditValues[ textCtrl ] = textCtrl->GetValue();
|
||||
textCtrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
|
||||
nullptr, this );
|
||||
|
||||
// We don't currently run this on GTK because some window managers don't hide the
|
||||
// selection in non-active controls, and other window managers do the selection
|
||||
// automatically anyway.
|
||||
#if defined( __WXMAC__ ) || defined( __WXMSW__ )
|
||||
if( !childTextCtrl->GetStringSelection().IsEmpty() )
|
||||
if( !textCtrl->GetStringSelection().IsEmpty() )
|
||||
{
|
||||
// Respect an existing selection
|
||||
}
|
||||
else
|
||||
else if( textCtrl->IsEditable() )
|
||||
{
|
||||
childTextCtrl->SelectAll();
|
||||
textCtrl->SelectAll();
|
||||
}
|
||||
#else
|
||||
ignore_unused( childTextCtrl );
|
||||
ignore_unused( textCtrl );
|
||||
#endif
|
||||
}
|
||||
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( child ) )
|
||||
{
|
||||
m_beforeEditValues[ scintilla ] = scintilla->GetText();
|
||||
scintilla->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ),
|
||||
nullptr, this );
|
||||
|
||||
if( !scintilla->GetSelectedText().IsEmpty() )
|
||||
{
|
||||
// Respect an existing selection
|
||||
@@ -533,11 +537,6 @@ void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
|
||||
{
|
||||
const int id = aEvent.GetId();
|
||||
|
||||
// If we are pressing a button to exit, we need to enable the escapeID
|
||||
// otherwise the dialog does not process cancel
|
||||
if( id == wxID_CANCEL )
|
||||
SetEscapeId( wxID_ANY );
|
||||
|
||||
if( IsQuasiModal() )
|
||||
{
|
||||
if( id == GetAffirmativeId() )
|
||||
@@ -555,7 +554,7 @@ void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
|
||||
ignore_unused( TransferDataFromWindow() );
|
||||
}
|
||||
}
|
||||
else if( id == GetEscapeId() || (id == wxID_CANCEL && GetEscapeId() == wxID_ANY) )
|
||||
else if( id == wxID_CANCEL )
|
||||
{
|
||||
EndQuasiModal( wxID_CANCEL );
|
||||
}
|
||||
@@ -572,6 +571,19 @@ void DIALOG_SHIM::OnButton( wxCommandEvent& aEvent )
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::onChildSetFocus( wxFocusEvent& aEvent )
|
||||
{
|
||||
// When setting focus to a text control reset the before-edit value.
|
||||
|
||||
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aEvent.GetEventObject() ) )
|
||||
m_beforeEditValues[ textCtrl ] = textCtrl->GetValue();
|
||||
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( aEvent.GetEventObject() ) )
|
||||
m_beforeEditValues[ scintilla ] = scintilla->GetText();
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
|
||||
{
|
||||
if( aEvt.GetKeyCode() == 'U' && aEvt.GetModifiers() == wxMOD_CONTROL )
|
||||
@@ -583,7 +595,8 @@ void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
|
||||
}
|
||||
}
|
||||
// shift-return (Mac default) or Ctrl-Return (GTK) for OK
|
||||
else if( aEvt.GetKeyCode() == WXK_RETURN && ( aEvt.ShiftDown() || aEvt.ControlDown() ) )
|
||||
else if( ( aEvt.GetKeyCode() == WXK_RETURN || aEvt.GetKeyCode() == WXK_NUMPAD_ENTER )
|
||||
&& ( aEvt.ShiftDown() || aEvt.ControlDown() ) )
|
||||
{
|
||||
wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
|
||||
return;
|
||||
@@ -626,25 +639,36 @@ void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( aEvt.GetKeyCode() == WXK_ESCAPE )
|
||||
{
|
||||
wxObject* eventSource = aEvt.GetEventObject();
|
||||
|
||||
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( eventSource ) )
|
||||
{
|
||||
// First escape after an edit cancels edit
|
||||
if( textCtrl->GetValue() != m_beforeEditValues[ textCtrl ] )
|
||||
{
|
||||
textCtrl->SetValue( m_beforeEditValues[ textCtrl ] );
|
||||
textCtrl->SelectAll();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( eventSource ) )
|
||||
{
|
||||
// First escape after an edit cancels edit
|
||||
if( scintilla->GetText() != m_beforeEditValues[ scintilla ] )
|
||||
{
|
||||
scintilla->SetText( m_beforeEditValues[ scintilla ] );
|
||||
scintilla->SelectAll();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aEvt.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::OnGridEditorShown( wxGridEvent& event )
|
||||
{
|
||||
SetEscapeId( wxID_NONE );
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_SHIM::OnGridEditorHidden( wxGridEvent& event )
|
||||
{
|
||||
SetEscapeId( wxID_ANY );
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
|
||||
static void recursiveDescent( wxSizer* aSizer, std::map<int, wxString>& aLabels )
|
||||
{
|
||||
wxStdDialogButtonSizer* sdbSizer = dynamic_cast<wxStdDialogButtonSizer*>( aSizer );
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -105,10 +105,7 @@ void DIALOG_ASSIGN_NETCLASS::onPatternText( wxCommandEvent& aEvent )
|
||||
|
||||
for( const wxString& net : m_netCandidates )
|
||||
{
|
||||
int matches;
|
||||
int offset;
|
||||
|
||||
if( matcher.Find( net, matches, offset ) && offset == 0 )
|
||||
if( matcher.StartsWith( net ) )
|
||||
{
|
||||
m_matchingNets->Report( net );
|
||||
matchingNetNames.push_back( net );
|
||||
|
||||
@@ -396,12 +396,12 @@ void DIALOG_COLOR_PICKER::drawRGBPalette()
|
||||
|
||||
// Use Y axis from bottom to top and origin to center
|
||||
bitmapDC.SetAxisOrientation( true, true );
|
||||
#if wxCHECK_VERSION( 3, 1, 7 )
|
||||
#if wxCHECK_VERSION( 3, 1, 7 ) && defined( __WXMSW__)
|
||||
// For some reason, SetDeviceOrigin has changed in wxWidgets 3.1.6 or 3.1.7
|
||||
bitmapDC.SetDeviceOrigin( half_size, -half_size );
|
||||
#else
|
||||
#else
|
||||
bitmapDC.SetDeviceOrigin( half_size, half_size );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Reserve room to draw cursors inside the bitmap
|
||||
half_size -= m_cursorsSize/2;
|
||||
@@ -466,12 +466,12 @@ void DIALOG_COLOR_PICKER::drawHSVPalette()
|
||||
|
||||
// Use Y axis from bottom to top and origin to center
|
||||
bitmapDC.SetAxisOrientation( true, true );
|
||||
#if wxCHECK_VERSION( 3, 1, 7 )
|
||||
#if wxCHECK_VERSION( 3, 1, 7 ) && defined( __WXMSW__)
|
||||
// For some reason, SetDeviceOrigin has changed in wxWidgets 3.1.6 or 3.1.7
|
||||
bitmapDC.SetDeviceOrigin( half_size, -half_size );
|
||||
#else
|
||||
#else
|
||||
bitmapDC.SetDeviceOrigin( half_size, half_size );
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Reserve room to draw cursors inside the bitmap
|
||||
half_size -= m_cursorsSize / 2;
|
||||
@@ -701,11 +701,13 @@ void DIALOG_COLOR_PICKER::onHSVMouseDrag( wxMouseEvent& event )
|
||||
|
||||
void DIALOG_COLOR_PICKER::OnColorValueText( wxCommandEvent& event )
|
||||
{
|
||||
m_newColor4D.SetFromHexString( m_colorValue->GetValue() );
|
||||
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
|
||||
if( m_newColor4D.SetFromHexString( m_colorValue->GetValue() ) )
|
||||
{
|
||||
m_newColor4D.ToHSV( m_hue, m_sat, m_val, true );
|
||||
|
||||
SetEditVals( HEX_CHANGED, true );
|
||||
drawAll();
|
||||
SetEditVals( HEX_CHANGED, false );
|
||||
drawAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,9 +44,8 @@
|
||||
* Ugly as it all is, it does improve our usability on various platforms.
|
||||
*/
|
||||
|
||||
PANEL_COMMON_SETTINGS::PANEL_COMMON_SETTINGS( DIALOG_SHIM* aDialog, wxWindow* aParent )
|
||||
PANEL_COMMON_SETTINGS::PANEL_COMMON_SETTINGS( wxWindow* aParent )
|
||||
: PANEL_COMMON_SETTINGS_BASE( aParent ),
|
||||
m_dialog( aDialog ),
|
||||
m_iconScaleLabel( nullptr ),
|
||||
m_iconScaleSlider( nullptr ),
|
||||
m_iconScaleAuto( nullptr ),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -415,6 +415,7 @@ PANEL_COMMON_SETTINGS_BASE::PANEL_COMMON_SETTINGS_BASE( wxWindow* parent, wxWind
|
||||
|
||||
this->SetSizer( bPanelSizer );
|
||||
this->Layout();
|
||||
bPanelSizer->Fit( this );
|
||||
|
||||
// Connect Events
|
||||
m_textEditorBtn->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_COMMON_SETTINGS_BASE::OnTextEditorClick ), NULL, this );
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">PANEL_COMMON_SETTINGS_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">676,655</property>
|
||||
<property name="size">-1,-1</property>
|
||||
<property name="subclass">RESETTABLE_PANEL; widgets/resettable_panel.h; Not forward_declare</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -113,7 +113,7 @@ class PANEL_COMMON_SETTINGS_BASE : public RESETTABLE_PANEL
|
||||
|
||||
public:
|
||||
|
||||
PANEL_COMMON_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 676,655 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
|
||||
PANEL_COMMON_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
|
||||
|
||||
~PANEL_COMMON_SETTINGS_BASE();
|
||||
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
#include <settings/settings_manager.h>
|
||||
|
||||
|
||||
PANEL_DATA_COLLECTION::PANEL_DATA_COLLECTION( PAGED_DIALOG* aDialog, wxWindow* aParent ) :
|
||||
PANEL_DATA_COLLECTION_BASE( aParent ), m_dialog( aDialog )
|
||||
PANEL_DATA_COLLECTION::PANEL_DATA_COLLECTION( wxWindow* aParent ) :
|
||||
PANEL_DATA_COLLECTION_BASE( aParent )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -47,9 +47,9 @@ bool PANEL_DATA_COLLECTION::TransferDataToWindow()
|
||||
{
|
||||
applySettingsToPanel();
|
||||
|
||||
KIPLATFORM::POLICY::STATE policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyState( POLICY_KEY_DATACOLLECTION );
|
||||
if( policyState != KIPLATFORM::POLICY::STATE::NOT_CONFIGURED )
|
||||
KIPLATFORM::POLICY::PBOOL policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyBool( POLICY_KEY_DATACOLLECTION );
|
||||
if( policyState != KIPLATFORM::POLICY::PBOOL::NOT_CONFIGURED )
|
||||
{
|
||||
Disable();
|
||||
}
|
||||
|
||||
@@ -26,9 +26,8 @@
|
||||
#include <wx/defs.h>
|
||||
|
||||
|
||||
PANEL_MOUSE_SETTINGS::PANEL_MOUSE_SETTINGS( PAGED_DIALOG* aDialog, wxWindow* aParent ) :
|
||||
PANEL_MOUSE_SETTINGS::PANEL_MOUSE_SETTINGS( wxWindow* aParent ) :
|
||||
PANEL_MOUSE_SETTINGS_BASE( aParent ),
|
||||
m_dialog( aDialog ),
|
||||
m_currentScrollMod( {} )
|
||||
{
|
||||
#ifdef __WXOSX_MAC__
|
||||
@@ -82,8 +81,9 @@ bool PANEL_MOUSE_SETTINGS::TransferDataFromWindow()
|
||||
|
||||
if( !isScrollModSetValid( m_currentScrollMod ) )
|
||||
{
|
||||
m_dialog->SetError( _( "Only one action can be assigned to each vertical scroll setting" ),
|
||||
this, nullptr );
|
||||
PAGED_DIALOG::GetDialog( this )->SetError( _( "Only one action can be assigned to each "
|
||||
"vertical scroll setting" ),
|
||||
this, nullptr );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -316,6 +316,7 @@ PANEL_MOUSE_SETTINGS_BASE::PANEL_MOUSE_SETTINGS_BASE( wxWindow* parent, wxWindow
|
||||
|
||||
this->SetSizer( bSizer10 );
|
||||
this->Layout();
|
||||
bSizer10->Fit( this );
|
||||
|
||||
// Connect Events
|
||||
m_rbZoomNone->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PANEL_MOUSE_SETTINGS_BASE::OnScrollRadioButton ), NULL, this );
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">PANEL_MOUSE_SETTINGS_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">609,523</property>
|
||||
<property name="size">-1,-1</property>
|
||||
<property name="subclass">RESETTABLE_PANEL; widgets/resettable_panel.h; Not forward_declare</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
@@ -97,7 +97,7 @@ class PANEL_MOUSE_SETTINGS_BASE : public RESETTABLE_PANEL
|
||||
|
||||
public:
|
||||
|
||||
PANEL_MOUSE_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 609,523 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
|
||||
PANEL_MOUSE_SETTINGS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
|
||||
|
||||
~PANEL_MOUSE_SETTINGS_BASE();
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include <widgets/wx_html_report_box.h>
|
||||
#include <widgets/wx_panel.h>
|
||||
#include <widgets/std_bitmap_button.h>
|
||||
#include <wx/treebook.h>
|
||||
#include <project/net_settings.h>
|
||||
|
||||
|
||||
@@ -70,13 +69,12 @@ std::vector<BITMAPS> g_lineStyleIcons;
|
||||
wxArrayString g_lineStyleNames;
|
||||
|
||||
|
||||
PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_FRAME* aFrame,
|
||||
PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( wxWindow* aParentWindow, EDA_DRAW_FRAME* aFrame,
|
||||
std::shared_ptr<NET_SETTINGS> aNetSettings,
|
||||
const std::set<wxString>& aNetNames,
|
||||
bool aIsEEschema ) :
|
||||
PANEL_SETUP_NETCLASSES_BASE( aParent->GetTreebook() ),
|
||||
PANEL_SETUP_NETCLASSES_BASE( aParentWindow ),
|
||||
m_frame( aFrame ),
|
||||
m_parent( aParent ),
|
||||
m_isEEschema( aIsEEschema ),
|
||||
m_netSettings( aNetSettings ),
|
||||
m_netNames( aNetNames ),
|
||||
@@ -121,10 +119,8 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_
|
||||
// as this initial width is sometimes strange depending on the language (wxGrid bug?)
|
||||
int const min_width = m_netclassGrid->GetVisibleWidth( i, true, true );
|
||||
|
||||
int const weighted_min_best_width =
|
||||
( i == GRID_LINESTYLE )
|
||||
? min_best_width * 3 / 2
|
||||
: min_best_width;
|
||||
int const weighted_min_best_width = ( i == GRID_LINESTYLE ) ? min_best_width * 3 / 2
|
||||
: min_best_width;
|
||||
|
||||
m_netclassGrid->SetColMinimalWidth( i, min_width );
|
||||
|
||||
@@ -158,8 +154,8 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_
|
||||
}
|
||||
|
||||
wxGridCellAttr* attr = new wxGridCellAttr;
|
||||
attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( aParent ) );
|
||||
attr->SetEditor( new GRID_CELL_COLOR_SELECTOR( aParent, m_netclassGrid ) );
|
||||
attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( PAGED_DIALOG::GetDialog( this ) ) );
|
||||
attr->SetEditor( new GRID_CELL_COLOR_SELECTOR( PAGED_DIALOG::GetDialog( this ), m_netclassGrid ) );
|
||||
m_netclassGrid->SetColAttr( GRID_SCHEMATIC_COLOR, attr );
|
||||
|
||||
attr = new wxGridCellAttr;
|
||||
@@ -174,7 +170,6 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, EDA_DRAW_
|
||||
|
||||
m_netclassGrid->SetAutoEvalCols( { GRID_WIREWIDTH,
|
||||
GRID_BUSWIDTH,
|
||||
|
||||
GRID_CLEARANCE,
|
||||
GRID_TRACKSIZE,
|
||||
GRID_VIASIZE,
|
||||
@@ -327,6 +322,8 @@ bool PANEL_SETUP_NETCLASSES::TransferDataToWindow()
|
||||
row++;
|
||||
}
|
||||
|
||||
AdjustAssignmentGridColumns( GetSize().x * 3 / 5 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -428,7 +425,7 @@ bool PANEL_SETUP_NETCLASSES::validateNetclassName( int aRow, const wxString& aNa
|
||||
if( tmp.IsEmpty() )
|
||||
{
|
||||
wxString msg = _( "Netclass must have a name." );
|
||||
m_parent->SetError( msg, this, m_netclassGrid, aRow, GRID_NAME );
|
||||
PAGED_DIALOG::GetDialog( this )->SetError( msg, this, m_netclassGrid, aRow, GRID_NAME );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -437,7 +434,8 @@ bool PANEL_SETUP_NETCLASSES::validateNetclassName( int aRow, const wxString& aNa
|
||||
if( ii != aRow && m_netclassGrid->GetCellValue( ii, GRID_NAME ).CmpNoCase( tmp ) == 0 )
|
||||
{
|
||||
wxString msg = _( "Netclass name already in use." );
|
||||
m_parent->SetError( msg, this, m_netclassGrid, focusFirst ? aRow : ii, GRID_NAME );
|
||||
PAGED_DIALOG::GetDialog( this )->SetError( msg, this, m_netclassGrid,
|
||||
focusFirst ? aRow : ii, GRID_NAME );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -652,16 +650,15 @@ void PANEL_SETUP_NETCLASSES::AdjustAssignmentGridColumns( int aWidth )
|
||||
// Account for scroll bars
|
||||
aWidth -= ( m_assignmentGrid->GetSize().x - m_assignmentGrid->GetClientSize().x );
|
||||
|
||||
// Set className column width to original className width from netclasses grid
|
||||
int classNameWidth = m_originalColWidths[ 0 ];
|
||||
m_assignmentGrid->SetColSize( 1, m_originalColWidths[ 0 ] );
|
||||
int classNameWidth = 160;
|
||||
m_assignmentGrid->SetColSize( 1, classNameWidth );
|
||||
m_assignmentGrid->SetColSize( 0, std::max( aWidth - classNameWidth, classNameWidth ) );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_SETUP_NETCLASSES::OnSizeAssignmentGrid( wxSizeEvent& event )
|
||||
{
|
||||
AdjustAssignmentGridColumns( event.GetSize().GetX());
|
||||
AdjustAssignmentGridColumns( event.GetSize().GetX() );
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
@@ -708,10 +705,7 @@ void PANEL_SETUP_NETCLASSES::OnUpdateUI( wxUpdateUIEvent& event )
|
||||
|
||||
for( const wxString& net : m_netNames )
|
||||
{
|
||||
int matches;
|
||||
int offset;
|
||||
|
||||
if( matcher.Find( net, matches, offset ) && offset == 0 )
|
||||
if( matcher.StartsWith( net ) )
|
||||
m_matchingNets->Report( net );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi
|
||||
|
||||
// Cell Defaults
|
||||
m_netclassGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
|
||||
bUpperSizer->Add( m_netclassGrid, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 1 );
|
||||
bUpperSizer->Add( m_netclassGrid, 1, wxEXPAND|wxFIXED_MINSIZE|wxLEFT|wxRIGHT|wxTOP, 1 );
|
||||
|
||||
wxBoxSizer* buttonBoxSizer;
|
||||
buttonBoxSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
@@ -129,7 +129,7 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi
|
||||
m_assignmentGrid->SetMargins( 0, 0 );
|
||||
|
||||
// Columns
|
||||
m_assignmentGrid->SetColSize( 0, 400 );
|
||||
m_assignmentGrid->SetColSize( 0, 270 );
|
||||
m_assignmentGrid->SetColSize( 1, 160 );
|
||||
m_assignmentGrid->EnableDragColMove( false );
|
||||
m_assignmentGrid->EnableDragColSize( true );
|
||||
@@ -147,7 +147,7 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi
|
||||
|
||||
// Cell Defaults
|
||||
m_assignmentGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
|
||||
bSizer14->Add( m_assignmentGrid, 2, wxEXPAND|wxLEFT, 5 );
|
||||
bSizer14->Add( m_assignmentGrid, 2, wxEXPAND|wxFIXED_MINSIZE|wxLEFT, 5 );
|
||||
|
||||
|
||||
bColumns->Add( bSizer14, 3, wxEXPAND, 5 );
|
||||
@@ -186,7 +186,6 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi
|
||||
|
||||
this->SetSizer( bpanelNetClassesSizer );
|
||||
this->Layout();
|
||||
bpanelNetClassesSizer->Fit( this );
|
||||
|
||||
// Connect Events
|
||||
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_NETCLASSES_BASE::OnUpdateUI ) );
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
<property name="minimum_size">-1,-1</property>
|
||||
<property name="name">PANEL_SETUP_NETCLASSES_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">-1,-1</property>
|
||||
<property name="size">700,500</property>
|
||||
<property name="subclass">; forward_declare</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
@@ -258,7 +258,7 @@
|
||||
</object>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">1</property>
|
||||
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
|
||||
<property name="flag">wxEXPAND|wxFIXED_MINSIZE|wxLEFT|wxRIGHT|wxTOP</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxGrid" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
@@ -737,7 +737,7 @@
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="0">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxLEFT</property>
|
||||
<property name="flag">wxEXPAND|wxFIXED_MINSIZE|wxLEFT</property>
|
||||
<property name="proportion">2</property>
|
||||
<object class="wxGrid" expanded="0">
|
||||
<property name="BottomDockable">1</property>
|
||||
@@ -766,7 +766,7 @@
|
||||
<property name="col_label_values">"Pattern" "Net Class"</property>
|
||||
<property name="col_label_vert_alignment">wxALIGN_CENTER</property>
|
||||
<property name="cols">2</property>
|
||||
<property name="column_sizes">400,160</property>
|
||||
<property name="column_sizes">270,160</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
|
||||
@@ -69,7 +69,7 @@ class PANEL_SETUP_NETCLASSES_BASE : public wxPanel
|
||||
|
||||
public:
|
||||
|
||||
PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
|
||||
PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 700,500 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
|
||||
|
||||
~PANEL_SETUP_NETCLASSES_BASE();
|
||||
|
||||
|
||||
@@ -28,14 +28,13 @@
|
||||
#include <wx/radiobut.h>
|
||||
#include <wx/scrolwin.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/treebook.h>
|
||||
|
||||
|
||||
PANEL_SETUP_SEVERITIES::PANEL_SETUP_SEVERITIES( PAGED_DIALOG* aParent,
|
||||
PANEL_SETUP_SEVERITIES::PANEL_SETUP_SEVERITIES( wxWindow* aParentWindow,
|
||||
std::vector<std::reference_wrapper<RC_ITEM>> aItems,
|
||||
std::map<int, SEVERITY>& aSeverities,
|
||||
RC_ITEM* aPinMapSpecialCase ) :
|
||||
wxPanel( aParent->GetTreebook() ),
|
||||
wxPanel( aParentWindow ),
|
||||
m_severities( aSeverities ),
|
||||
m_items( aItems ),
|
||||
m_pinMapSpecialCase( aPinMapSpecialCase )
|
||||
|
||||
@@ -110,6 +110,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
|
||||
|
||||
EnableScrolling( false, false ); // otherwise Zoom Auto disables GAL canvas
|
||||
KIPLATFORM::UI::SetOverlayScrolling( this, false ); // Prevent excessive repaint on GTK
|
||||
KIPLATFORM::UI::ImmControl( this, false ); // Ensure our panel can't suck in IME events
|
||||
|
||||
Connect( wxEVT_SIZE, wxSizeEventHandler( EDA_DRAW_PANEL_GAL::onSize ), nullptr, this );
|
||||
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( EDA_DRAW_PANEL_GAL::onEnter ), nullptr,
|
||||
@@ -365,7 +366,10 @@ void EDA_DRAW_PANEL_GAL::onSize( wxSizeEvent& aEvent )
|
||||
if( m_view )
|
||||
{
|
||||
if( infobar && infobar->IsLocked() )
|
||||
m_view->SetCenter( bottom - m_view->ToWorld( clientSize, false ) / 2.0 );
|
||||
{
|
||||
VECTOR2D halfScreen( std::ceil( 0.5 * clientSize.x ), std::ceil( 0.5 * clientSize.y ) );
|
||||
m_view->SetCenter( bottom - m_view->ToWorld( halfScreen, false ) );
|
||||
}
|
||||
|
||||
m_view->MarkTargetDirty( KIGFX::TARGET_CACHED );
|
||||
m_view->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
|
||||
|
||||
@@ -106,13 +106,13 @@ void DS_DATA_ITEM::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX::VIEW* aV
|
||||
|
||||
for( int j = 0; j < m_RepeatCount; j++ )
|
||||
{
|
||||
if( j && ! IsInsidePage( j ) )
|
||||
if( j > 0 && !IsInsidePage( j ) )
|
||||
continue;
|
||||
|
||||
if( m_type == DS_SEGMENT )
|
||||
item = new DS_DRAW_ITEM_LINE( this, j, GetStartPosUi( j ), GetEndPosUi( j ), pensize );
|
||||
item = new DS_DRAW_ITEM_LINE( this, j, GetStartPosIU( j ), GetEndPosIU( j ), pensize );
|
||||
else if( m_type == DS_RECT )
|
||||
item = new DS_DRAW_ITEM_RECT( this, j, GetStartPosUi( j ), GetEndPosUi( j ), pensize );
|
||||
item = new DS_DRAW_ITEM_RECT( this, j, GetStartPosIU( j ), GetEndPosIU( j ), pensize );
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG( wxS( "Unknown drawing sheet item type" ) );
|
||||
@@ -162,8 +162,8 @@ void DS_DATA_ITEM::MoveTo( const VECTOR2D& aPosition )
|
||||
|
||||
for( DS_DRAW_ITEM_BASE* drawItem : m_drawItems )
|
||||
{
|
||||
drawItem->SetPosition( GetStartPosUi( drawItem->GetIndexInPeer() ) );
|
||||
drawItem->SetEnd( GetEndPosUi( drawItem->GetIndexInPeer() ) );
|
||||
drawItem->SetPosition( GetStartPosIU( drawItem->GetIndexInPeer() ) );
|
||||
drawItem->SetEnd( GetEndPosIU( drawItem->GetIndexInPeer() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ const VECTOR2D DS_DATA_ITEM::GetStartPos( int ii ) const
|
||||
}
|
||||
|
||||
|
||||
const VECTOR2I DS_DATA_ITEM::GetStartPosUi( int ii ) const
|
||||
const VECTOR2I DS_DATA_ITEM::GetStartPosIU( int ii ) const
|
||||
{
|
||||
VECTOR2D pos = GetStartPos( ii ) * DS_DATA_MODEL::GetTheInstance().m_WSunits2Iu;
|
||||
return VECTOR2I( KiROUND( pos.x ), KiROUND( pos.y ) );
|
||||
@@ -331,7 +331,7 @@ const VECTOR2D DS_DATA_ITEM::GetEndPos( int ii ) const
|
||||
}
|
||||
|
||||
|
||||
const VECTOR2I DS_DATA_ITEM::GetEndPosUi( int ii ) const
|
||||
const VECTOR2I DS_DATA_ITEM::GetEndPosIU( int ii ) const
|
||||
{
|
||||
VECTOR2D pos = GetEndPos( ii );
|
||||
pos = pos * DS_DATA_MODEL::GetTheInstance().m_WSunits2Iu;
|
||||
@@ -343,17 +343,13 @@ bool DS_DATA_ITEM::IsInsidePage( int ii ) const
|
||||
{
|
||||
DS_DATA_MODEL& model = DS_DATA_MODEL::GetTheInstance();
|
||||
|
||||
VECTOR2D pos = GetStartPos( ii );
|
||||
|
||||
for( int kk = 0; kk < 1; kk++ )
|
||||
for( const VECTOR2D& pos : { GetStartPos( ii ), GetEndPos( ii ) } )
|
||||
{
|
||||
if( model.m_RB_Corner.x < pos.x || model.m_LT_Corner.x > pos.x )
|
||||
return false;
|
||||
|
||||
if( model.m_RB_Corner.y < pos.y || model.m_LT_Corner.y > pos.y )
|
||||
return false;
|
||||
|
||||
pos = GetEndPos( ii );
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -406,11 +402,11 @@ void DS_DATA_ITEM_POLYGONS::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX:
|
||||
|
||||
for( int j = 0; j < m_RepeatCount; j++ )
|
||||
{
|
||||
if( j && !IsInsidePage( j ) )
|
||||
if( j > 0 && !IsInsidePage( j ) )
|
||||
continue;
|
||||
|
||||
int pensize = GetPenSizeUi();
|
||||
auto poly_shape = new DS_DRAW_ITEM_POLYPOLYGONS( this, j, GetStartPosUi( j ), pensize );
|
||||
auto poly_shape = new DS_DRAW_ITEM_POLYPOLYGONS( this, j, GetStartPosIU( j ), pensize );
|
||||
poly_shape->SetFlags( itemFlags[ j ] );
|
||||
m_drawItems.push_back( poly_shape );
|
||||
|
||||
@@ -584,7 +580,7 @@ void DS_DATA_ITEM_TEXT::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX::VIE
|
||||
if( j > 0 && !IsInsidePage( j ) )
|
||||
continue;
|
||||
|
||||
text = new DS_DRAW_ITEM_TEXT( this, j, m_FullText, GetStartPosUi( j ), textsize, pensize,
|
||||
text = new DS_DRAW_ITEM_TEXT( this, j, m_FullText, GetStartPosIU( j ), textsize, pensize,
|
||||
m_Font, m_Italic, m_Bold, m_TextColor );
|
||||
text->SetFlags( itemFlags[ j ] );
|
||||
m_drawItems.push_back( text );
|
||||
@@ -595,14 +591,14 @@ void DS_DATA_ITEM_TEXT::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX::VIE
|
||||
if( aView )
|
||||
aView->Add( text );
|
||||
|
||||
text->SetHorizJustify( m_Hjustify ) ;
|
||||
text->SetHorizJustify( m_Hjustify );
|
||||
text->SetVertJustify( m_Vjustify );
|
||||
text->SetTextAngle( EDA_ANGLE( m_Orient, DEGREES_T ) );
|
||||
text->SetMultilineAllowed( multilines );
|
||||
|
||||
// Increment label for the next text (has no meaning for multiline texts)
|
||||
if( m_RepeatCount > 1 && !multilines )
|
||||
IncrementLabel(( j + 1 ) * m_IncrementLabel );
|
||||
IncrementLabel( ( j + 1 ) * m_IncrementLabel );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -746,10 +742,10 @@ void DS_DATA_ITEM_BITMAP::SyncDrawItems( DS_DRAW_ITEM_LIST* aCollector, KIGFX::V
|
||||
|
||||
for( int j = 0; j < m_RepeatCount; j++ )
|
||||
{
|
||||
if( j && !IsInsidePage( j ) )
|
||||
if( j > 0 && !IsInsidePage( j ) )
|
||||
continue;
|
||||
|
||||
DS_DRAW_ITEM_BITMAP* bitmap = new DS_DRAW_ITEM_BITMAP( this, j, GetStartPosUi( j ) );
|
||||
DS_DRAW_ITEM_BITMAP* bitmap = new DS_DRAW_ITEM_BITMAP( this, j, GetStartPosIU( j ) );
|
||||
|
||||
bitmap->SetFlags( itemFlags[ j ] );
|
||||
m_drawItems.push_back( bitmap );
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2013-2016 CERN
|
||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* @author Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||
*
|
||||
@@ -247,13 +247,14 @@ void DS_DATA_MODEL_IO::format( DS_DATA_ITEM_TEXT* aItem, int aNestLevel ) const
|
||||
// Write font info, only if it is not the default setup
|
||||
bool write_size = aItem->m_TextSize.x != 0.0 || aItem->m_TextSize.y != 0.0;
|
||||
bool write_thickness = aItem->m_LineWidth != 0.0;
|
||||
bool write_face = aItem->m_Font && !aItem->m_Font->GetName().IsEmpty();
|
||||
|
||||
if( write_thickness || write_size || aItem->m_Bold
|
||||
|| aItem->m_Italic || aItem->m_TextColor != COLOR4D::UNSPECIFIED )
|
||||
if( write_thickness || write_size || aItem->m_Bold || aItem->m_Italic
|
||||
|| write_face || aItem->m_TextColor != COLOR4D::UNSPECIFIED )
|
||||
{
|
||||
m_out->Print( 0, " (font" );
|
||||
|
||||
if( aItem->m_Font && !aItem->m_Font->GetName().IsEmpty() )
|
||||
if( write_face )
|
||||
m_out->Print( 0, " (face \"%s\")", aItem->m_Font->NameAsToken() );
|
||||
|
||||
if( write_thickness )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 1992-2013 Jean-Pierre Charras <jp.charras at wanadoo.fr>.
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -118,8 +118,12 @@ void DS_DRAW_ITEM_BASE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame,
|
||||
break;
|
||||
|
||||
case DS_DATA_ITEM::DS_TEXT:
|
||||
aList.emplace_back( _( "Text" ), static_cast<DS_DRAW_ITEM_TEXT*>( this )->GetShownText() );
|
||||
{
|
||||
DS_DRAW_ITEM_TEXT* textItem = static_cast<DS_DRAW_ITEM_TEXT*>( this );
|
||||
// Don't use GetShownText(); we want to see the variable references here
|
||||
aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, textItem->GetText() ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case DS_DATA_ITEM::DS_POLYPOLYGON:
|
||||
aList.emplace_back( _( "Imported Shape" ), wxEmptyString );
|
||||
@@ -170,6 +174,37 @@ void DS_DRAW_ITEM_TEXT::PrintWsItem( const RENDER_SETTINGS* aSettings, const VEC
|
||||
}
|
||||
|
||||
|
||||
const BOX2I DS_DRAW_ITEM_TEXT::GetApproxBBox()
|
||||
{
|
||||
// A really dumb over-approximation because doing it for real (even with the stroke font)
|
||||
// shows up large in profiles.
|
||||
|
||||
const TEXT_ATTRIBUTES& attrs = GetAttributes();
|
||||
const wxString text = GetShownText( true );
|
||||
BOX2I bbox( GetTextPos() );
|
||||
|
||||
bbox.SetWidth( (int) text.length() * attrs.m_Size.x * 1.3 );
|
||||
bbox.SetHeight( attrs.m_Size.y );
|
||||
|
||||
switch( attrs.m_Halign )
|
||||
{
|
||||
case GR_TEXT_H_ALIGN_LEFT: break;
|
||||
case GR_TEXT_H_ALIGN_CENTER: bbox.Offset( -bbox.GetWidth() / 2, 0 ); break;
|
||||
case GR_TEXT_H_ALIGN_RIGHT: bbox.Offset( -bbox.GetWidth(), 0 ); break;
|
||||
}
|
||||
|
||||
switch( GetAttributes().m_Valign )
|
||||
{
|
||||
case GR_TEXT_V_ALIGN_TOP: break;
|
||||
case GR_TEXT_V_ALIGN_CENTER: bbox.Offset( 0, -bbox.GetHeight() / 2 ); break;
|
||||
case GR_TEXT_V_ALIGN_BOTTOM: bbox.Offset( 0, -bbox.GetHeight() ); break;
|
||||
}
|
||||
|
||||
bbox.Inflate( attrs.m_Size.x, attrs.m_Size.y / 2 );
|
||||
return bbox;
|
||||
}
|
||||
|
||||
|
||||
const BOX2I DS_DRAW_ITEM_TEXT::GetBoundingBox() const
|
||||
{
|
||||
return EDA_TEXT::GetTextBox();
|
||||
@@ -190,7 +225,7 @@ bool DS_DRAW_ITEM_TEXT::HitTest( const BOX2I& aRect, bool aContains, int aAccura
|
||||
|
||||
wxString DS_DRAW_ITEM_TEXT::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||
{
|
||||
return wxString::Format( _( "Text '%s'" ), GetShownText() );
|
||||
return wxString::Format( _( "Text '%s'" ), KIUI::EllipsizeMenuText( GetText() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ void KIGFX::DS_PAINTER::draw( const DS_DRAW_ITEM_TEXT* aItem, int aLayer ) const
|
||||
attrs.m_StrokeWidth = std::max( aItem->GetEffectiveTextPenWidth(),
|
||||
m_renderSettings.GetDefaultPenWidth() );
|
||||
|
||||
font->Draw( m_gal, aItem->GetShownText(), aItem->GetTextPos(), attrs );
|
||||
font->Draw( m_gal, aItem->GetShownText( true ), aItem->GetTextPos(), attrs );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -126,8 +126,13 @@ void DS_PROXY_VIEW_ITEM::ViewDraw( int aLayer, VIEW* aView ) const
|
||||
ws_settings->SetDefaultFont( settings->GetDefaultFont() );
|
||||
|
||||
// Draw all the components that make the drawing sheet
|
||||
BOX2I viewport( aView->GetViewport().GetOrigin(), aView->GetViewport().GetSize() );
|
||||
|
||||
for( DS_DRAW_ITEM_BASE* item = drawList.GetFirst(); item; item = drawList.GetNext() )
|
||||
ws_painter.Draw( item, LAYER_DRAWINGSHEET );
|
||||
{
|
||||
if( viewport.Intersects( item->GetApproxBBox() ) )
|
||||
ws_painter.Draw( item, LAYER_DRAWINGSHEET );
|
||||
}
|
||||
|
||||
// Draw gray line that outlines the sheet size
|
||||
if( settings->GetShowPageLimits() )
|
||||
|
||||
+85
-43
@@ -55,13 +55,15 @@
|
||||
#include <widgets/paged_dialog.h>
|
||||
#include <widgets/wx_infobar.h>
|
||||
#include <widgets/wx_aui_art_providers.h>
|
||||
#include <widgets/wx_grid.h>
|
||||
#include <widgets/wx_treebook.h>
|
||||
#include <wx/app.h>
|
||||
#include <wx/config.h>
|
||||
#include <wx/display.h>
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/treebook.h>
|
||||
#include <kiplatform/app.h>
|
||||
#include <kiplatform/io.h>
|
||||
#include <kiplatform/ui.h>
|
||||
|
||||
#include <functional>
|
||||
@@ -166,15 +168,28 @@ EDA_BASE_FRAME::EDA_BASE_FRAME( wxWindow* aParent, FRAME_T aFrameType, const wxS
|
||||
}
|
||||
|
||||
|
||||
wxWindow* findQuasiModalDialog( wxWindow* aParent )
|
||||
{
|
||||
for( wxWindow* child : aParent->GetChildren() )
|
||||
{
|
||||
if( DIALOG_SHIM* dlg = dynamic_cast<DIALOG_SHIM*>( child ) )
|
||||
{
|
||||
if( dlg->IsQuasiModal() )
|
||||
return dlg;
|
||||
|
||||
if( wxWindow* nestedDlg = findQuasiModalDialog( child ) )
|
||||
return nestedDlg;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
wxWindow* EDA_BASE_FRAME::findQuasiModalDialog()
|
||||
{
|
||||
for( wxWindow* iter : GetChildren() )
|
||||
{
|
||||
DIALOG_SHIM* dlg = dynamic_cast<DIALOG_SHIM*>( iter );
|
||||
|
||||
if( dlg && dlg->IsQuasiModal() )
|
||||
return dlg;
|
||||
}
|
||||
if( wxWindow* dlg = ::findQuasiModalDialog( this ) )
|
||||
return dlg;
|
||||
|
||||
// FIXME: CvPcb is currently implemented on top of KIWAY_PLAYER rather than DIALOG_SHIM,
|
||||
// so we have to look for it separately.
|
||||
@@ -403,6 +418,8 @@ void EDA_BASE_FRAME::HandleUpdateUIEvent( wxUpdateUIEvent& aEvent, EDA_BASE_FRAM
|
||||
enableRes = true;
|
||||
else if( textEntry && isPaste && textEntry->CanPaste() )
|
||||
enableRes = true;
|
||||
else if( dynamic_cast<WX_GRID*>( focus ) )
|
||||
enableRes = false; // Must disable menu in order to get command as CharHook event
|
||||
}
|
||||
|
||||
aEvent.Enable( enableRes );
|
||||
@@ -1005,26 +1022,45 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
|
||||
{
|
||||
wxBeginBusyCursor( wxHOURGLASS_CURSOR );
|
||||
|
||||
PAGED_DIALOG dlg( this, _( "Preferences" ), true );
|
||||
PAGED_DIALOG dlg( this, _( "Preferences" ), true, wxEmptyString, wxSize( 980, 560 ) );
|
||||
|
||||
dlg.SetEvtHandlerEnabled( false );
|
||||
wxTreebook* book = dlg.GetTreebook();
|
||||
|
||||
WX_TREEBOOK* book = dlg.GetTreebook();
|
||||
PANEL_HOTKEYS_EDITOR* hotkeysPanel = new PANEL_HOTKEYS_EDITOR( this, book, false );
|
||||
KIFACE* kiface = nullptr;
|
||||
std::vector<int> expand;
|
||||
|
||||
Kiway().GetActions( hotkeysPanel->ActionsList() );
|
||||
|
||||
book->AddPage( new PANEL_COMMON_SETTINGS( &dlg, book ), _( "Common" ) );
|
||||
book->AddPage( new PANEL_MOUSE_SETTINGS( &dlg, book ), _( "Mouse and Touchpad" ) );
|
||||
book->AddLazyPage(
|
||||
[]( wxWindow* aParent ) -> wxWindow*
|
||||
{
|
||||
return new PANEL_COMMON_SETTINGS( aParent );
|
||||
},
|
||||
_( "Common" ) );
|
||||
|
||||
book->AddLazyPage(
|
||||
[]( wxWindow* aParent ) -> wxWindow*
|
||||
{
|
||||
return new PANEL_MOUSE_SETTINGS( aParent );
|
||||
}, _( "Mouse and Touchpad" ) );
|
||||
|
||||
book->AddPage( hotkeysPanel, _( "Hotkeys" ) );
|
||||
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
book->AddPage( new PANEL_DATA_COLLECTION( &dlg, book ), _( "Data Collection" ) );
|
||||
book->AddLazyPage(
|
||||
[]( wxWindow* aParent ) -> wxWindow*
|
||||
{
|
||||
return new PANEL_DATA_COLLECTION( aParent );
|
||||
}, _( "Data Collection" ) );
|
||||
#endif
|
||||
|
||||
#define CREATE_PANEL( key ) kiface->CreateKiWindow( book, key, &Kiway() )
|
||||
#define LAZY_CTOR( key ) \
|
||||
[=]( wxWindow* aParent ) \
|
||||
{ \
|
||||
return kiface->CreateKiWindow( aParent, key, &Kiway() ); \
|
||||
}
|
||||
|
||||
// If a dll is not loaded, the loader will show an error message.
|
||||
|
||||
@@ -1038,20 +1074,19 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
|
||||
expand.push_back( book->GetPageCount() );
|
||||
|
||||
book->AddPage( new wxPanel( book ), _( "Symbol Editor" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_SYM_DISP_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_SYM_EDIT_OPTIONS ), _( "Editing Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_SYM_COLORS ), _( "Colors" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_DISP_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_EDIT_OPTIONS ), _( "Editing Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_SYM_COLORS ), _( "Colors" ) );
|
||||
|
||||
if( GetFrameType() == FRAME_SCH )
|
||||
expand.push_back( book->GetPageCount() );
|
||||
|
||||
book->AddPage( new wxPanel( book ), _( "Schematic Editor" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_SCH_DISP_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_SCH_EDIT_OPTIONS ), _( "Editing Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_SCH_ANNO_OPTIONS ), _( "Annotation Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_SCH_COLORS ), _( "Colors" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_SCH_FIELD_NAME_TEMPLATES ),
|
||||
_( "Field Name Templates" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_DISP_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_EDIT_OPTIONS ), _( "Editing Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_ANNO_OPTIONS ), _( "Annotation Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_COLORS ), _( "Colors" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_SCH_FIELD_NAME_TEMPLATES ), _( "Field Name Templates" ) );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
@@ -1067,29 +1102,29 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
|
||||
expand.push_back( book->GetPageCount() );
|
||||
|
||||
book->AddPage( new wxPanel( book ), _( "Footprint Editor" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_FP_DISPLAY_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_FP_EDIT_OPTIONS ), _( "Editing Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_FP_COLORS ), _( "Colors" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_FP_DEFAULT_VALUES ), _( "Default Values" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_FP_DISPLAY_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_FP_EDIT_OPTIONS ), _( "Editing Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_FP_COLORS ), _( "Colors" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_FP_DEFAULT_VALUES ), _( "Default Values" ) );
|
||||
|
||||
if( GetFrameType() == FRAME_PCB_EDITOR )
|
||||
expand.push_back( book->GetPageCount() );
|
||||
|
||||
book->AddPage( new wxPanel( book ), _( "PCB Editor" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_PCB_DISPLAY_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_PCB_EDIT_OPTIONS ), _( "Editing Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_PCB_COLORS ), _( "Colors" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_PCB_ACTION_PLUGINS ), _( "Action Plugins" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_PCB_ORIGINS_AXES ), _( "Origins & Axes" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_DISPLAY_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_EDIT_OPTIONS ), _( "Editing Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_COLORS ), _( "Colors" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_ACTION_PLUGINS ), _( "Action Plugins" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_PCB_ORIGINS_AXES ), _( "Origins & Axes" ) );
|
||||
|
||||
if( GetFrameType() == FRAME_PCB_DISPLAY3D )
|
||||
expand.push_back( book->GetPageCount() );
|
||||
|
||||
book->AddPage( new wxPanel( book ), _( "3D Viewer" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_3DV_DISPLAY_OPTIONS ), _( "General" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_3DV_OPENGL ), _( "Realtime Renderer" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_3DV_RAYTRACING ), _( "Raytracing Renderer" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_3DV_COLORS ), _( "Colors" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_DISPLAY_OPTIONS ), _( "General" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_OPENGL ), _( "Realtime Renderer" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_RAYTRACING ), _( "Raytracing Renderer" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_3DV_COLORS ), _( "Colors" ) );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
@@ -1105,9 +1140,9 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
|
||||
expand.push_back( book->GetPageCount() );
|
||||
|
||||
book->AddPage( new wxPanel( book ), _( "Gerber Viewer" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_GBR_DISPLAY_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_GBR_COLORS ), _( "Colors" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_GBR_EXCELLON_OPTIONS ), _( "Excellon Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_DISPLAY_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_COLORS ), _( "Colors" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_EXCELLON_OPTIONS ), _( "Excellon Options" ) );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
@@ -1122,10 +1157,14 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
|
||||
expand.push_back( book->GetPageCount() );
|
||||
|
||||
book->AddPage( new wxPanel( book ), _( "Drawing Sheet Editor" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_DS_DISPLAY_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddSubPage( CREATE_PANEL( PANEL_DS_COLORS ), _( "Colors" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_DS_DISPLAY_OPTIONS ), _( "Display Options" ) );
|
||||
book->AddLazySubPage( LAZY_CTOR( PANEL_DS_COLORS ), _( "Colors" ) );
|
||||
|
||||
book->AddPage( new PANEL_PCM_SETTINGS( book ), _( "Plugin and Content Manager" ) );
|
||||
book->AddLazyPage(
|
||||
[]( wxWindow* aParent ) -> wxWindow*
|
||||
{
|
||||
return new PANEL_PCM_SETTINGS( aParent );
|
||||
}, _( "Plugin and Content Manager" ) );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
@@ -1153,7 +1192,7 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
|
||||
dlg.Kiway().CommonSettingsChanged( false, false );
|
||||
}
|
||||
|
||||
#undef CREATE_PANEL
|
||||
#undef LAZY_CTOR
|
||||
}
|
||||
|
||||
|
||||
@@ -1265,6 +1304,9 @@ void EDA_BASE_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
|
||||
// the file name.
|
||||
if( response == wxYES )
|
||||
{
|
||||
// Preserve the permissions of the current file
|
||||
KIPLATFORM::IO::DuplicatePermissions( aFileName.GetFullPath(), autoSaveFileName.GetFullPath() );
|
||||
|
||||
if( !wxRenameFile( autoSaveFileName.GetFullPath(), aFileName.GetFullPath() ) )
|
||||
{
|
||||
wxMessageBox( _( "The auto save file could not be renamed to the board file name." ),
|
||||
|
||||
@@ -144,6 +144,10 @@ bool GetAssociatedDocument( wxWindow* aParent, const wxString& aDocName, PROJECT
|
||||
|
||||
wxFileName currentFileName( fullfilename );
|
||||
|
||||
// Use wxWidgets to resolve any "." and ".." in the path
|
||||
currentFileName.MakeAbsolute();
|
||||
fullfilename = currentFileName.GetFullPath();
|
||||
|
||||
wxString file_ext = currentFileName.GetExt();
|
||||
|
||||
if( file_ext.Lower() == wxT( "pdf" ) )
|
||||
|
||||
+26
-32
@@ -27,6 +27,7 @@
|
||||
#include <bitmaps.h>
|
||||
#include <confirm.h>
|
||||
#include <core/arraydim.h>
|
||||
#include <core/kicad_algo.h>
|
||||
#include <dialog_shim.h>
|
||||
#include <eda_draw_frame.h>
|
||||
#include <file_history.h>
|
||||
@@ -216,15 +217,22 @@ EDA_DRAW_FRAME::~EDA_DRAW_FRAME()
|
||||
|
||||
void EDA_DRAW_FRAME::ReleaseFile()
|
||||
{
|
||||
m_file_checker = nullptr;
|
||||
if( m_file_checker.get() != nullptr )
|
||||
m_file_checker->UnlockFile();
|
||||
}
|
||||
|
||||
|
||||
bool EDA_DRAW_FRAME::LockFile( const wxString& aFileName )
|
||||
{
|
||||
m_file_checker = ::LockFile( aFileName );
|
||||
// We need to explicitly reset here to get the deletion before
|
||||
// we create a new unique_ptr that may be for the same file
|
||||
m_file_checker.reset();
|
||||
|
||||
return m_file_checker && !m_file_checker->IsAnotherRunning();
|
||||
m_file_checker = std::make_unique<LOCKFILE>( aFileName );
|
||||
|
||||
// If the file is valid, return true. This could mean that the file is
|
||||
// locked or it could mean that the file is read-only
|
||||
return m_file_checker->Valid();
|
||||
}
|
||||
|
||||
|
||||
@@ -741,21 +749,21 @@ void EDA_DRAW_FRAME::SaveSettings( APP_SETTINGS_BASE* aCfg )
|
||||
void EDA_DRAW_FRAME::AppendMsgPanel( const wxString& aTextUpper, const wxString& aTextLower,
|
||||
int aPadding )
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
m_messagePanel->AppendMessage( aTextUpper, aTextLower, aPadding );
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_FRAME::ClearMsgPanel()
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
m_messagePanel->EraseMsgBox();
|
||||
}
|
||||
|
||||
|
||||
void EDA_DRAW_FRAME::SetMsgPanel( const std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
{
|
||||
m_messagePanel->EraseMsgBox();
|
||||
|
||||
@@ -768,10 +776,9 @@ void EDA_DRAW_FRAME::SetMsgPanel( const std::vector<MSG_PANEL_ITEM>& aList )
|
||||
void EDA_DRAW_FRAME::SetMsgPanel( const wxString& aTextUpper, const wxString& aTextLower,
|
||||
int aPadding )
|
||||
{
|
||||
if( m_messagePanel )
|
||||
if( m_messagePanel && !m_isClosing )
|
||||
{
|
||||
m_messagePanel->EraseMsgBox();
|
||||
|
||||
m_messagePanel->AppendMessage( aTextUpper, aTextLower, aPadding );
|
||||
}
|
||||
}
|
||||
@@ -842,26 +849,15 @@ bool EDA_DRAW_FRAME::saveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvas
|
||||
// Not all classes derived from EDA_DRAW_FRAME can save the canvas type, because some
|
||||
// have a fixed type, or do not have a option to set the canvas type (they inherit from
|
||||
// a parent frame)
|
||||
FRAME_T allowed_frames[] =
|
||||
{
|
||||
FRAME_SCH, FRAME_SCH_SYMBOL_EDITOR,
|
||||
FRAME_PCB_EDITOR, FRAME_FOOTPRINT_EDITOR,
|
||||
FRAME_GERBER,
|
||||
FRAME_PL_EDITOR
|
||||
};
|
||||
static std::vector<FRAME_T> s_allowedFrames =
|
||||
{
|
||||
FRAME_SCH, FRAME_SCH_SYMBOL_EDITOR,
|
||||
FRAME_PCB_EDITOR, FRAME_FOOTPRINT_EDITOR,
|
||||
FRAME_GERBER,
|
||||
FRAME_PL_EDITOR
|
||||
};
|
||||
|
||||
bool allow_save = false;
|
||||
|
||||
for( unsigned ii = 0; ii < arrayDim( allowed_frames ); ii++ )
|
||||
{
|
||||
if( m_ident == allowed_frames[ii] )
|
||||
{
|
||||
allow_save = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !allow_save )
|
||||
if( !alg::contains( s_allowedFrames, m_ident ) )
|
||||
return false;
|
||||
|
||||
if( aCanvasType < EDA_DRAW_PANEL_GAL::GAL_TYPE_NONE
|
||||
@@ -871,9 +867,7 @@ bool EDA_DRAW_FRAME::saveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvas
|
||||
return false;
|
||||
}
|
||||
|
||||
APP_SETTINGS_BASE* cfg = Kiface().KifaceSettings();
|
||||
|
||||
if( cfg )
|
||||
if( APP_SETTINGS_BASE* cfg = Kiface().KifaceSettings() )
|
||||
cfg->m_Graphics.canvas_type = static_cast<int>( aCanvasType );
|
||||
|
||||
return false;
|
||||
@@ -883,7 +877,7 @@ bool EDA_DRAW_FRAME::saveCanvasTypeSetting( EDA_DRAW_PANEL_GAL::GAL_TYPE aCanvas
|
||||
VECTOR2I EDA_DRAW_FRAME::GetNearestGridPosition( const VECTOR2I& aPosition ) const
|
||||
{
|
||||
const VECTOR2I& gridOrigin = GetGridOrigin();
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize();
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize();
|
||||
|
||||
double xOffset = fmod( gridOrigin.x, gridSize.x );
|
||||
int x = KiROUND( (aPosition.x - xOffset) / gridSize.x );
|
||||
@@ -897,7 +891,7 @@ VECTOR2I EDA_DRAW_FRAME::GetNearestGridPosition( const VECTOR2I& aPosition ) con
|
||||
VECTOR2I EDA_DRAW_FRAME::GetNearestHalfGridPosition( const VECTOR2I& aPosition ) const
|
||||
{
|
||||
const VECTOR2I& gridOrigin = GetGridOrigin();
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize() / 2.0;
|
||||
VECTOR2D gridSize = GetCanvas()->GetGAL()->GetGridSize() / 2.0;
|
||||
|
||||
double xOffset = fmod( gridOrigin.x, gridSize.x );
|
||||
int x = KiROUND( (aPosition.x - xOffset) / gridSize.x );
|
||||
|
||||
@@ -412,6 +412,30 @@ bool EDA_COMBINED_MATCHER::Find( const wxString& aTerm, int& aMatchersTriggered,
|
||||
}
|
||||
|
||||
|
||||
bool EDA_COMBINED_MATCHER::Find( const wxString& aTerm )
|
||||
{
|
||||
for( const std::unique_ptr<EDA_PATTERN_MATCH>& matcher : m_matchers )
|
||||
{
|
||||
if( matcher->Find( aTerm ).start >= 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool EDA_COMBINED_MATCHER::StartsWith( const wxString& aTerm )
|
||||
{
|
||||
for( const std::unique_ptr<EDA_PATTERN_MATCH>& matcher : m_matchers )
|
||||
{
|
||||
if( matcher->Find( aTerm ).start == 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
wxString const& EDA_COMBINED_MATCHER::GetPattern() const
|
||||
{
|
||||
return m_pattern;
|
||||
|
||||
+65
-53
@@ -37,6 +37,7 @@
|
||||
#include <callback_gal.h>
|
||||
#include <eda_text.h> // for EDA_TEXT, TEXT_EFFECTS, GR_TEXT_VJUSTIF...
|
||||
#include <gal/color4d.h> // for COLOR4D, COLOR4D::BLACK
|
||||
#include <font/glyph.h>
|
||||
#include <gr_text.h>
|
||||
#include <string_utils.h> // for UnescapeString
|
||||
#include <math/util.h> // for KiROUND
|
||||
@@ -90,6 +91,7 @@ GR_TEXT_V_ALIGN_T EDA_TEXT::MapVertJustify( int aVertJustify )
|
||||
EDA_TEXT::EDA_TEXT( const EDA_IU_SCALE& aIuScale, const wxString& aText ) :
|
||||
m_text( aText ),
|
||||
m_IuScale( aIuScale ),
|
||||
m_render_cache_font( nullptr ),
|
||||
m_bounding_box_cache_valid( false ),
|
||||
m_bounding_box_cache_line( -1 ),
|
||||
m_bounding_box_cache_inverted( false )
|
||||
@@ -110,15 +112,19 @@ EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText ) :
|
||||
m_attributes = aText.m_attributes;
|
||||
m_pos = aText.m_pos;
|
||||
|
||||
m_render_cache_font = aText.m_render_cache_font;
|
||||
m_render_cache_text = aText.m_render_cache_text;
|
||||
m_render_cache_angle = aText.m_render_cache_angle;
|
||||
m_render_cache_offset = aText.m_render_cache_offset;
|
||||
|
||||
m_render_cache.clear();
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aText.m_render_cache )
|
||||
{
|
||||
KIFONT::OUTLINE_GLYPH* outline_glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() );
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline_glyph ) );
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
|
||||
}
|
||||
|
||||
m_bounding_box_cache_valid = aText.m_bounding_box_cache_valid;
|
||||
@@ -142,15 +148,19 @@ EDA_TEXT& EDA_TEXT::operator=( const EDA_TEXT& aText )
|
||||
m_attributes = aText.m_attributes;
|
||||
m_pos = aText.m_pos;
|
||||
|
||||
m_render_cache_font = aText.m_render_cache_font;
|
||||
m_render_cache_text = aText.m_render_cache_text;
|
||||
m_render_cache_angle = aText.m_render_cache_angle;
|
||||
m_render_cache_offset = aText.m_render_cache_offset;
|
||||
|
||||
m_render_cache.clear();
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aText.m_render_cache )
|
||||
{
|
||||
KIFONT::OUTLINE_GLYPH* outline_glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() );
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline_glyph ) );
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
m_render_cache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
|
||||
}
|
||||
|
||||
m_bounding_box_cache_valid = aText.m_bounding_box_cache_valid;
|
||||
@@ -388,10 +398,18 @@ void EDA_TEXT::SetTextY( int aY )
|
||||
|
||||
void EDA_TEXT::Offset( const VECTOR2I& aOffset )
|
||||
{
|
||||
if( aOffset.x == 0 && aOffset.y == 0 )
|
||||
return;
|
||||
|
||||
m_pos += aOffset;
|
||||
|
||||
for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_render_cache )
|
||||
static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( aOffset );
|
||||
{
|
||||
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
|
||||
outline->Move( aOffset );
|
||||
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
|
||||
glyph = stroke->Transform( { 1.0, 1.0 }, aOffset, 0, ANGLE_0, false, { 0, 0 } );
|
||||
}
|
||||
|
||||
m_bounding_box_cache_valid = false;
|
||||
}
|
||||
@@ -451,23 +469,26 @@ std::vector<std::unique_ptr<KIFONT::GLYPH>>*
|
||||
EDA_TEXT::GetRenderCache( const KIFONT::FONT* aFont, const wxString& forResolvedText,
|
||||
const VECTOR2I& aOffset ) const
|
||||
{
|
||||
if( getDrawFont()->IsOutline() )
|
||||
if( aFont->IsOutline() )
|
||||
{
|
||||
EDA_ANGLE resolvedAngle = GetDrawRotation();
|
||||
|
||||
if( m_render_cache.empty()
|
||||
|| m_render_cache_font != aFont
|
||||
|| m_render_cache_text != forResolvedText
|
||||
|| m_render_cache_angle != resolvedAngle
|
||||
|| m_render_cache_offset != aOffset )
|
||||
{
|
||||
m_render_cache.clear();
|
||||
|
||||
KIFONT::OUTLINE_FONT* font = static_cast<KIFONT::OUTLINE_FONT*>( getDrawFont() );
|
||||
TEXT_ATTRIBUTES attrs = GetAttributes();
|
||||
const KIFONT::OUTLINE_FONT* font = static_cast<const KIFONT::OUTLINE_FONT*>( aFont );
|
||||
TEXT_ATTRIBUTES attrs = GetAttributes();
|
||||
|
||||
attrs.m_Angle = resolvedAngle;
|
||||
|
||||
font->GetLinesAsGlyphs( &m_render_cache, GetShownText(), GetDrawPos() + aOffset, attrs );
|
||||
font->GetLinesAsGlyphs( &m_render_cache, forResolvedText, GetDrawPos() + aOffset,
|
||||
attrs );
|
||||
m_render_cache_font = aFont;
|
||||
m_render_cache_angle = resolvedAngle;
|
||||
m_render_cache_text = forResolvedText;
|
||||
m_render_cache_offset = aOffset;
|
||||
@@ -514,7 +535,7 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
|
||||
|
||||
BOX2I bbox;
|
||||
wxArrayString strings;
|
||||
wxString text = GetShownText();
|
||||
wxString text = GetShownText( true );
|
||||
int thickness = GetEffectiveTextPenWidth();
|
||||
|
||||
if( IsMultilineAllowed() )
|
||||
@@ -542,12 +563,16 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
|
||||
// bounding box will be moved later according to the actual text options
|
||||
wxSize textsize = wxSize( extents.x, extents.y );
|
||||
VECTOR2I pos = drawPos;
|
||||
int fudgeFactor = extents.y * 0.17;
|
||||
|
||||
if( font->IsStroke() )
|
||||
textsize.y += fudgeFactor;
|
||||
|
||||
if( IsMultilineAllowed() && aLine > 0 && aLine < (int) strings.GetCount() )
|
||||
pos.y -= KiROUND( aLine * font->GetInterline( fontSize.y ) );
|
||||
|
||||
if( text.Contains( wxT( "~{" ) ) )
|
||||
overbarOffset = extents.y / 14;
|
||||
overbarOffset = extents.y / 6;
|
||||
|
||||
if( aInvertY )
|
||||
pos.y = -pos.y;
|
||||
@@ -555,7 +580,7 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
|
||||
bbox.SetOrigin( pos );
|
||||
|
||||
// for multiline texts and aLine < 0, merge all rectangles (aLine == -1 signals all lines)
|
||||
if( IsMultilineAllowed() && aLine < 0 && strings.GetCount() )
|
||||
if( IsMultilineAllowed() && aLine < 0 && strings.GetCount() > 1 )
|
||||
{
|
||||
for( unsigned ii = 1; ii < strings.GetCount(); ii++ )
|
||||
{
|
||||
@@ -569,6 +594,8 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
|
||||
textsize.y += KiROUND( ( strings.GetCount() - 1 ) * font->GetInterline( fontSize.y ) );
|
||||
}
|
||||
|
||||
textsize.y += overbarOffset;
|
||||
|
||||
bbox.SetSize( textsize );
|
||||
|
||||
/*
|
||||
@@ -597,14 +624,16 @@ BOX2I EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
|
||||
switch( GetVertJustify() )
|
||||
{
|
||||
case GR_TEXT_V_ALIGN_TOP:
|
||||
bbox.Offset( 0, -fudgeFactor );
|
||||
break;
|
||||
|
||||
case GR_TEXT_V_ALIGN_CENTER:
|
||||
bbox.SetY( bbox.GetY() - ( bbox.GetHeight() + overbarOffset ) / 2 );
|
||||
bbox.SetY( bbox.GetY() - bbox.GetHeight() / 2 );
|
||||
break;
|
||||
|
||||
case GR_TEXT_V_ALIGN_BOTTOM:
|
||||
bbox.SetY( bbox.GetY() - ( bbox.GetHeight() + overbarOffset ) );
|
||||
bbox.SetY( bbox.GetY() - bbox.GetHeight() );
|
||||
bbox.Offset( 0, fudgeFactor );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -652,7 +681,7 @@ void EDA_TEXT::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
|
||||
{
|
||||
std::vector<VECTOR2I> positions;
|
||||
wxArrayString strings;
|
||||
wxStringSplit( GetShownText(), strings, '\n' );
|
||||
wxStringSplit( GetShownText( true ), strings, '\n' );
|
||||
|
||||
positions.reserve( strings.Count() );
|
||||
|
||||
@@ -663,7 +692,8 @@ void EDA_TEXT::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset,
|
||||
}
|
||||
else
|
||||
{
|
||||
printOneLineOfText( aSettings, aOffset, aColor, aFillMode, GetShownText(), GetDrawPos() );
|
||||
printOneLineOfText( aSettings, aOffset, aColor, aFillMode, GetShownText( true ),
|
||||
GetDrawPos() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -857,12 +887,23 @@ std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangula
|
||||
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
|
||||
KIFONT::FONT* font = getDrawFont();
|
||||
int penWidth = GetEffectiveTextPenWidth();
|
||||
wxString shownText( GetShownText( true ) );
|
||||
VECTOR2I drawPos = GetDrawPos();
|
||||
TEXT_ATTRIBUTES attrs = GetAttributes();
|
||||
|
||||
std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
|
||||
|
||||
if( aUseTextRotation )
|
||||
{
|
||||
attrs.m_Angle = GetDrawRotation();
|
||||
|
||||
if( font->IsOutline() )
|
||||
cache = GetRenderCache( font, shownText, drawPos );
|
||||
}
|
||||
else
|
||||
{
|
||||
attrs.m_Angle = ANGLE_0;
|
||||
}
|
||||
|
||||
if( aTriangulate )
|
||||
{
|
||||
@@ -884,7 +925,10 @@ std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangula
|
||||
shape->AddShape( triShape );
|
||||
} );
|
||||
|
||||
font->Draw( &callback_gal, GetShownText(), GetDrawPos(), attrs );
|
||||
if( cache )
|
||||
callback_gal.DrawGlyphs( *cache );
|
||||
else
|
||||
font->Draw( &callback_gal, shownText, drawPos, attrs );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -901,7 +945,10 @@ std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangula
|
||||
shape->AddShape( aPoly.Clone() );
|
||||
} );
|
||||
|
||||
font->Draw( &callback_gal, GetShownText(), GetDrawPos(), attrs );
|
||||
if( cache )
|
||||
callback_gal.DrawGlyphs( *cache );
|
||||
else
|
||||
font->Draw( &callback_gal, shownText, drawPos, attrs );
|
||||
}
|
||||
|
||||
return shape;
|
||||
@@ -942,41 +989,6 @@ int EDA_TEXT::Compare( const EDA_TEXT* aOther ) const
|
||||
}
|
||||
|
||||
|
||||
void EDA_TEXT::TransformBoundingBoxToPolygon( SHAPE_POLY_SET* aBuffer, int aClearance ) const
|
||||
{
|
||||
if( GetText().Length() == 0 )
|
||||
return;
|
||||
|
||||
VECTOR2I corners[4]; // Buffer of polygon corners
|
||||
BOX2I rect = GetTextBox();
|
||||
|
||||
// TrueType bounding boxes aren't guaranteed to include all descenders, diacriticals, etc.
|
||||
// Since we use this for zone knockouts and DRC, we need something more accurate.
|
||||
if( getDrawFont()->IsOutline() )
|
||||
rect = GetEffectiveTextShape( false, false )->BBox();
|
||||
|
||||
rect.Inflate( aClearance );
|
||||
|
||||
corners[0].x = rect.GetOrigin().x;
|
||||
corners[0].y = rect.GetOrigin().y;
|
||||
corners[1].y = corners[0].y;
|
||||
corners[1].x = rect.GetRight();
|
||||
corners[2].x = corners[1].x;
|
||||
corners[2].y = rect.GetBottom();
|
||||
corners[3].y = corners[2].y;
|
||||
corners[3].x = corners[0].x;
|
||||
|
||||
aBuffer->NewOutline();
|
||||
|
||||
for( VECTOR2I& corner : corners )
|
||||
{
|
||||
RotatePoint( corner, GetDrawPos(), GetDrawRotation() );
|
||||
|
||||
aBuffer->Append( corner.x, corner.y );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EDA_TEXT::ValidateHyperlink( const wxString& aURL )
|
||||
{
|
||||
if( aURL.IsEmpty() || IsGotoPageHref( aURL ) )
|
||||
|
||||
+11
-3
@@ -120,10 +120,18 @@ FUTURE_FORMAT_ERROR::FUTURE_FORMAT_ERROR( const PARSE_ERROR& aParseError,
|
||||
const wxString& aRequiredVersion ) :
|
||||
PARSE_ERROR()
|
||||
{
|
||||
init( aRequiredVersion );
|
||||
if( const FUTURE_FORMAT_ERROR* ffe = dynamic_cast<const FUTURE_FORMAT_ERROR*>( &aParseError ) )
|
||||
{
|
||||
requiredVersion = ffe->requiredVersion;
|
||||
problem = ffe->Problem();
|
||||
}
|
||||
else
|
||||
{
|
||||
init( aRequiredVersion );
|
||||
|
||||
if( !aParseError.Problem().IsEmpty() )
|
||||
problem += wxS( "\n\n" ) + _( "Full error text:" ) + wxS( "\n" ) + aParseError.Problem();
|
||||
if( !aParseError.Problem().IsEmpty() )
|
||||
problem += wxS( "\n\n" ) + _( "Full error text:" ) + wxS( "\n" ) + aParseError.Problem();
|
||||
}
|
||||
|
||||
lineNumber = aParseError.lineNumber;
|
||||
byteIndex = aParseError.byteIndex;
|
||||
|
||||
+136
-39
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Ola Rinta-Koski
|
||||
* Copyright (C) 2021-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Font abstract base class
|
||||
*
|
||||
@@ -35,6 +35,7 @@
|
||||
// The "official" name of the building Kicad stroke font (always existing)
|
||||
#include <font/kicad_font_name.h>
|
||||
#include "macros.h"
|
||||
#include "wx/tokenzr.h"
|
||||
|
||||
|
||||
// markup_parser.h includes pegtl.hpp which includes windows.h... which leaks #define DrawText
|
||||
@@ -120,6 +121,13 @@ void FONT::getLinePositions( const wxString& aText, const VECTOR2I& aPosition,
|
||||
VECTOR2I offset( 0, 0 );
|
||||
offset.y += aAttrs.m_Size.y;
|
||||
|
||||
if( IsStroke() )
|
||||
{
|
||||
// Fudge factors to match 6.0 positioning
|
||||
offset.x += aAttrs.m_StrokeWidth / 1.52;
|
||||
offset.y -= aAttrs.m_StrokeWidth * 0.052;
|
||||
}
|
||||
|
||||
switch( aAttrs.m_Valign )
|
||||
{
|
||||
case GR_TEXT_V_ALIGN_TOP: break;
|
||||
@@ -138,7 +146,7 @@ void FONT::getLinePositions( const wxString& aText, const VECTOR2I& aPosition,
|
||||
{
|
||||
case GR_TEXT_H_ALIGN_LEFT: break;
|
||||
case GR_TEXT_H_ALIGN_CENTER: lineOffset.x = -lineSize.x / 2; break;
|
||||
case GR_TEXT_H_ALIGN_RIGHT: lineOffset.x = -lineSize.x; break;
|
||||
case GR_TEXT_H_ALIGN_RIGHT: lineOffset.x = -( lineSize.x + offset.x ); break;
|
||||
}
|
||||
|
||||
aPositions.push_back( aPosition + lineOffset );
|
||||
@@ -191,6 +199,8 @@ VECTOR2I drawMarkup( BOX2I* aBoundingBox, std::vector<std::unique_ptr<GLYPH>>* a
|
||||
bool aMirror, const VECTOR2I& aOrigin, TEXT_STYLE_FLAGS aTextStyle )
|
||||
{
|
||||
VECTOR2I nextPosition = aPosition;
|
||||
bool drawUnderline = false;
|
||||
bool drawOverbar = false;
|
||||
|
||||
if( aNode )
|
||||
{
|
||||
@@ -199,30 +209,79 @@ VECTOR2I drawMarkup( BOX2I* aBoundingBox, std::vector<std::unique_ptr<GLYPH>>* a
|
||||
if( !aNode->is_root() )
|
||||
{
|
||||
if( aNode->isSubscript() )
|
||||
textStyle = TEXT_STYLE::SUBSCRIPT;
|
||||
textStyle |= TEXT_STYLE::SUBSCRIPT;
|
||||
else if( aNode->isSuperscript() )
|
||||
textStyle = TEXT_STYLE::SUPERSCRIPT;
|
||||
textStyle |= TEXT_STYLE::SUPERSCRIPT;
|
||||
|
||||
if( aNode->isOverbar() )
|
||||
textStyle |= TEXT_STYLE::OVERBAR;
|
||||
drawOverbar = true;
|
||||
|
||||
if( aNode->has_content() )
|
||||
{
|
||||
BOX2I bbox;
|
||||
|
||||
nextPosition = aFont->GetTextAsGlyphs( &bbox, aGlyphs, aNode->asWxString(), aSize,
|
||||
aPosition, aAngle, aMirror, aOrigin,
|
||||
nextPosition, aAngle, aMirror, aOrigin,
|
||||
textStyle );
|
||||
|
||||
if( aBoundingBox )
|
||||
aBoundingBox->Merge( bbox );
|
||||
}
|
||||
}
|
||||
else if( aTextStyle & TEXT_STYLE::UNDERLINE )
|
||||
{
|
||||
drawUnderline = true;
|
||||
}
|
||||
|
||||
for( const std::unique_ptr<MARKUP::NODE>& child : aNode->children )
|
||||
{
|
||||
nextPosition = drawMarkup( aBoundingBox, aGlyphs, child, nextPosition, aFont, aSize,
|
||||
aAngle, aMirror, aOrigin, textStyle );
|
||||
aAngle, aMirror, aOrigin, textStyle );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if( drawUnderline )
|
||||
{
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = aSize.x * 0.1;
|
||||
double barOffset = aFont->ComputeUnderlineVerticalPosition( aSize.y );
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barTrim, aPosition.y - barOffset );
|
||||
VECTOR2D barEnd( nextPosition.x - barTrim, nextPosition.y - barOffset );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH barGlyph;
|
||||
|
||||
barGlyph.AddPoint( barStart );
|
||||
barGlyph.AddPoint( barEnd );
|
||||
barGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( barGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false, aAngle, aMirror,
|
||||
aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( drawOverbar )
|
||||
{
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = aSize.x * 0.1;
|
||||
double barOffset = aFont->ComputeOverbarVerticalPosition( aSize.y );
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barTrim, aPosition.y - barOffset );
|
||||
VECTOR2D barEnd( nextPosition.x - barTrim, nextPosition.y - barOffset );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH barGlyph;
|
||||
|
||||
barGlyph.AddPoint( barStart );
|
||||
barGlyph.AddPoint( barEnd );
|
||||
barGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( barGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false, aAngle, aMirror,
|
||||
aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,6 +312,7 @@ void FONT::drawSingleLineText( KIGFX::GAL* aGal, BOX2I* aBoundingBox, const wxSt
|
||||
|
||||
TEXT_STYLE_FLAGS textStyle = 0;
|
||||
|
||||
|
||||
if( aItalic )
|
||||
textStyle |= TEXT_STYLE::ITALIC;
|
||||
|
||||
@@ -281,13 +341,13 @@ VECTOR2I FONT::StringBoundaryLimits( const wxString& aText, const VECTOR2I& aSiz
|
||||
if( aItalic )
|
||||
textStyle |= TEXT_STYLE::ITALIC;
|
||||
|
||||
(void) drawMarkup( &boundingBox, nullptr, aText, VECTOR2I(), aSize, ANGLE_0, false,
|
||||
VECTOR2I(), textStyle );
|
||||
(void) drawMarkup( &boundingBox, nullptr, aText, VECTOR2I(), aSize, ANGLE_0, false, VECTOR2I(),
|
||||
textStyle );
|
||||
|
||||
if( IsStroke() )
|
||||
{
|
||||
// Inflate by a bit more than thickness/2 to catch diacriticals, descenders, etc.
|
||||
boundingBox.Inflate( KiROUND( aThickness * 1.25 ) );
|
||||
boundingBox.Inflate( KiROUND( aThickness * 1.5 ) );
|
||||
}
|
||||
else if( IsOutline() )
|
||||
{
|
||||
@@ -308,7 +368,7 @@ VECTOR2I FONT::boundingBoxSingleLine( BOX2I* aBBox, const wxString& aText,
|
||||
textStyle |= TEXT_STYLE::ITALIC;
|
||||
|
||||
VECTOR2I extents = drawMarkup( aBBox, nullptr, aText, aPosition, aSize, ANGLE_0, false,
|
||||
VECTOR2I(), textStyle );
|
||||
VECTOR2I(), textStyle );
|
||||
|
||||
return extents;
|
||||
}
|
||||
@@ -376,20 +436,22 @@ void wordbreakMarkup( std::vector<std::pair<wxString, int>>* aWords,
|
||||
}
|
||||
else
|
||||
{
|
||||
wxString textRun = aNode->asWxString();
|
||||
wxArrayString words;
|
||||
wxString textRun = aNode->asWxString();
|
||||
wxStringTokenizer tokenizer( textRun, " ", wxTOKEN_RET_DELIMS );
|
||||
std::vector<wxString> words;
|
||||
|
||||
wxStringSplit( textRun, words, ' ' );
|
||||
while( tokenizer.HasMoreTokens() )
|
||||
words.emplace_back( tokenizer.GetNextToken() );
|
||||
|
||||
if( textRun.EndsWith( wxS( " " ) ) )
|
||||
words.Add( wxS( " " ) );
|
||||
|
||||
for( size_t ii = 0; ii < words.size(); ++ii )
|
||||
for( const wxString& word : words )
|
||||
{
|
||||
int w = aFont->GetTextAsGlyphs( nullptr, nullptr, words[ii], aSize, { 0, 0 },
|
||||
wxString chars = word;
|
||||
chars.Trim();
|
||||
|
||||
int w = aFont->GetTextAsGlyphs( nullptr, nullptr, chars, aSize, { 0, 0 },
|
||||
ANGLE_0, false, { 0, 0 }, textStyle ).x;
|
||||
|
||||
aWords->emplace_back( std::make_pair( words[ii], w ) );
|
||||
aWords->emplace_back( std::make_pair( word, w ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,35 +503,70 @@ void FONT::LinebreakText( wxString& aText, int aColumnWidth, const VECTOR2I& aSi
|
||||
|
||||
for( size_t ii = 0; ii < textLines.Count(); ++ii )
|
||||
{
|
||||
bool virginLine = true;
|
||||
int lineWidth = 0;
|
||||
std::vector<std::pair<wxString, int>> markup;
|
||||
std::vector<std::pair<wxString, int>> words;
|
||||
|
||||
wordbreakMarkup( &words, textLines[ii], aSize, textStyle );
|
||||
wordbreakMarkup( &markup, textLines[ii], aSize, textStyle );
|
||||
|
||||
for( size_t jj = 0; jj < words.size(); /* advance in loop */ )
|
||||
for( const auto& [ run, runWidth ] : markup )
|
||||
{
|
||||
if( virginLine )
|
||||
if( !words.empty() && !words.back().first.EndsWith( ' ' ) )
|
||||
{
|
||||
// First word is always placed, even when wider than columnWidth.
|
||||
aText += words[jj].first;
|
||||
lineWidth += words[jj].second;
|
||||
jj++;
|
||||
|
||||
virginLine = false;
|
||||
}
|
||||
else if( lineWidth + spaceWidth + words[jj].second < aColumnWidth - aThickness )
|
||||
{
|
||||
aText += " " + words[jj].first;
|
||||
lineWidth += spaceWidth + words[jj].second;
|
||||
jj++;
|
||||
words.back().first += run;
|
||||
words.back().second += runWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
aText += '\n';
|
||||
words.emplace_back( std::make_pair( run, runWidth ) );
|
||||
}
|
||||
}
|
||||
|
||||
bool buryMode = false;
|
||||
int lineWidth = 0;
|
||||
wxString pendingSpaces;
|
||||
|
||||
for( const auto& [ word, wordWidth ] : words )
|
||||
{
|
||||
int pendingSpaceWidth = (int) pendingSpaces.Length() * spaceWidth;
|
||||
bool overflow = lineWidth + pendingSpaceWidth + wordWidth > aColumnWidth - aThickness;
|
||||
|
||||
if( overflow && pendingSpaces.Length() > 0 )
|
||||
{
|
||||
aText += '\n';
|
||||
lineWidth = 0;
|
||||
virginLine = true;
|
||||
pendingSpaces = wxEmptyString;
|
||||
pendingSpaceWidth = 0;
|
||||
buryMode = true;
|
||||
}
|
||||
|
||||
if( word == wxS( " " ) )
|
||||
{
|
||||
pendingSpaces += word;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( buryMode )
|
||||
{
|
||||
buryMode = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
aText += pendingSpaces;
|
||||
lineWidth += pendingSpaceWidth;
|
||||
}
|
||||
|
||||
if( word.EndsWith( ' ' ) )
|
||||
{
|
||||
aText += word.Left( word.Length() - 1 );
|
||||
pendingSpaces = wxS( " " );
|
||||
}
|
||||
else
|
||||
{
|
||||
aText += word;
|
||||
pendingSpaces = wxEmptyString;
|
||||
}
|
||||
|
||||
lineWidth += wordWidth;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2021 Ola Rinta-Koski <gitlab@rinta-koski.net>
|
||||
* Copyright (C) 2021-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2021-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Outline font class
|
||||
*
|
||||
@@ -313,22 +313,6 @@ VECTOR2I OUTLINE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
|
||||
}
|
||||
|
||||
|
||||
double OUTLINE_FONT::getOverbarOffset( int ascender, int height, int thickness ) const
|
||||
{
|
||||
double thicknessRatio = abs( (double) thickness ) / (double) height;
|
||||
double ascenderRatio = (double) ascender / (double) height;
|
||||
|
||||
if( thicknessRatio < 0.05 )
|
||||
return 0.04;
|
||||
else if( ascenderRatio < 0.78 )
|
||||
return 0.00;
|
||||
else if( ascenderRatio < 0.80 )
|
||||
return -0.03;
|
||||
else
|
||||
return -0.06;
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
@@ -338,14 +322,15 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
return getTextAsGlyphsUnlocked( aBBox, aGlyphs, aText, aSize, aPosition, aAngle, aMirror,
|
||||
aOrigin, aTextStyle );
|
||||
aOrigin, aTextStyle );
|
||||
}
|
||||
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
std::vector<std::unique_ptr<GLYPH>>* aGlyphs,
|
||||
const wxString& aText, const VECTOR2I& aSize,
|
||||
const VECTOR2I& aPosition, const EDA_ANGLE& aAngle,
|
||||
bool aMirror, const VECTOR2I& aOrigin,
|
||||
TEXT_STYLE_FLAGS aTextStyle ) const
|
||||
{
|
||||
VECTOR2D glyphSize = aSize;
|
||||
FT_Face face = m_face;
|
||||
@@ -377,6 +362,9 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::u
|
||||
|
||||
VECTOR2I cursor( 0, 0 );
|
||||
|
||||
if( aGlyphs )
|
||||
aGlyphs->reserve( glyphCount );
|
||||
|
||||
for( unsigned int i = 0; i < glyphCount; i++ )
|
||||
{
|
||||
// Don't process glyphs that were already included in a previous cluster
|
||||
@@ -395,7 +383,7 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::u
|
||||
matrix.yx = (FT_Fixed) ( 0 * 0x10000L ); // Don't rotate in the y direction
|
||||
matrix.yy = (FT_Fixed) ( 1 * 0x10000L );
|
||||
|
||||
FT_Set_Transform(face, &matrix,0);
|
||||
FT_Set_Transform( face, &matrix, 0 );
|
||||
}
|
||||
|
||||
FT_Load_Glyph( face, glyphInfo[i].codepoint, FT_LOAD_NO_BITMAP );
|
||||
@@ -418,6 +406,8 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::u
|
||||
GLYPH_POINTS points = c.m_Points;
|
||||
SHAPE_LINE_CHAIN shape;
|
||||
|
||||
shape.ReservePoints( points.size() );
|
||||
|
||||
for( const VECTOR2D& v : points )
|
||||
{
|
||||
VECTOR2D pt( v + cursor );
|
||||
@@ -462,13 +452,6 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::u
|
||||
}
|
||||
}
|
||||
|
||||
// FONT TODO we might not want to do Fracture() here;
|
||||
// knockout text (eg. silkscreen labels with a background) will
|
||||
// need to do that after the contours have been turned into holes
|
||||
// and vice versa
|
||||
if( glyph->HasHoles() )
|
||||
glyph->Fracture( SHAPE_POLY_SET::PM_FAST ); // FONT TODO verify aFastMode
|
||||
|
||||
aGlyphs->push_back( std::move( glyph ) );
|
||||
}
|
||||
|
||||
@@ -478,75 +461,9 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox, std::vector<std::u
|
||||
}
|
||||
|
||||
int ascender = abs( face->size->metrics.ascender * GLYPH_SIZE_SCALER );
|
||||
int height = abs( face->size->metrics.height * GLYPH_SIZE_SCALER );
|
||||
int descender = abs( face->size->metrics.descender * GLYPH_SIZE_SCALER );
|
||||
VECTOR2I extents( cursor.x * scaleFactor.x, ( ascender + descender ) * abs( scaleFactor.y ) );
|
||||
|
||||
// Font metrics don't include all descenders and diacriticals, so beef them up just a little.
|
||||
extents.y *= 1.05;
|
||||
|
||||
if( IsOverbar( aTextStyle ) )
|
||||
{
|
||||
std::vector<std::unique_ptr<GLYPH>> underscoreGlyphs;
|
||||
|
||||
getTextAsGlyphsUnlocked( nullptr, &underscoreGlyphs, wxT( "_" ), aSize, { 0, 0 }, ANGLE_0, false,
|
||||
{ 0, 0 }, aTextStyle & ~TEXT_STYLE::OVERBAR );
|
||||
|
||||
OUTLINE_GLYPH* underscoreGlyph = static_cast<OUTLINE_GLYPH*>( underscoreGlyphs[0].get() );
|
||||
BOX2I underscoreBBox;
|
||||
|
||||
for( const VECTOR2I& pt : underscoreGlyph->Outline( 0 ).CPoints() )
|
||||
underscoreBBox.Merge( pt );
|
||||
|
||||
int barThickness = underscoreBBox.GetHeight();
|
||||
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = barThickness / 2.0;
|
||||
double barOffset = getOverbarOffset( ascender, height, barThickness / scaleFactor.y );
|
||||
|
||||
VECTOR2I topLeft( aPosition );
|
||||
VECTOR2I topRight( aPosition );
|
||||
|
||||
topLeft.y += ascender * scaleFactor.y * ( 1.0 + barOffset );
|
||||
topRight.y = topLeft.y;
|
||||
|
||||
topLeft.x += barTrim;
|
||||
topRight.x += extents.x - barTrim;
|
||||
|
||||
extents.y *= ( 1.0 + barOffset + barOffset );
|
||||
extents.x += barTrim;
|
||||
|
||||
if( IsItalic() )
|
||||
{
|
||||
topLeft.x += aSize.y * ITALIC_TILT;
|
||||
topRight.x += aSize.y * ITALIC_TILT;
|
||||
extents.x += aSize.y * ITALIC_TILT;
|
||||
}
|
||||
|
||||
if( aMirror )
|
||||
{
|
||||
topLeft.x = aOrigin.x - ( topLeft.x - aOrigin.x );
|
||||
topRight.x = aOrigin.x - ( topRight.x - aOrigin.x );
|
||||
}
|
||||
|
||||
if( !aAngle.IsZero() )
|
||||
{
|
||||
RotatePoint( topLeft, aOrigin, aAngle );
|
||||
RotatePoint( topRight, aOrigin, aAngle );
|
||||
}
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
int maxError = KiROUND( barThickness / 48 );
|
||||
SHAPE_POLY_SET poly;
|
||||
|
||||
TransformOvalToPolygon( poly, topLeft, topRight, barThickness, maxError, ERROR_INSIDE );
|
||||
|
||||
std::unique_ptr<OUTLINE_GLYPH> overbarGlyph = std::make_unique<OUTLINE_GLYPH>( poly );
|
||||
aGlyphs->push_back( std::move( overbarGlyph ) );
|
||||
}
|
||||
}
|
||||
|
||||
hb_buffer_destroy( buf );
|
||||
hb_font_destroy( referencedFont );
|
||||
|
||||
@@ -575,7 +492,7 @@ void OUTLINE_FONT::RenderToOpenGLCanvas( KIGFX::OPENGL_GAL& aGal, const wxString
|
||||
unsigned int glyphCount;
|
||||
hb_glyph_info_t* glyphInfo = hb_buffer_get_glyph_infos( buf, &glyphCount );
|
||||
hb_glyph_position_t* glyphPos = hb_buffer_get_glyph_positions( buf, &glyphCount );
|
||||
|
||||
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
hb_font_t* referencedFont = hb_ft_font_create_referenced( m_face );
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2013 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
* Copyright (C) 2016-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2016-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* Stroke font class
|
||||
*
|
||||
@@ -44,7 +44,7 @@ using namespace KIFONT;
|
||||
|
||||
|
||||
///< Factor that determines relative vertical position of the overbar.
|
||||
static constexpr double OVERBAR_POSITION_FACTOR = 1.40;
|
||||
static constexpr double OVERBAR_POSITION_FACTOR = 1.23;
|
||||
|
||||
///< Factor that determines relative vertical position of the underline.
|
||||
static constexpr double UNDERLINE_POSITION_FACTOR = -0.16;
|
||||
@@ -128,7 +128,6 @@ void STROKE_FONT::loadNewStrokeFont( const char* const aNewStrokeFont[], int aNe
|
||||
|
||||
while( aNewStrokeFont[j][i] )
|
||||
{
|
||||
|
||||
if( aNewStrokeFont[j][i] == ' ' && aNewStrokeFont[j][i+1] == 'R' )
|
||||
strokes++;
|
||||
|
||||
@@ -228,9 +227,9 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
|
||||
{
|
||||
constexpr int TAB_WIDTH = 4;
|
||||
constexpr double INTER_CHAR = 0.2;
|
||||
constexpr double SUPER_SUB_SIZE_MULTIPLIER = 0.7;
|
||||
constexpr double SUPER_HEIGHT_OFFSET = 0.5;
|
||||
constexpr double SUB_HEIGHT_OFFSET = 0.3;
|
||||
constexpr double SUPER_SUB_SIZE_MULTIPLIER = 0.8;
|
||||
constexpr double SUPER_HEIGHT_OFFSET = 0.35;
|
||||
constexpr double SUB_HEIGHT_OFFSET = 0.15;
|
||||
|
||||
VECTOR2I cursor( aPosition );
|
||||
VECTOR2D glyphSize( aSize );
|
||||
@@ -295,71 +294,16 @@ VECTOR2I STROKE_FONT::GetTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_ptr
|
||||
|
||||
glyphExtents *= glyphSize;
|
||||
|
||||
if( tilt > 0.0 )
|
||||
glyphExtents.x -= glyphExtents.y * tilt;
|
||||
|
||||
cursor.x += KiROUND( glyphExtents.x );
|
||||
}
|
||||
|
||||
++char_count;
|
||||
}
|
||||
|
||||
VECTOR2D barOffset( 0.0, 0.0 );
|
||||
|
||||
// Shorten the bar a little so its rounded ends don't make it over-long
|
||||
double barTrim = glyphSize.x * 0.1;
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::OVERBAR )
|
||||
{
|
||||
barOffset.y = ComputeOverbarVerticalPosition( glyphSize.y );
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::ITALIC )
|
||||
barOffset.x = barOffset.y * ITALIC_TILT;
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barOffset.x + barTrim, cursor.y - barOffset.y );
|
||||
VECTOR2D barEnd( cursor.x + barOffset.x - barTrim, cursor.y - barOffset.y );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH overbarGlyph;
|
||||
|
||||
overbarGlyph.AddPoint( barStart );
|
||||
overbarGlyph.AddPoint( barEnd );
|
||||
overbarGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( overbarGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false,
|
||||
aAngle, aMirror, aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::UNDERLINE )
|
||||
{
|
||||
barOffset.y = ComputeUnderlineVerticalPosition( glyphSize.y );
|
||||
|
||||
if( aTextStyle & TEXT_STYLE::ITALIC )
|
||||
barOffset.x = barOffset.y * ITALIC_TILT;
|
||||
|
||||
VECTOR2D barStart( aPosition.x + barOffset.x + barTrim, cursor.y - barOffset.y );
|
||||
VECTOR2D barEnd( cursor.x + barOffset.x - barTrim, cursor.y - barOffset.y );
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
STROKE_GLYPH underlineGlyph;
|
||||
|
||||
underlineGlyph.AddPoint( barStart );
|
||||
underlineGlyph.AddPoint( barEnd );
|
||||
underlineGlyph.Finalize();
|
||||
|
||||
aGlyphs->push_back( underlineGlyph.Transform( { 1.0, 1.0 }, { 0, 0 }, false,
|
||||
aAngle, aMirror, aOrigin ) );
|
||||
}
|
||||
}
|
||||
|
||||
if( aBBox )
|
||||
{
|
||||
aBBox->SetOrigin( aPosition );
|
||||
aBBox->SetEnd( cursor.x + barOffset.x - KiROUND( glyphSize.x * INTER_CHAR ),
|
||||
cursor.y + std::max( glyphSize.y, barOffset.y * OVERBAR_POSITION_FACTOR ) );
|
||||
aBBox->SetEnd( cursor.x - KiROUND( glyphSize.x * INTER_CHAR ), cursor.y + glyphSize.y );
|
||||
aBBox->Normalize();
|
||||
}
|
||||
|
||||
|
||||
@@ -86,12 +86,11 @@ void FOOTPRINT_FILTER_IT::increment()
|
||||
candidate.GetLibNickname(),
|
||||
candidate.GetFootprintName(),
|
||||
candidate.GetSearchText() );
|
||||
int matches, position;
|
||||
bool exclude = false;
|
||||
bool exclude = false;
|
||||
|
||||
for( std::unique_ptr<EDA_COMBINED_MATCHER>& matcher : m_filter->m_pattern_filters )
|
||||
{
|
||||
if( !matcher->Find( searchStr.Lower(), matches, position ) )
|
||||
if( !matcher->Find( searchStr.Lower() ) )
|
||||
{
|
||||
exclude = true;
|
||||
break;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||
* Copyright (C) 2012-2021 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2012-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2018 CERN
|
||||
*
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
@@ -537,17 +537,27 @@ void CAIRO_GAL_BASE::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
|
||||
{
|
||||
for( int col = 0; col < w; col++ )
|
||||
{
|
||||
// Build the RGB24 pixel:
|
||||
uint32_t pixel = bm_pix_buffer.GetRed( col, row ) << 16;
|
||||
pixel += bm_pix_buffer.GetGreen( col, row ) << 8;
|
||||
pixel += bm_pix_buffer.GetBlue( col, row );
|
||||
unsigned char r = bm_pix_buffer.GetRed( col, row );
|
||||
unsigned char g = bm_pix_buffer.GetGreen( col, row );
|
||||
unsigned char b = bm_pix_buffer.GetBlue( col, row );
|
||||
unsigned char a = wxALPHA_OPAQUE;
|
||||
|
||||
if( bm_pix_buffer.HasAlpha() )
|
||||
pixel += bm_pix_buffer.GetAlpha( col, row ) << 24;
|
||||
else if( bm_pix_buffer.HasMask() && pixel == mask_color )
|
||||
pixel += ( wxALPHA_TRANSPARENT << 24 );
|
||||
else
|
||||
pixel += ( wxALPHA_OPAQUE << 24 );
|
||||
{
|
||||
a = bm_pix_buffer.GetAlpha( col, row );
|
||||
|
||||
// ARGB32 format needs pre-multiplied alpha
|
||||
r = int32_t( r ) * a / 0xFF;
|
||||
g = int32_t( g ) * a / 0xFF;
|
||||
b = int32_t( b ) * a / 0xFF;
|
||||
}
|
||||
else if( bm_pix_buffer.HasMask() && ( r << 16 | g << 8 | b ) == mask_color )
|
||||
{
|
||||
a = wxALPHA_TRANSPARENT;
|
||||
}
|
||||
|
||||
// Build the ARGB24 pixel:
|
||||
uint32_t pixel = a << 24 | r << 16 | g << 8 | b;
|
||||
|
||||
// Write the pixel to the cairo image buffer:
|
||||
uint32_t* pix_ptr = (uint32_t*) pix_buffer;
|
||||
|
||||
@@ -180,7 +180,7 @@ bool COLOR4D::SetFromHexString( const wxString& aColorString )
|
||||
str.Trim( true );
|
||||
str.Trim( false );
|
||||
|
||||
if( str.length() < 7 || str.GetChar( 0 ) != '#' )
|
||||
if( str.length() < 7 || !str.StartsWith( '#' ) )
|
||||
return false;
|
||||
|
||||
unsigned long tmp;
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
|
||||
#include <macros.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <thread_pool.h>
|
||||
|
||||
#include <profile.h>
|
||||
#include <trace_helpers.h>
|
||||
@@ -259,11 +260,17 @@ OPENGL_GAL::OPENGL_GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions, wxWindow* aParent,
|
||||
{
|
||||
m_glMainContext = GL_CONTEXT_MANAGER::Get().CreateCtx( this );
|
||||
|
||||
if( !m_glMainContext )
|
||||
throw std::runtime_error( "Could not create the main OpenGL context" );
|
||||
|
||||
m_glPrivContext = m_glMainContext;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_glPrivContext = GL_CONTEXT_MANAGER::Get().CreateCtx( this, m_glMainContext );
|
||||
|
||||
if( !m_glPrivContext )
|
||||
throw std::runtime_error( "Could not create a private OpenGL context" );
|
||||
}
|
||||
|
||||
m_shader = new SHADER();
|
||||
@@ -1418,21 +1425,23 @@ void OPENGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
|
||||
glActiveTexture( GL_TEXTURE0 );
|
||||
glBindTexture( GL_TEXTURE_2D, texture_id );
|
||||
|
||||
float texStartX = aBitmap.IsMirrored() ? 1.0 : 0.0;
|
||||
float texEndX = aBitmap.IsMirrored() ? 0.0 : 1.0;
|
||||
float texStartX = aBitmap.IsMirroredX() ? 1.0 : 0.0;
|
||||
float texEndX = aBitmap.IsMirroredX() ? 0.0 : 1.0;
|
||||
float texStartY = aBitmap.IsMirroredY() ? 1.0 : 0.0;
|
||||
float texEndY = aBitmap.IsMirroredY() ? 0.0 : 1.0;
|
||||
|
||||
glBegin( GL_QUADS );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texStartX, 0.0 );
|
||||
glTexCoord2f( texStartX, texStartY );
|
||||
glVertex3f( v0.x, v0.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texEndX, 0.0 );
|
||||
glTexCoord2f( texEndX, texStartY);
|
||||
glVertex3f( v1.x, v0.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texEndX, 1.0 );
|
||||
glTexCoord2f( texEndX, texEndY);
|
||||
glVertex3f( v1.x, v1.y, m_layerDepth );
|
||||
glColor4f( 1.0, 1.0, 1.0, alpha );
|
||||
glTexCoord2f( texStartX, 1.0 );
|
||||
glTexCoord2f( texStartX, texEndY);
|
||||
glVertex3f( v0.x, v1.y, m_layerDepth );
|
||||
glEnd();
|
||||
|
||||
@@ -2248,13 +2257,13 @@ void OPENGL_GAL::drawSegmentChain( const std::function<VECTOR2D( int )>& aPointG
|
||||
auto start = aPointGetter( i - 1 );
|
||||
auto end = aPointGetter( i );
|
||||
|
||||
VECTOR2D startEndVector = start - end;
|
||||
VECTOR2D startEndVector = end - start;
|
||||
double lineLength = startEndVector.EuclideanNorm();
|
||||
|
||||
float startx = start.x;
|
||||
float starty = end.y;
|
||||
float starty = start.y;
|
||||
float endx = start.x + lineLength;
|
||||
float endy = end.y + lineLength;
|
||||
float endy = start.y + lineLength;
|
||||
|
||||
// Be careful about floating point rounding. As we draw segments in larger and larger
|
||||
// coordinates, the shader (which uses floats) will lose precision and stop drawing small
|
||||
@@ -2530,16 +2539,8 @@ void OPENGL_GAL::init()
|
||||
#endif /* wxCHECK_VERSION( 3, 0, 3 ) */
|
||||
|
||||
// Check correct initialization from the constructor
|
||||
if( !m_glMainContext )
|
||||
throw std::runtime_error( "Could not create the main OpenGL context" );
|
||||
|
||||
if( !m_glPrivContext )
|
||||
throw std::runtime_error( "Could not create a private OpenGL context" );
|
||||
|
||||
if( m_tesselator == nullptr )
|
||||
throw std::runtime_error( "Could not create the m_tesselator" );
|
||||
// End initialization checks
|
||||
|
||||
throw std::runtime_error( "Could not create the tesselator" );
|
||||
GLenum err = glewInit();
|
||||
|
||||
if( GLEW_OK != err )
|
||||
@@ -2779,15 +2780,31 @@ void OPENGL_GAL::DrawGlyphs( const std::vector<std::unique_ptr<KIFONT::GLYPH>>&
|
||||
// Optimized path for stroke fonts that pre-reserves glyph triangles.
|
||||
int triangleCount = 0;
|
||||
|
||||
if( aGlyphs.size() > 0 )
|
||||
{
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
tp.push_loop( aGlyphs.size(),
|
||||
[&]( const int a, const int b)
|
||||
{
|
||||
for( int ii = a; ii < b; ++ii )
|
||||
{
|
||||
auto glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( aGlyphs.at( ii ).get() );
|
||||
|
||||
// Only call CacheTriangulation() if it has never been done before.
|
||||
// Otherwise we'll hash the triangulation to see if it has been edited,
|
||||
// and all our glpyh editing ops update the triangulation anyway.
|
||||
if( glyph->TriangulatedPolyCount() == 0 )
|
||||
glyph->CacheTriangulation( false );
|
||||
}
|
||||
} );
|
||||
tp.wait_for_tasks();
|
||||
}
|
||||
|
||||
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aGlyphs )
|
||||
{
|
||||
const auto& outlineGlyph = static_cast<const KIFONT::OUTLINE_GLYPH&>( *glyph );
|
||||
|
||||
// Only call CacheTriangulation if it has never been done before. Otherwise we'll hash
|
||||
// the triangulation to see if it has been edited, and glyphs after creation are read-only.
|
||||
if( outlineGlyph.TriangulatedPolyCount() == 0 )
|
||||
const_cast<KIFONT::OUTLINE_GLYPH&>( outlineGlyph ).CacheTriangulation( false );
|
||||
|
||||
for( unsigned int i = 0; i < outlineGlyph.TriangulatedPolyCount(); i++ )
|
||||
{
|
||||
const SHAPE_POLY_SET::TRIANGULATED_POLYGON* polygon =
|
||||
|
||||
@@ -87,7 +87,7 @@ void GL_CONTEXT_MANAGER::DeleteAll()
|
||||
|
||||
void GL_CONTEXT_MANAGER::LockCtx( wxGLContext* aContext, wxGLCanvas* aCanvas )
|
||||
{
|
||||
wxCHECK( aCanvas || m_glContexts.count( aContext ) > 0, /* void */ );
|
||||
wxCHECK( aContext && m_glContexts.count( aContext ) > 0, /* void */ );
|
||||
|
||||
m_glCtxMutex.lock();
|
||||
wxGLCanvas* canvas = aCanvas ? aCanvas : m_glContexts.at( aContext );
|
||||
@@ -106,7 +106,7 @@ void GL_CONTEXT_MANAGER::LockCtx( wxGLContext* aContext, wxGLCanvas* aCanvas )
|
||||
|
||||
void GL_CONTEXT_MANAGER::UnlockCtx( wxGLContext* aContext )
|
||||
{
|
||||
wxCHECK( m_glContexts.count( aContext ) > 0, /* void */ );
|
||||
wxCHECK( aContext && m_glContexts.count( aContext ) > 0, /* void */ );
|
||||
|
||||
if( m_glCtx == aContext )
|
||||
{
|
||||
|
||||
@@ -94,7 +94,10 @@ void GRSetColorPen( wxDC* DC, const COLOR4D& Color, int width, wxPenStyle style
|
||||
// wxWidgets will enforce a minimum pen width when printing, so we have to make the pen
|
||||
// transparent when we don't want the object stroked.
|
||||
if( width == 0 )
|
||||
{
|
||||
color = COLOR4D::UNSPECIFIED;
|
||||
style = wxPENSTYLE_TRANSPARENT;
|
||||
}
|
||||
|
||||
const wxPen& curr_pen = DC->GetPen();
|
||||
|
||||
|
||||
+21
-8
@@ -418,9 +418,16 @@ void GRID_TRICKS::onCharHook( wxKeyEvent& ev )
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
if( ev.GetKeyCode() == WXK_RETURN && m_grid->GetGridCursorRow() == m_grid->GetNumberRows() - 1 )
|
||||
if( ( ev.GetKeyCode() == WXK_RETURN || ev.GetKeyCode() == WXK_NUMPAD_ENTER )
|
||||
&& ev.GetModifiers() == wxMOD_NONE
|
||||
&& m_grid->GetGridCursorRow() == m_grid->GetNumberRows() - 1 )
|
||||
{
|
||||
if( m_grid->CommitPendingChanges() )
|
||||
if( m_grid->IsCellEditControlShown() )
|
||||
{
|
||||
if( m_grid->CommitPendingChanges() )
|
||||
handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
m_addHandler( dummy );
|
||||
@@ -449,6 +456,14 @@ void GRID_TRICKS::onCharHook( wxKeyEvent& ev )
|
||||
m_grid->ForceRefresh();
|
||||
}
|
||||
}
|
||||
else if( ev.GetKeyCode() == WXK_ESCAPE )
|
||||
{
|
||||
if( m_grid->IsCellEditControlShown() )
|
||||
{
|
||||
m_grid->CancelPendingChanges();
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !handled )
|
||||
ev.Skip( true );
|
||||
@@ -711,18 +726,16 @@ void GRID_TRICKS::paste_text( const wxString& cb_text )
|
||||
wxStringTokenizer cols( rowTxt, COL_SEP, wxTOKEN_RET_EMPTY );
|
||||
|
||||
if( !is_selection )
|
||||
{
|
||||
end_col = cur_col + cols.CountTokens();
|
||||
|
||||
if( end_col > tbl->GetNumberCols() )
|
||||
end_col = tbl->GetNumberCols();
|
||||
}
|
||||
|
||||
for( int col = start_col; col < end_col; ++col )
|
||||
for( int col = start_col; col < end_col && col < tbl->GetNumberCols(); ++col )
|
||||
{
|
||||
// Skip hidden columns
|
||||
if( !m_grid->IsColShown( col ) )
|
||||
{
|
||||
end_col++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If number of selected cols is larger than the count of cols on the clipboard,
|
||||
// paste again and again until the end of the selection is reached.
|
||||
|
||||
@@ -39,6 +39,8 @@ public:
|
||||
m_includeNetlistAttributes( true ),
|
||||
m_useX2Format( true ),
|
||||
m_disableApertureMacros( false ),
|
||||
m_useAuxOrigin( false ),
|
||||
m_useProtelFileExtension( true ),
|
||||
m_precision( 5 ),
|
||||
m_printMaskLayer()
|
||||
{
|
||||
@@ -59,6 +61,8 @@ public:
|
||||
bool m_includeNetlistAttributes;
|
||||
bool m_useX2Format;
|
||||
bool m_disableApertureMacros;
|
||||
bool m_useAuxOrigin;
|
||||
bool m_useProtelFileExtension;
|
||||
|
||||
int m_precision;
|
||||
|
||||
@@ -66,4 +70,4 @@ public:
|
||||
LSET m_printMaskLayer;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -33,7 +33,9 @@ public:
|
||||
m_filename(),
|
||||
m_outputFile(),
|
||||
m_colorTheme(),
|
||||
m_mirror( false ),
|
||||
m_blackAndWhite( false ),
|
||||
m_negative( false ),
|
||||
m_plotFootprintValues( true ),
|
||||
m_plotRefDes( true ),
|
||||
m_plotBorderTitleBlocks( false ),
|
||||
@@ -45,7 +47,9 @@ public:
|
||||
wxString m_outputFile;
|
||||
wxString m_colorTheme;
|
||||
|
||||
bool m_mirror;
|
||||
bool m_blackAndWhite;
|
||||
bool m_negative;
|
||||
bool m_plotFootprintValues;
|
||||
bool m_plotRefDes;
|
||||
bool m_plotBorderTitleBlocks;
|
||||
@@ -53,4 +57,4 @@ public:
|
||||
LSET m_printMaskLayer;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,8 @@ class JOB_EXPORT_PCB_SVG : public JOB
|
||||
public:
|
||||
JOB_EXPORT_PCB_SVG( bool aIsCli ) :
|
||||
JOB( "svg", aIsCli ), m_filename(), m_outputFile(), m_colorTheme(), m_mirror( false ),
|
||||
m_blackAndWhite( false ), m_plotDrawingSheet( true ), m_pageSizeMode( 0 ), m_printMaskLayer()
|
||||
m_blackAndWhite( false ), m_negative( false ), m_plotDrawingSheet( true ),
|
||||
m_pageSizeMode( 0 ), m_printMaskLayer()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -40,6 +41,7 @@ public:
|
||||
|
||||
bool m_mirror;
|
||||
bool m_blackAndWhite;
|
||||
bool m_negative;
|
||||
|
||||
bool m_plotDrawingSheet;
|
||||
int m_pageSizeMode;
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef JOB_EXPORT_SCH_PDF_H
|
||||
#define JOB_EXPORT_SCH_PDF_H
|
||||
|
||||
#include <wx/string.h>
|
||||
#include "job.h"
|
||||
|
||||
class JOB_EXPORT_SCH_PDF : public JOB
|
||||
{
|
||||
public:
|
||||
JOB_EXPORT_SCH_PDF( bool aIsCli ) :
|
||||
JOB( "pdf", aIsCli ),
|
||||
m_filename(),
|
||||
m_outputFile(),
|
||||
m_blackAndWhite( false ),
|
||||
m_useBackgroundColor( false ),
|
||||
m_plotDrawingSheet( false )
|
||||
{
|
||||
}
|
||||
|
||||
wxString m_filename;
|
||||
wxString m_outputFile;
|
||||
wxString m_colorTheme;
|
||||
|
||||
bool m_blackAndWhite;
|
||||
bool m_useBackgroundColor;
|
||||
bool m_plotDrawingSheet;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -18,21 +18,24 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef COMMAND_EXPORT_SCH_SVG_H
|
||||
#define COMMAND_EXPORT_SCH_SVG_H
|
||||
#ifndef JOB_EXPORT_SCH_PLOT_H
|
||||
#define JOB_EXPORT_SCH_PLOT_H
|
||||
|
||||
#include "command_export_pcb_base.h"
|
||||
#include <wx/string.h>
|
||||
#include <plotters/plotter.h>
|
||||
#include "job.h"
|
||||
|
||||
namespace CLI
|
||||
{
|
||||
class EXPORT_SCH_SVG_COMMAND : public EXPORT_PCB_BASE_COMMAND
|
||||
class JOB_EXPORT_SCH_PLOT : public JOB
|
||||
{
|
||||
public:
|
||||
EXPORT_SCH_SVG_COMMAND();
|
||||
JOB_EXPORT_SCH_PLOT( bool aIsCli, PLOT_FORMAT aPlotFormat, wxString aFilename ) :
|
||||
JOB( "plot", aIsCli ), m_plotFormat( aPlotFormat ), m_filename( aFilename )
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
int doPerform( KIWAY& aKiway ) override;
|
||||
PLOT_FORMAT m_plotFormat;
|
||||
wxString m_filename;
|
||||
SCH_PLOT_SETTINGS settings;
|
||||
};
|
||||
} // namespace CLI
|
||||
|
||||
#endif
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
|
||||
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef JOB_EXPORT_SCH_SVG_H
|
||||
#define JOB_EXPORT_SCH_SVG_H
|
||||
|
||||
#include <wx/string.h>
|
||||
#include "job.h"
|
||||
|
||||
class JOB_EXPORT_SCH_SVG : public JOB
|
||||
{
|
||||
public:
|
||||
JOB_EXPORT_SCH_SVG( bool aIsCli ) :
|
||||
JOB( "svg", aIsCli ),
|
||||
m_filename(),
|
||||
m_outputDirectory(),
|
||||
m_blackAndWhite( false ),
|
||||
m_useBackgroundColor( false ),
|
||||
m_plotDrawingSheet( false )
|
||||
{
|
||||
}
|
||||
|
||||
wxString m_filename;
|
||||
wxString m_outputDirectory;
|
||||
wxString m_colorTheme;
|
||||
|
||||
bool m_blackAndWhite;
|
||||
bool m_useBackgroundColor;
|
||||
bool m_plotDrawingSheet;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -27,109 +27,21 @@
|
||||
// conflicts for some defines, at least on Windows
|
||||
#include <kicad_curl/kicad_curl.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <ki_exception.h> // THROW_IO_ERROR
|
||||
|
||||
|
||||
|
||||
// These are even more private than class members, and since there is only
|
||||
// one instance of KICAD_CURL ever, these statics are hidden here to simplify the
|
||||
// client (API) header file.
|
||||
static volatile bool s_initialized;
|
||||
|
||||
static std::mutex s_lock; // for s_initialized
|
||||
|
||||
/// At process termination, using atexit() keeps the CURL stuff out of the
|
||||
/// singletops and PGM_BASE.
|
||||
static void at_terminate()
|
||||
{
|
||||
KICAD_CURL::Cleanup();
|
||||
}
|
||||
|
||||
|
||||
void KICAD_CURL::Init()
|
||||
{
|
||||
// We test s_initialized twice in an effort to avoid
|
||||
// unnecessarily locking s_lock. This understands that the common case
|
||||
// will not need to lock.
|
||||
if( !s_initialized )
|
||||
if( curl_global_init( CURL_GLOBAL_ALL ) != CURLE_OK )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( s_lock );
|
||||
|
||||
if( !s_initialized )
|
||||
{
|
||||
if( curl_global_init( CURL_GLOBAL_ALL ) != CURLE_OK )
|
||||
{
|
||||
THROW_IO_ERROR( "curl_global_init() failed." );
|
||||
}
|
||||
|
||||
s_initialized = true;
|
||||
}
|
||||
THROW_IO_ERROR( "curl_global_init() failed." );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KICAD_CURL::Cleanup()
|
||||
{
|
||||
/*
|
||||
|
||||
Calling lock_guard() from a static destructor will typically be bad, since the
|
||||
s_lock may already have been statically destroyed itself leading to a boost
|
||||
exception. (Remember C++ does not provide certain sequencing of static
|
||||
destructor invocation.)
|
||||
|
||||
To prevent this we test s_initialized twice, which ensures that the lock_guard
|
||||
is only instantiated on the first call, which should be from
|
||||
PGM_BASE::destroy() which is first called earlier than static destruction.
|
||||
Then when called again from the actual PGM_BASE::~PGM_BASE() function,
|
||||
lock_guard will not be instantiated because s_initialized will be false.
|
||||
|
||||
*/
|
||||
|
||||
if( s_initialized )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( s_lock );
|
||||
|
||||
if( s_initialized )
|
||||
{
|
||||
curl_global_cleanup();
|
||||
|
||||
atexit( &at_terminate );
|
||||
|
||||
s_initialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string KICAD_CURL::GetSimpleVersion()
|
||||
{
|
||||
if( !s_initialized )
|
||||
Init();
|
||||
|
||||
curl_version_info_data* info = curl_version_info( CURLVERSION_NOW );
|
||||
|
||||
std::string res;
|
||||
|
||||
if( info->version )
|
||||
{
|
||||
res += "libcurl version: " + std::string( info->version );
|
||||
}
|
||||
|
||||
res += " (";
|
||||
|
||||
if( info->features & CURL_VERSION_SSL )
|
||||
{
|
||||
res += "with SSL - ";
|
||||
res += std::string( info->ssl_version );
|
||||
}
|
||||
else
|
||||
{
|
||||
res += "without SSL";
|
||||
}
|
||||
res += ")";
|
||||
|
||||
return res;
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#include <kiplatform/environment.h>
|
||||
#include <pgm_base.h>
|
||||
|
||||
#include <kiplatform/policy.h>
|
||||
#include <policy_keys.h>
|
||||
|
||||
struct CURL_PROGRESS
|
||||
{
|
||||
@@ -112,12 +114,6 @@ static int progressinfo( void* aProgress, double aDLtotal, double aDLnow, double
|
||||
KICAD_CURL_EASY::KICAD_CURL_EASY() :
|
||||
m_headers( nullptr )
|
||||
{
|
||||
// Call KICAD_CURL::Init() from in here every time, but only the first time
|
||||
// will incur any overhead. This strategy ensures that libcurl is never loaded
|
||||
// unless it is needed.
|
||||
|
||||
KICAD_CURL::Init();
|
||||
|
||||
m_CURL = curl_easy_init();
|
||||
|
||||
if( !m_CURL )
|
||||
@@ -133,11 +129,29 @@ KICAD_CURL_EASY::KICAD_CURL_EASY() :
|
||||
curl_easy_setopt( m_CURL, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS );
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN32
|
||||
// We need this to use the Windows Certificate store
|
||||
curl_easy_setopt( m_CURL, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA );
|
||||
long sslOpts = CURLSSLOPT_NATIVE_CA;
|
||||
|
||||
POLICY_CURL_SSL_REVOKE policyState = KIPLATFORM::POLICY::GetPolicyEnum<POLICY_CURL_SSL_REVOKE>( POLICY_KEY_REQUESTS_CURL_REVOKE );
|
||||
if( policyState == POLICY_CURL_SSL_REVOKE::BEST_EFFORT )
|
||||
{
|
||||
sslOpts |= CURLSSLOPT_REVOKE_BEST_EFFORT;
|
||||
}
|
||||
else if( policyState == POLICY_CURL_SSL_REVOKE::NONE )
|
||||
{
|
||||
sslOpts |= CURLSSLOPT_NO_REVOKE;
|
||||
}
|
||||
|
||||
curl_easy_setopt( m_CURL, CURLOPT_SSL_OPTIONS, sslOpts );
|
||||
#endif
|
||||
|
||||
if( wxGetEnv( wxT( "KICAD_CURL_VERBOSE" ), nullptr ) )
|
||||
{
|
||||
// note: curl verbose will end up in stderr
|
||||
curl_easy_setopt( m_CURL, CURLOPT_VERBOSE, 1L );
|
||||
}
|
||||
|
||||
wxPlatformInfo platformInfo;
|
||||
wxString application( Pgm().App().GetAppName() );
|
||||
wxString version( GetBuildVersion() );
|
||||
|
||||
+71
-19
@@ -45,6 +45,10 @@
|
||||
#include <wx/utils.h>
|
||||
#include <confirm.h>
|
||||
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
#include <sentry.h>
|
||||
#endif
|
||||
|
||||
KIFACE* KIWAY::m_kiface[KIWAY_FACE_COUNT];
|
||||
int KIWAY::m_kiface_version[KIWAY_FACE_COUNT];
|
||||
|
||||
@@ -212,8 +216,6 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
|
||||
if( m_kiface[aFaceId] )
|
||||
return m_kiface[aFaceId];
|
||||
|
||||
wxString msg;
|
||||
|
||||
// DSO with KIFACE has not been loaded yet, does caller want to load it?
|
||||
if( doLoad )
|
||||
{
|
||||
@@ -236,6 +238,7 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
|
||||
bool codeSignOk = KIPLATFORM::ENV::VerifyFileSignature( dname );
|
||||
if( !codeSignOk )
|
||||
{
|
||||
wxString msg;
|
||||
msg.Printf( _( "Failed to verify kiface library '%s' signature." ), dname );
|
||||
THROW_IO_ERROR( msg );
|
||||
}
|
||||
@@ -257,6 +260,14 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
|
||||
|
||||
setlocale( lc_new_type, user_locale.c_str() );
|
||||
|
||||
wxString msg = wxString::Format( "Loading kiface %d", aFaceId );
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
sentry_value_t crumb = sentry_value_new_breadcrumb( "navigation", msg.utf8_str() );
|
||||
sentry_value_set_by_key( crumb, "category", sentry_value_new_string( "kiway.kiface" ) );
|
||||
sentry_value_set_by_key( crumb, "level", sentry_value_new_string( "info" ) );
|
||||
sentry_add_breadcrumb( crumb );
|
||||
#endif
|
||||
|
||||
if( !success )
|
||||
{
|
||||
// Failure: error reporting UI was done via wxLogSysError().
|
||||
@@ -287,15 +298,38 @@ KIFACE* KIWAY::KiFACE( FACE_T aFaceId, bool doLoad )
|
||||
wxASSERT_MSG( kiface,
|
||||
wxT( "attempted DSO has a bug, failed to return a KIFACE*" ) );
|
||||
|
||||
wxDllType dsoHandle = dso.Detach();
|
||||
|
||||
bool startSuccess = false;
|
||||
|
||||
// Give the DSO a single chance to do its "process level" initialization.
|
||||
// "Process level" specifically means stay away from any projects in there.
|
||||
if( kiface->OnKifaceStart( m_program, m_ctl ) )
|
||||
{
|
||||
// Tell dso's wxDynamicLibrary destructor not to Unload() the program image.
|
||||
ignore_unused( dso.Detach() );
|
||||
|
||||
try
|
||||
{
|
||||
startSuccess = kiface->OnKifaceStart( m_program, m_ctl );
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// OnKiFaceStart may generate an exception
|
||||
// Before we continue and ultimately unload our module to retry we need
|
||||
// to process the exception before we delete the free the memory space the exception resides in
|
||||
Pgm().HandleException( std::current_exception() );
|
||||
}
|
||||
|
||||
if( startSuccess )
|
||||
{
|
||||
return m_kiface[aFaceId] = kiface;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Usually means cancelled initial global library setup
|
||||
// But it could have been an exception/failure
|
||||
// Let the module go out of scope to unload
|
||||
dso.Attach( dsoHandle );
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// In any of the failure cases above, dso.Unload() should be called here
|
||||
@@ -414,6 +448,14 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow
|
||||
{
|
||||
try
|
||||
{
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
wxString msg = wxString::Format( "Creating window type %d", aFrameType );
|
||||
sentry_value_t crumb = sentry_value_new_breadcrumb( "navigation", msg.utf8_str() );
|
||||
sentry_value_set_by_key( crumb, "category", sentry_value_new_string( "kiway.player" ) );
|
||||
sentry_value_set_by_key( crumb, "level", sentry_value_new_string( "info" ) );
|
||||
sentry_add_breadcrumb( crumb );
|
||||
#endif
|
||||
|
||||
FACE_T face_type = KifaceType( aFrameType );
|
||||
KIFACE* kiface = KiFACE( face_type );
|
||||
|
||||
@@ -429,18 +471,9 @@ KIWAY_PLAYER* KIWAY::Player( FRAME_T aFrameType, bool doCreate, wxTopLevelWindow
|
||||
m_playerFrameId[aFrameType].store( frame->GetId() );
|
||||
return frame;
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
wxLogError( ioe.What() );
|
||||
wxLogError( _( "Error loading editor." ) );
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
wxLogError( e.what() );
|
||||
wxLogError( _( "Error loading editor." ) );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
Pgm().HandleException( std::current_exception() );
|
||||
wxLogError( _( "Error loading editor." ) );
|
||||
}
|
||||
}
|
||||
@@ -462,11 +495,19 @@ bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce )
|
||||
return false;
|
||||
}
|
||||
|
||||
KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
|
||||
KIWAY_PLAYER* frame = GetPlayerFrame( aFrameType );
|
||||
|
||||
if( frame == nullptr ) // Already closed
|
||||
return true;
|
||||
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
wxString msg = wxString::Format( "Closing window type %d", aFrameType );
|
||||
sentry_value_t crumb = sentry_value_new_breadcrumb( "navigation", msg.utf8_str() );
|
||||
sentry_value_set_by_key( crumb, "category", sentry_value_new_string( "kiway.playerclose" ) );
|
||||
sentry_value_set_by_key( crumb, "level", sentry_value_new_string( "info" ) );
|
||||
sentry_add_breadcrumb( crumb );
|
||||
#endif
|
||||
|
||||
if( frame->NonUserClose( doForce ) )
|
||||
{
|
||||
m_playerFrameId[aFrameType] = wxID_NONE;
|
||||
@@ -482,14 +523,18 @@ bool KIWAY::PlayersClose( bool doForce )
|
||||
bool ret = true;
|
||||
|
||||
for( unsigned i=0; i < KIWAY_PLAYER_COUNT; ++i )
|
||||
{
|
||||
ret = ret && PlayerClose( FRAME_T( i ), doForce );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void KIWAY::PlayerDidClose( FRAME_T aFrameType )
|
||||
{
|
||||
m_playerFrameId[aFrameType] = wxID_NONE;
|
||||
}
|
||||
|
||||
|
||||
void KIWAY::ExpressMail( FRAME_T aDestination, MAIL_T aCommand, std::string& aPayload,
|
||||
wxWindow* aSource )
|
||||
{
|
||||
@@ -599,6 +644,13 @@ void KIWAY::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextVarsChanged )
|
||||
|
||||
void KIWAY::ProjectChanged()
|
||||
{
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
sentry_value_t crumb = sentry_value_new_breadcrumb( "navigation", "Changing project" );
|
||||
sentry_value_set_by_key( crumb, "category", sentry_value_new_string( "kiway.projectchanged" ) );
|
||||
sentry_value_set_by_key( crumb, "level", sentry_value_new_string( "info" ) );
|
||||
sentry_add_breadcrumb( crumb );
|
||||
#endif
|
||||
|
||||
if( m_ctl & KFCTL_CPP_PROJECT_SUITE )
|
||||
{
|
||||
// A dynamic_cast could be better, but creates link issues
|
||||
|
||||
@@ -55,6 +55,12 @@ KIWAY_PLAYER::KIWAY_PLAYER( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrameType
|
||||
}
|
||||
|
||||
|
||||
// Don't use this one; it's only for wxFormBuilder, and it must be augmented with code to
|
||||
// correct the m_ident and set the m_kiway early in derived constructor.
|
||||
//
|
||||
// Because of its inherent danger, it's also declared private and requires friend-class
|
||||
// declarations for each usage.
|
||||
//
|
||||
KIWAY_PLAYER::KIWAY_PLAYER( wxWindow* aParent, wxWindowID aId, const wxString& aTitle,
|
||||
const wxPoint& aPos, const wxSize& aSize, long aStyle,
|
||||
const wxString& aWdoName ) :
|
||||
@@ -169,6 +175,8 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow
|
||||
|
||||
bool KIWAY_PLAYER::Destroy()
|
||||
{
|
||||
Kiway().PlayerDidClose( GetFrameType() );
|
||||
|
||||
return EDA_BASE_FRAME::Destroy();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*lib_tree_model
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
|
||||
* Copyright (C) 2014-2019 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -24,14 +24,12 @@
|
||||
#include <algorithm>
|
||||
#include <eda_pattern_match.h>
|
||||
#include <lib_tree_item.h>
|
||||
#include <utility>
|
||||
#include <pgm_base.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
// Each node gets this lowest score initially, without any matches applied.
|
||||
// Matches will then increase this score depending on match quality. This way,
|
||||
// an empty search string will result in all components being displayed as they
|
||||
// have the minimum score. However, in that case, we avoid expanding all the
|
||||
// Each node gets this lowest score initially, without any matches applied. Matches will then
|
||||
// increase this score. This way, an empty search string will result in all components being
|
||||
// displayed as they have the minimum score. However, in that case, we avoid expanding all the
|
||||
// nodes asd the result is very unspecific.
|
||||
static const unsigned kLowestDefaultScore = 1;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
|
||||
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
|
||||
* Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2014-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -213,17 +213,11 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool a
|
||||
Thaw();
|
||||
}
|
||||
|
||||
LIB_TREE_NODE* bestMatch = ShowResults();
|
||||
const LIB_TREE_NODE* firstMatch = ShowResults();
|
||||
|
||||
if( !bestMatch )
|
||||
bestMatch = ShowPreselect();
|
||||
|
||||
if( !bestMatch )
|
||||
bestMatch = ShowSingleLibrary();
|
||||
|
||||
if( bestMatch )
|
||||
if( firstMatch )
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( bestMatch );
|
||||
wxDataViewItem item = ToItem( firstMatch );
|
||||
m_widget->Select( item );
|
||||
|
||||
// Make sure the *parent* item is visible. The selected item is the
|
||||
@@ -422,6 +416,12 @@ wxDataViewItem LIB_TREE_MODEL_ADAPTER::FindItem( const LIB_ID& aLibId )
|
||||
}
|
||||
|
||||
|
||||
wxDataViewItem LIB_TREE_MODEL_ADAPTER::GetCurrentDataViewItem()
|
||||
{
|
||||
return FindItem( m_preselect_lib_id );
|
||||
}
|
||||
|
||||
|
||||
unsigned int LIB_TREE_MODEL_ADAPTER::GetChildren( const wxDataViewItem& aItem,
|
||||
wxDataViewItemArray& aChildren ) const
|
||||
{
|
||||
@@ -619,93 +619,85 @@ bool LIB_TREE_MODEL_ADAPTER::GetAttr( const wxDataViewItem& aItem,
|
||||
}
|
||||
|
||||
|
||||
void LIB_TREE_MODEL_ADAPTER::Find( LIB_TREE_NODE& aNode,
|
||||
std::function<bool( const LIB_TREE_NODE* )> aFunc,
|
||||
LIB_TREE_NODE** aHighScore )
|
||||
void recursiveDescent( LIB_TREE_NODE& aNode, const std::function<bool( const LIB_TREE_NODE* )>& f )
|
||||
{
|
||||
for( std::unique_ptr<LIB_TREE_NODE>& node: aNode.m_Children )
|
||||
{
|
||||
if( aFunc( &*node ) )
|
||||
{
|
||||
if( !(*aHighScore) || node->m_Score > (*aHighScore)->m_Score )
|
||||
(*aHighScore) = &*node;
|
||||
}
|
||||
if( !f( node.get() ) )
|
||||
break;
|
||||
|
||||
Find( *node, aFunc, aHighScore );
|
||||
recursiveDescent( *node, f );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowResults()
|
||||
const LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowResults()
|
||||
{
|
||||
LIB_TREE_NODE* highScore = nullptr;
|
||||
const LIB_TREE_NODE* firstMatch = nullptr;
|
||||
|
||||
Find( m_tree,
|
||||
[]( LIB_TREE_NODE const* n )
|
||||
{
|
||||
// return leaf nodes with some level of matching
|
||||
return n->m_Type == LIB_TREE_NODE::TYPE::LIBID && n->m_Score > 1;
|
||||
},
|
||||
&highScore );
|
||||
|
||||
if( highScore)
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( highScore );
|
||||
m_widget->ExpandAncestors( item );
|
||||
}
|
||||
|
||||
return highScore;
|
||||
}
|
||||
|
||||
|
||||
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowPreselect()
|
||||
{
|
||||
LIB_TREE_NODE* highScore = nullptr;
|
||||
|
||||
if( !m_preselect_lib_id.IsValid() )
|
||||
return highScore;
|
||||
|
||||
Find( m_tree,
|
||||
[&]( LIB_TREE_NODE const* n )
|
||||
// Expand parents of leaf nodes with some level of matching
|
||||
recursiveDescent( m_tree,
|
||||
[&]( const LIB_TREE_NODE* n )
|
||||
{
|
||||
if( n->m_Type == LIB_TREE_NODE::LIBID && ( n->m_Children.empty() ||
|
||||
!m_preselect_unit ) )
|
||||
return m_preselect_lib_id == n->m_LibId;
|
||||
else if( n->m_Type == LIB_TREE_NODE::UNIT && m_preselect_unit )
|
||||
return m_preselect_lib_id == n->m_Parent->m_LibId &&
|
||||
m_preselect_unit == n->m_Unit;
|
||||
else
|
||||
return false;
|
||||
},
|
||||
&highScore );
|
||||
if( n->m_Type == LIB_TREE_NODE::TYPE::LIBID && n->m_Score > 1 )
|
||||
{
|
||||
if( !firstMatch )
|
||||
firstMatch = n;
|
||||
else if( n->m_Score > firstMatch->m_Score )
|
||||
firstMatch = n;
|
||||
|
||||
if( highScore)
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
}
|
||||
|
||||
return true; // keep going to expand ancestors of all found items
|
||||
} );
|
||||
|
||||
// If no matches, find and show the preselect node
|
||||
if( !firstMatch && m_preselect_lib_id.IsValid() )
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( highScore );
|
||||
m_widget->ExpandAncestors( item );
|
||||
recursiveDescent( m_tree,
|
||||
[&]( const LIB_TREE_NODE* n )
|
||||
{
|
||||
if( n->m_Type == LIB_TREE_NODE::LIBID
|
||||
&& ( n->m_Children.empty() || !m_preselect_unit )
|
||||
&& m_preselect_lib_id == n->m_LibId )
|
||||
{
|
||||
firstMatch = n;
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
return false;
|
||||
}
|
||||
else if( n->m_Type == LIB_TREE_NODE::UNIT
|
||||
&& ( m_preselect_unit && m_preselect_unit == n->m_Unit )
|
||||
&& m_preselect_lib_id == n->m_Parent->m_LibId )
|
||||
{
|
||||
firstMatch = n;
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} );
|
||||
}
|
||||
|
||||
return highScore;
|
||||
// If still no matches expand a single library if there is only one
|
||||
if( !firstMatch )
|
||||
{
|
||||
recursiveDescent( m_tree,
|
||||
[&]( const LIB_TREE_NODE* n )
|
||||
{
|
||||
if( n->m_Type == LIB_TREE_NODE::TYPE::LIBID
|
||||
&& n->m_Parent->m_Parent->m_Children.size() == 1 )
|
||||
{
|
||||
firstMatch = n;
|
||||
m_widget->ExpandAncestors( ToItem( n ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} );
|
||||
}
|
||||
|
||||
return firstMatch;
|
||||
}
|
||||
|
||||
|
||||
LIB_TREE_NODE* LIB_TREE_MODEL_ADAPTER::ShowSingleLibrary()
|
||||
{
|
||||
LIB_TREE_NODE* highScore = nullptr;
|
||||
|
||||
Find( m_tree,
|
||||
[]( LIB_TREE_NODE const* n )
|
||||
{
|
||||
return n->m_Type == LIB_TREE_NODE::TYPE::LIBID &&
|
||||
n->m_Parent->m_Parent->m_Children.size() == 1;
|
||||
},
|
||||
&highScore );
|
||||
|
||||
if( highScore)
|
||||
{
|
||||
wxDataViewItem item = wxDataViewItem( highScore );
|
||||
m_widget->ExpandAncestors( item );
|
||||
}
|
||||
|
||||
return highScore;
|
||||
}
|
||||
|
||||
@@ -646,7 +646,7 @@ void dumpNode( wxString& buf, TREE_NODE* tok, int depth = 0 )
|
||||
|
||||
case TR_OP_FUNC_CALL:
|
||||
buf += "CALL '";
|
||||
buf += *tok->leaf[0]->value.str;
|
||||
buf += formatNode( tok->leaf[0] );
|
||||
buf += "': ";
|
||||
dumpNode( buf, tok->leaf[1], depth + 1 );
|
||||
break;
|
||||
@@ -786,7 +786,7 @@ static std::vector<TREE_NODE*> squashParamList( TREE_NODE* root )
|
||||
std::reverse( args.begin(), args.end() );
|
||||
|
||||
for( size_t i = 0; i < args.size(); i++ )
|
||||
libeval_dbg( 10, "squash arg%d: %s\n", int( i ), *args[i]->value.str );
|
||||
libeval_dbg( 10, "squash arg%d: %s\n", int( i ), formatNode( args[i] ) );
|
||||
|
||||
return args;
|
||||
}
|
||||
@@ -845,7 +845,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
int pos = node->leaf[0]->srcPos;
|
||||
|
||||
if( node->leaf[0]->value.str )
|
||||
pos -= static_cast<int>( node->leaf[0]->value.str->length() );
|
||||
pos -= static_cast<int>( formatNode( node->leaf[0] ).length() );
|
||||
|
||||
reportError( CST_CODEGEN, _( "Unknown parent of property" ), pos );
|
||||
|
||||
@@ -864,8 +864,8 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
// leaf[0]: object
|
||||
// leaf[1]: field
|
||||
|
||||
wxString itemName = *node->leaf[0]->value.str;
|
||||
wxString propName = *node->leaf[1]->value.str;
|
||||
wxString itemName = formatNode( node->leaf[0] );
|
||||
wxString propName = formatNode( node->leaf[1] );
|
||||
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( itemName, propName );
|
||||
|
||||
if( !vref )
|
||||
@@ -895,7 +895,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
// leaf[0]: function name
|
||||
// leaf[1]: parameter
|
||||
|
||||
wxString itemName = *node->leaf[0]->value.str;
|
||||
wxString itemName = formatNode( node->leaf[0] );
|
||||
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( itemName, "" );
|
||||
|
||||
if( !vref )
|
||||
@@ -905,7 +905,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
node->leaf[0]->srcPos - (int) itemName.length() );
|
||||
}
|
||||
|
||||
wxString functionName = *node->leaf[1]->leaf[0]->value.str;
|
||||
wxString functionName = formatNode( node->leaf[1]->leaf[0] );
|
||||
auto func = aCode->CreateFuncCall( functionName );
|
||||
std::vector<TREE_NODE*> params = squashParamList( node->leaf[1]->leaf[1] );
|
||||
|
||||
@@ -924,7 +924,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
for( TREE_NODE* pnode : params )
|
||||
{
|
||||
VALUE* param = aPreflightContext->AllocValue();
|
||||
param->Set( *pnode->value.str );
|
||||
param->Set( formatNode( pnode ) );
|
||||
aPreflightContext->Push( param );
|
||||
}
|
||||
|
||||
@@ -968,8 +968,8 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
// leaf[0]: object
|
||||
// leaf[1]: malformed syntax
|
||||
|
||||
wxString itemName = *node->leaf[0]->value.str;
|
||||
wxString propName = *node->leaf[1]->value.str;
|
||||
wxString itemName = formatNode( node->leaf[0] );
|
||||
wxString propName = formatNode( node->leaf[1] );
|
||||
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( itemName, propName );
|
||||
|
||||
if( !vref )
|
||||
@@ -1006,12 +1006,12 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
{
|
||||
if( m_unitResolver->GetSupportedUnits().empty() )
|
||||
{
|
||||
msg.Printf( _( "Unexpected units for '%s'" ), *node->value.str );
|
||||
msg.Printf( _( "Unexpected units for '%s'" ), formatNode( node ) );
|
||||
reportError( CST_CODEGEN, msg, node->srcPos );
|
||||
}
|
||||
|
||||
int units = son->value.idx;
|
||||
value = m_unitResolver->Convert( *node->value.str, units );
|
||||
value = m_unitResolver->Convert( formatNode( node ), units );
|
||||
son->isVisited = true;
|
||||
}
|
||||
else
|
||||
@@ -1019,12 +1019,12 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
if( !m_unitResolver->GetSupportedUnitsMessage().empty() )
|
||||
{
|
||||
msg.Printf( _( "Missing units for '%s'| (%s)" ),
|
||||
*node->value.str,
|
||||
formatNode( node ),
|
||||
m_unitResolver->GetSupportedUnitsMessage() );
|
||||
reportError( CST_CODEGEN, msg, node->srcPos );
|
||||
}
|
||||
|
||||
value = EDA_UNIT_UTILS::UI::DoubleValueFromString( *node->value.str );
|
||||
value = EDA_UNIT_UTILS::UI::DoubleValueFromString( formatNode( node ) );
|
||||
}
|
||||
|
||||
node->SetUop( TR_UOP_PUSH_VALUE, value );
|
||||
@@ -1034,7 +1034,7 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
|
||||
case TR_STRING:
|
||||
{
|
||||
wxString str = *node->value.str;
|
||||
wxString str = formatNode( node );
|
||||
bool isWildcard = str.Contains("?") || str.Contains("*");
|
||||
node->SetUop( TR_UOP_PUSH_VALUE, str, isWildcard );
|
||||
node->isTerminal = true;
|
||||
@@ -1043,12 +1043,12 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
|
||||
|
||||
case TR_IDENTIFIER:
|
||||
{
|
||||
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( *node->value.str, "" );
|
||||
std::unique_ptr<VAR_REF> vref = aCode->CreateVarRef( formatNode( node ), "" );
|
||||
|
||||
if( !vref )
|
||||
{
|
||||
msg.Printf( _( "Unrecognized item '%s'" ), *node->value.str );
|
||||
reportError( CST_CODEGEN, msg, node->srcPos - (int) node->value.str->length() );
|
||||
msg.Printf( _( "Unrecognized item '%s'" ), formatNode( node ) );
|
||||
reportError( CST_CODEGEN, msg, node->srcPos - (int) formatNode( node ).length() );
|
||||
}
|
||||
|
||||
node->SetUop( TR_UOP_PUSH_VAR, std::move( vref ) );
|
||||
@@ -1220,7 +1220,7 @@ void UOP::Exec( CONTEXT* ctx )
|
||||
result = arg1Value != 0.0 ? 0 : 1;
|
||||
break;
|
||||
default:
|
||||
result = 0.0;
|
||||
result = arg1Value != 0.0 ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2014-2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||
* Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <build_version.h>
|
||||
#include <lockfile.h>
|
||||
|
||||
#include <wx/filename.h>
|
||||
#include <wx/snglinst.h>
|
||||
|
||||
|
||||
std::unique_ptr<wxSingleInstanceChecker> LockFile( const wxString& aFileName )
|
||||
{
|
||||
// first make absolute and normalize, to avoid that different lock files
|
||||
// for the same file can be created
|
||||
wxFileName fn( aFileName );
|
||||
|
||||
fn.MakeAbsolute();
|
||||
|
||||
wxString lockFileName = fn.GetFullPath() + ".lock";
|
||||
|
||||
lockFileName.Replace( "/", "_" );
|
||||
|
||||
// We can have filenames coming from Windows, so also convert Windows separator
|
||||
lockFileName.Replace( "\\", "_" );
|
||||
|
||||
auto p = std::make_unique<wxSingleInstanceChecker>( lockFileName, GetKicadLockFilePath() );
|
||||
|
||||
if( p->IsAnotherRunning() )
|
||||
p = nullptr;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
wxString GetKicadLockFilePath()
|
||||
{
|
||||
wxFileName lockpath;
|
||||
lockpath.AssignDir( wxGetHomeDir() ); // Default wx behavior
|
||||
|
||||
#if defined( __WXMAC__ )
|
||||
// In OSX use the standard per user cache directory
|
||||
lockpath.AppendDir( "Library" );
|
||||
lockpath.AppendDir( "Caches" );
|
||||
lockpath.AppendDir( "kicad" );
|
||||
#elif defined( __UNIX__ )
|
||||
wxString envstr;
|
||||
// Try first the standard XDG_RUNTIME_DIR, falling back to XDG_CACHE_HOME
|
||||
if( wxGetEnv( "XDG_RUNTIME_DIR", &envstr ) && !envstr.IsEmpty() )
|
||||
{
|
||||
lockpath.AssignDir( envstr );
|
||||
}
|
||||
else if( wxGetEnv( "XDG_CACHE_HOME", &envstr ) && !envstr.IsEmpty() )
|
||||
{
|
||||
lockpath.AssignDir( envstr );
|
||||
}
|
||||
else
|
||||
{
|
||||
// If all fails, just use ~/.cache
|
||||
lockpath.AppendDir( ".cache" );
|
||||
}
|
||||
|
||||
lockpath.AppendDir( wxString::Format( "kicad_v%s", GetMajorMinorVersion() ) );
|
||||
#endif
|
||||
|
||||
#if defined( __WXMAC__ ) || defined( __UNIX__ )
|
||||
if( !lockpath.DirExists() )
|
||||
{
|
||||
// Lockfiles should be only readable by the user
|
||||
lockpath.Mkdir( 0700, wxPATH_MKDIR_FULL );
|
||||
}
|
||||
#endif
|
||||
return lockpath.GetPath();
|
||||
}
|
||||
+50
-12
@@ -43,6 +43,7 @@
|
||||
#include <wx/tooltip.h>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <cli/cli_names.h> // Needed for the pre wx 3.2 cli workaround
|
||||
#include <common.h>
|
||||
#include <config_params.h>
|
||||
#include <confirm.h>
|
||||
@@ -51,8 +52,9 @@
|
||||
#include <eda_draw_frame.h>
|
||||
#include <gestfich.h>
|
||||
#include <id.h>
|
||||
#include <kicad_curl/kicad_curl.h>
|
||||
#include <kiplatform/policy.h>
|
||||
#include <lockfile.h>
|
||||
#include <macros.h>
|
||||
#include <menus_helpers.h>
|
||||
#include <paths.h>
|
||||
#include <pgm_base.h>
|
||||
@@ -150,6 +152,8 @@ PGM_BASE::~PGM_BASE()
|
||||
|
||||
void PGM_BASE::Destroy()
|
||||
{
|
||||
KICAD_CURL::Cleanup();
|
||||
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
sentry_close();
|
||||
#endif
|
||||
@@ -234,11 +238,11 @@ const wxString PGM_BASE::AskUserForPreferredEditor( const wxString& aDefaultEdit
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
bool PGM_BASE::IsSentryOptedIn()
|
||||
{
|
||||
KIPLATFORM::POLICY::STATE policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyState( POLICY_KEY_DATACOLLECTION );
|
||||
if( policyState != KIPLATFORM::POLICY::STATE::NOT_CONFIGURED )
|
||||
KIPLATFORM::POLICY::PBOOL policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyBool( POLICY_KEY_DATACOLLECTION );
|
||||
if( policyState != KIPLATFORM::POLICY::PBOOL::NOT_CONFIGURED )
|
||||
{
|
||||
return policyState == KIPLATFORM::POLICY::STATE::ENABLED;
|
||||
return policyState == KIPLATFORM::POLICY::PBOOL::ENABLED;
|
||||
}
|
||||
|
||||
return m_sentry_optin_fn.Exists();
|
||||
@@ -345,10 +349,10 @@ void PGM_BASE::sentryPrompt()
|
||||
if( !IsGUI() )
|
||||
return;
|
||||
|
||||
KIPLATFORM::POLICY::STATE policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyState( POLICY_KEY_DATACOLLECTION );
|
||||
KIPLATFORM::POLICY::PBOOL policyState =
|
||||
KIPLATFORM::POLICY::GetPolicyBool( POLICY_KEY_DATACOLLECTION );
|
||||
|
||||
if( policyState == KIPLATFORM::POLICY::STATE::NOT_CONFIGURED
|
||||
if( policyState == KIPLATFORM::POLICY::PBOOL::NOT_CONFIGURED
|
||||
&& !m_settings_manager->GetCommonSettings()->m_DoNotShowAgain.data_collection_prompt )
|
||||
{
|
||||
wxMessageDialog optIn = wxMessageDialog(
|
||||
@@ -408,6 +412,8 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
|
||||
// In particular, the user cache path is the most likely to be hit by startup code
|
||||
PATHS::EnsureUserPathsExist();
|
||||
|
||||
KICAD_CURL::Init();
|
||||
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
sentryInit();
|
||||
#endif
|
||||
@@ -649,7 +655,7 @@ bool PGM_BASE::SetLanguage( wxString& aErrMsg, bool first_time )
|
||||
|
||||
// don't use wxLOCALE_LOAD_DEFAULT flag so that Init() doesn't return
|
||||
// false just because it failed to load wxstd catalog
|
||||
if( !m_locale->Init( m_language_id, wxLOCALE_DONT_LOAD_DEFAULT ) )
|
||||
if( !m_locale->Init( m_language_id ) )
|
||||
{
|
||||
wxLogTrace( traceLocale, wxT( "This language is not supported by the system." ) );
|
||||
|
||||
@@ -657,7 +663,7 @@ bool PGM_BASE::SetLanguage( wxString& aErrMsg, bool first_time )
|
||||
delete m_locale;
|
||||
|
||||
m_locale = new wxLocale;
|
||||
m_locale->Init( wxLANGUAGE_DEFAULT, wxLOCALE_DONT_LOAD_DEFAULT);
|
||||
m_locale->Init( wxLANGUAGE_DEFAULT );
|
||||
|
||||
aErrMsg = _( "This language is not supported by the operating system." );
|
||||
return false;
|
||||
@@ -708,7 +714,7 @@ bool PGM_BASE::SetLanguage( wxString& aErrMsg, bool first_time )
|
||||
delete m_locale;
|
||||
|
||||
m_locale = new wxLocale;
|
||||
m_locale->Init( wxLANGUAGE_DEFAULT, wxLOCALE_DONT_LOAD_DEFAULT);
|
||||
m_locale->Init( wxLANGUAGE_DEFAULT );
|
||||
|
||||
aErrMsg = _( "The KiCad language file for this language is not installed." );
|
||||
return false;
|
||||
@@ -874,4 +880,36 @@ bool PGM_BASE::IsGUI()
|
||||
bool run_gui = wxTheApp->GetClassName() != KICAD_CLI_APP_NAME;
|
||||
return run_gui;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PGM_BASE::HandleException( std::exception_ptr aPtr )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( aPtr )
|
||||
std::rethrow_exception( aPtr );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
{
|
||||
wxLogError( ioe.What() );
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
#ifdef KICAD_USE_SENTRY
|
||||
sentry_value_t exc = sentry_value_new_exception( "exception", e.what() );
|
||||
sentry_value_set_stacktrace( exc, NULL, 0 );
|
||||
|
||||
sentry_value_t sentryEvent = sentry_value_new_event();
|
||||
sentry_event_add_exception( sentryEvent, exc );
|
||||
sentry_capture_event( sentryEvent );
|
||||
#endif
|
||||
|
||||
wxLogError( wxT( "Unhandled exception class: %s what: %s" ),
|
||||
FROM_UTF8( typeid( e ).name() ), FROM_UTF8( e.what() ) );
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
wxLogError( wxT( "Unhandled exception of unknown type" ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,10 +513,11 @@ void PDF_PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double
|
||||
|
||||
if( alpha < 0xFF )
|
||||
{
|
||||
float a = 1.0 - ( (float) alpha / 255.0 );
|
||||
r = ( int )( r + ( a * 0xFF ) ) & 0xFF;
|
||||
g = ( int )( g + ( a * 0xFF ) ) & 0xFF;
|
||||
b = ( int )( b + ( a * 0xFF ) ) & 0xFF;
|
||||
float d = alpha / 255.0;
|
||||
float a = 1.0 - d;
|
||||
r = std::min( KiROUND( r * d + ( a * 0xFF ) ), 0xFF );
|
||||
g = std::min( KiROUND( g * d + ( a * 0xFF ) ), 0xFF );
|
||||
b = std::min( KiROUND( b * d + ( a * 0xFF ) ), 0xFF );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1216,7 +1217,7 @@ bool PDF_PLOTTER::EndPlot()
|
||||
|
||||
js += wxT( "var cChoice = app.popUpMenuEx.apply\\( app, aParams \\); " );
|
||||
js += wxT( "if\\( cChoice != null && cChoice.substring\\( 0, 1 \\) == '#' \\)"
|
||||
" this.pageNum = cChoice.slice\\( 1 \\); " );
|
||||
" this.pageNum = parseInt\\( cChoice.slice\\( 1 \\) \\); " );
|
||||
js += wxT( "else if\\( cChoice != null && cChoice.substring\\( 0, 4 \\) == 'http' \\)"
|
||||
" app.launchURL\\( cChoice \\);" );
|
||||
|
||||
|
||||
@@ -139,17 +139,17 @@ void PlotDrawingSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BL
|
||||
|
||||
int penWidth = std::max( text->GetEffectiveTextPenWidth(), defaultPenWidth );
|
||||
|
||||
plotter->Text( text->GetTextPos(), color, text->GetShownText(), text->GetTextAngle(),
|
||||
text->GetTextSize(), text->GetHorizJustify(), text->GetVertJustify(),
|
||||
penWidth, text->IsItalic(), text->IsBold(), text->IsMultilineAllowed(),
|
||||
font );
|
||||
plotter->Text( text->GetTextPos(), color, text->GetShownText( true ),
|
||||
text->GetTextAngle(), text->GetTextSize(), text->GetHorizJustify(),
|
||||
text->GetVertJustify(), penWidth, text->IsItalic(), text->IsBold(),
|
||||
text->IsMultilineAllowed(), font );
|
||||
}
|
||||
break;
|
||||
|
||||
case WSG_POLY_T:
|
||||
{
|
||||
DS_DRAW_ITEM_POLYPOLYGONS* poly = (DS_DRAW_ITEM_POLYPOLYGONS*) item;
|
||||
int penWidth = std::max( poly->GetPenWidth(), defaultPenWidth );
|
||||
int penWidth = poly->GetPenWidth();
|
||||
std::vector<VECTOR2I> points;
|
||||
|
||||
for( int idx = 0; idx < poly->GetPolygons().OutlineCount(); ++idx )
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
||||
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -88,26 +89,106 @@ ALTIUM_COMPOUND_FILE::ALTIUM_COMPOUND_FILE( const wxString& aFilePath )
|
||||
}
|
||||
|
||||
|
||||
static const CFB::COMPOUND_FILE_ENTRY*
|
||||
FindStreamSingleLevel( const CFB::CompoundFileReader& aReader,
|
||||
const CFB::COMPOUND_FILE_ENTRY* aEntry, const std::string aName,
|
||||
const bool aIsStream )
|
||||
std::map<wxString, wxString> ALTIUM_COMPOUND_FILE::ListLibFootprints() const
|
||||
{
|
||||
std::map<wxString, wxString> patternMap;
|
||||
|
||||
if( !m_reader )
|
||||
return patternMap;
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* root = m_reader->GetRootEntry();
|
||||
|
||||
if( !root )
|
||||
return patternMap;
|
||||
|
||||
m_reader->EnumFiles( root, 2,
|
||||
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||
int level ) -> void
|
||||
{
|
||||
std::wstring dirName = UTF16ToWstring( dir.data(), dir.size() );
|
||||
std::wstring fileName = UTF16ToWstring( entry->name, entry->nameLen );
|
||||
|
||||
if( m_reader->IsStream( entry ) && fileName == L"Parameters" )
|
||||
{
|
||||
ALTIUM_PARSER parametersReader( *this, entry );
|
||||
std::map<wxString, wxString> parameterProperties =
|
||||
parametersReader.ReadProperties();
|
||||
|
||||
wxString key = ALTIUM_PARSER::ReadString(
|
||||
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||
|
||||
wxString fpName = ALTIUM_PARSER::ReadUnicodeString(
|
||||
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||
|
||||
patternMap.emplace( key, fpName );
|
||||
}
|
||||
} );
|
||||
|
||||
return patternMap;
|
||||
}
|
||||
|
||||
|
||||
wxString ALTIUM_COMPOUND_FILE::FindLibFootprintDirName( const wxString& aFpUnicodeName ) const
|
||||
{
|
||||
if( !m_reader )
|
||||
return wxEmptyString;
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* root = m_reader->GetRootEntry();
|
||||
|
||||
if( !root )
|
||||
return wxEmptyString;
|
||||
|
||||
wxString ret;
|
||||
|
||||
m_reader->EnumFiles( root, 2,
|
||||
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||
int level ) -> void
|
||||
{
|
||||
std::wstring dirName = UTF16ToWstring( dir.data(), dir.size() );
|
||||
std::wstring fileName = UTF16ToWstring( entry->name, entry->nameLen );
|
||||
|
||||
if( m_reader->IsStream( entry ) && fileName == L"Parameters" )
|
||||
{
|
||||
ALTIUM_PARSER parametersReader( *this, entry );
|
||||
std::map<wxString, wxString> parameterProperties =
|
||||
parametersReader.ReadProperties();
|
||||
|
||||
wxString fpName = ALTIUM_PARSER::ReadUnicodeString(
|
||||
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
|
||||
|
||||
if( fpName == aFpUnicodeName )
|
||||
{
|
||||
ret = dirName;
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY*
|
||||
ALTIUM_COMPOUND_FILE::FindStreamSingleLevel( const CFB::COMPOUND_FILE_ENTRY* aEntry,
|
||||
const std::string aName, const bool aIsStream ) const
|
||||
{
|
||||
if( !m_reader || !aEntry )
|
||||
return nullptr;
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* ret = nullptr;
|
||||
|
||||
aReader.EnumFiles( aEntry, 1,
|
||||
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||
int level ) -> void
|
||||
{
|
||||
if( aReader.IsStream( entry ) == aIsStream )
|
||||
{
|
||||
std::string name = UTF16ToUTF8( entry->name );
|
||||
if( name == aName.c_str() )
|
||||
{
|
||||
ret = entry;
|
||||
}
|
||||
}
|
||||
} );
|
||||
m_reader->EnumFiles( aEntry, 1,
|
||||
[&]( const CFB::COMPOUND_FILE_ENTRY* entry, const CFB::utf16string& dir,
|
||||
int level ) -> void
|
||||
{
|
||||
if( m_reader->IsStream( entry ) == aIsStream )
|
||||
{
|
||||
std::string name = UTF16ToUTF8( entry->name );
|
||||
if( name == aName.c_str() )
|
||||
{
|
||||
ret = entry;
|
||||
}
|
||||
}
|
||||
} );
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -116,9 +197,7 @@ const CFB::COMPOUND_FILE_ENTRY*
|
||||
ALTIUM_COMPOUND_FILE::FindStream( const std::vector<std::string>& aStreamPath ) const
|
||||
{
|
||||
if( !m_reader )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* currentDirEntry = m_reader->GetRootEntry();
|
||||
|
||||
@@ -129,12 +208,11 @@ ALTIUM_COMPOUND_FILE::FindStream( const std::vector<std::string>& aStreamPath )
|
||||
|
||||
if( ++it == aStreamPath.cend() )
|
||||
{
|
||||
return FindStreamSingleLevel( *m_reader.get(), currentDirEntry, name, true );
|
||||
return FindStreamSingleLevel( currentDirEntry, name, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
currentDirEntry =
|
||||
FindStreamSingleLevel( *m_reader.get(), currentDirEntry, name, false );
|
||||
currentDirEntry = FindStreamSingleLevel( currentDirEntry, name, false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,9 +310,12 @@ std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties()
|
||||
else
|
||||
value = wxString( valueS.c_str(), wxConvISO8859_1 );
|
||||
|
||||
// Breathless hack because I haven't a clue what the story is here (but this character
|
||||
// appears in a lot of radial dimensions and is rendered by Altium as a space).
|
||||
value.Replace( wxT( "ÿ" ), wxT( " " ) );
|
||||
if( canonicalKey != wxS( "PATTERN" ) && canonicalKey != wxS( "SOURCEFOOTPRINTLIBRARY" ) )
|
||||
{
|
||||
// Breathless hack because I haven't a clue what the story is here (but this character
|
||||
// appears in a lot of radial dimensions and is rendered by Altium as a space).
|
||||
value.Replace( wxT( "ÿ" ), wxT( " " ) );
|
||||
}
|
||||
|
||||
if( canonicalKey == wxT( "DESIGNATOR" )
|
||||
|| canonicalKey == wxT( "NAME" )
|
||||
@@ -341,3 +422,28 @@ wxString ALTIUM_PARSER::ReadString( const std::map<wxString, wxString>& aProps,
|
||||
|
||||
return aDefault;
|
||||
}
|
||||
|
||||
|
||||
wxString ALTIUM_PARSER::ReadUnicodeString( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault )
|
||||
{
|
||||
const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) );
|
||||
|
||||
if( unicodeFlag != aProps.end() && unicodeFlag->second.Contains( wxS( "EXISTS" ) ) )
|
||||
{
|
||||
const auto& unicodeValue = aProps.find( wxString( "UNICODE__" ) + aKey );
|
||||
|
||||
if( unicodeValue != aProps.end() )
|
||||
{
|
||||
wxArrayString arr = wxSplit( unicodeValue->second, ',', '\0' );
|
||||
wxString out;
|
||||
|
||||
for( wxString part : arr )
|
||||
out += wxString( wchar_t( wxAtoi( part ) ) );
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
return ReadString( aProps, aKey, aDefault );
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
|
||||
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -63,8 +63,16 @@ public:
|
||||
|
||||
const CFB::CompoundFileReader& GetCompoundFileReader() const { return *m_reader; }
|
||||
|
||||
std::map<wxString, wxString> ListLibFootprints() const;
|
||||
|
||||
wxString FindLibFootprintDirName( const wxString& aFpUnicodeName ) const;
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* FindStream( const std::vector<std::string>& aStreamPath ) const;
|
||||
|
||||
const CFB::COMPOUND_FILE_ENTRY* FindStreamSingleLevel( const CFB::COMPOUND_FILE_ENTRY* aEntry,
|
||||
const std::string aName,
|
||||
const bool aIsStream ) const;
|
||||
|
||||
private:
|
||||
std::unique_ptr<CFB::CompoundFileReader> m_reader;
|
||||
std::vector<char> m_buffer;
|
||||
@@ -107,24 +115,31 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
wxString ReadWxString()
|
||||
wxScopedCharBuffer ReadCharBuffer()
|
||||
{
|
||||
uint8_t len = Read<uint8_t>();
|
||||
if( GetRemainingBytes() >= len )
|
||||
{
|
||||
// TODO: Identify where the actual code page is stored. For now, this default code page
|
||||
// has limited impact, because recent Altium files come with a UTF16 string table
|
||||
wxString val = wxString( m_pos, wxConvISO8859_1, len );
|
||||
char* buf = new char[len];
|
||||
memcpy( buf, m_pos, len );
|
||||
m_pos += len;
|
||||
return val;
|
||||
|
||||
return wxScopedCharBuffer::CreateOwned( buf, len );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_error = true;
|
||||
return wxString( "" );
|
||||
return wxScopedCharBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
wxString ReadWxString()
|
||||
{
|
||||
// TODO: Identify where the actual code page is stored. For now, this default code page
|
||||
// has limited impact, because recent Altium files come with a UTF16 string table
|
||||
return wxString( ReadCharBuffer(), wxConvISO8859_1 );
|
||||
}
|
||||
|
||||
std::map<uint32_t, wxString> ReadWideStringTable()
|
||||
{
|
||||
std::map<uint32_t, wxString> table;
|
||||
@@ -225,6 +240,9 @@ public:
|
||||
static wxString ReadString( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault );
|
||||
|
||||
static wxString ReadUnicodeString( const std::map<wxString, wxString>& aProps,
|
||||
const wxString& aKey, const wxString& aDefault );
|
||||
|
||||
void Skip( size_t aLength )
|
||||
{
|
||||
if( GetRemainingBytes() >= aLength )
|
||||
|
||||
@@ -49,7 +49,7 @@ wxString escapeName( const wxString& aNetName )
|
||||
|
||||
wxString interpretText( const wxString& aText )
|
||||
{
|
||||
wxString token = aText.Upper();
|
||||
wxString token = aText;
|
||||
|
||||
if( substituteVariable( &token ) )
|
||||
return token;
|
||||
@@ -116,25 +116,32 @@ wxString interpretText( const wxString& aText )
|
||||
|
||||
bool substituteVariable( wxString* aText )
|
||||
{
|
||||
if ( *aText == wxT( ">NAME" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( *aText == wxT( ">VALUE" ) ) *aText = wxT( "${VALUE}" );
|
||||
else if( *aText == wxT( ">PART" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( *aText == wxT( ">GATE" ) ) *aText = wxT( "${UNIT}" );
|
||||
else if( *aText == wxT( ">MODULE" ) ) *aText = wxT( "${FOOTPRINT_NAME}" );
|
||||
else if( *aText == wxT( ">SHEETNR" ) ) *aText = wxT( "${#}" );
|
||||
else if( *aText == wxT( ">SHEETS" ) ) *aText = wxT( "${##}" );
|
||||
else if( *aText == wxT( ">SHEET" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( *aText == wxT( ">SHEETNR_TOTAL" ) ) *aText = wxT( "${#}" );
|
||||
else if( *aText == wxT( ">SHEETS_TOTAL" ) ) *aText = wxT( "${##}" );
|
||||
else if( *aText == wxT( ">SHEET_TOTAL" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( *aText == wxT( ">SHEET_HEADLINE" ) ) *aText = wxT( "${SHEETNAME}" );
|
||||
else if( *aText == wxT( ">ASSEMBLY_VARIANT" ) ) *aText = wxT( "${ASSEMBLY_VARIANT}" );
|
||||
else if( *aText == wxT( ">DRAWING_NAME" ) ) *aText = wxT( "${PROJECTNAME}" );
|
||||
else if( *aText == wxT( ">LAST_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else if( *aText == wxT( ">PLOT_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else return false;
|
||||
if( aText->StartsWith( '>' ) && aText->AfterFirst( ' ' ).IsEmpty() )
|
||||
{
|
||||
wxString token = aText->Upper();
|
||||
|
||||
return true;
|
||||
if ( token == wxT( ">NAME" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( token == wxT( ">VALUE" ) ) *aText = wxT( "${VALUE}" );
|
||||
else if( token == wxT( ">PART" ) ) *aText = wxT( "${REFERENCE}" );
|
||||
else if( token == wxT( ">GATE" ) ) *aText = wxT( "${UNIT}" );
|
||||
else if( token == wxT( ">MODULE" ) ) *aText = wxT( "${FOOTPRINT_NAME}" );
|
||||
else if( token == wxT( ">SHEETNR" ) ) *aText = wxT( "${#}" );
|
||||
else if( token == wxT( ">SHEETS" ) ) *aText = wxT( "${##}" );
|
||||
else if( token == wxT( ">SHEET" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( token == wxT( ">SHEETNR_TOTAL" ) ) *aText = wxT( "${#}" );
|
||||
else if( token == wxT( ">SHEETS_TOTAL" ) ) *aText = wxT( "${##}" );
|
||||
else if( token == wxT( ">SHEET_TOTAL" ) ) *aText = wxT( "${#}/${##}" );
|
||||
else if( token == wxT( ">SHEET_HEADLINE" ) ) *aText = wxT( "${SHEETNAME}" );
|
||||
else if( token == wxT( ">ASSEMBLY_VARIANT" ) ) *aText = wxT( "${ASSEMBLY_VARIANT}" );
|
||||
else if( token == wxT( ">DRAWING_NAME" ) ) *aText = wxT( "${PROJECTNAME}" );
|
||||
else if( token == wxT( ">LAST_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else if( token == wxT( ">PLOT_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
|
||||
else *aText = wxString::Format( wxS( "${%s}" ), aText->Mid( 1 ).Trim() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017-2022 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2017-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -117,6 +117,12 @@ bool POLYGON_GEOM_MANAGER::IsPolygonInProgress() const
|
||||
}
|
||||
|
||||
|
||||
int POLYGON_GEOM_MANAGER::PolygonPointCount() const
|
||||
{
|
||||
return m_lockedPoints.PointCount();
|
||||
}
|
||||
|
||||
|
||||
bool POLYGON_GEOM_MANAGER::NewPointClosesOutline( const VECTOR2I& aPt ) const
|
||||
{
|
||||
return m_lockedPoints.PointCount() > 0 && m_lockedPoints.CPoint( 0 ) == aPt;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2019-2021 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2019-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@@ -154,6 +154,22 @@ void KIGFX::PREVIEW::DrawTextNextToCursor( KIGFX::VIEW* aView, const VECTOR2D& a
|
||||
textPos.x -= 15.0 / gal->GetWorldScale();
|
||||
}
|
||||
|
||||
// text is left (or right) aligned, so a shadow text need a small offset to be draw
|
||||
// around the basic text
|
||||
int shadowXoffset = aDrawingDropShadows ? textDims.ShadowWidth : 0;
|
||||
|
||||
// Due to the fact a shadow text is drawn left or right aligned,
|
||||
// it needs an offset = shadowWidth/2 to be drawn at the same place as normal text
|
||||
// But for some reason we need to slightly modify this offset
|
||||
// for a better look for KiCad font (better alignment of shadow shape)
|
||||
const float adjust = 1.2f; // Value chosen after tests
|
||||
shadowXoffset *= adjust;
|
||||
|
||||
if( ( textAttrs.m_Halign == GR_TEXT_H_ALIGN_LEFT ) != viewFlipped )
|
||||
textPos.x -= shadowXoffset;
|
||||
else
|
||||
textPos.x += shadowXoffset;
|
||||
|
||||
gal->SetStrokeColor( aView->GetPainter()->GetSettings()->GetLayerColor( LAYER_AUX_ITEMS ) );
|
||||
textAttrs.m_Mirrored = viewFlipped; // Prevent text flipping when view is flipped
|
||||
textAttrs.m_Size = textDims.GlyphSize;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2017-2022 Kicad Developers, see change_log.txt for contributors.
|
||||
* Copyright (C) 2017-2023 Kicad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -167,25 +167,50 @@ void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECT
|
||||
EDA_ANGLE labelAngle = - EDA_ANGLE( tickLine );
|
||||
VECTOR2I labelOffset = tickLine.Resize( majorTickLen );
|
||||
|
||||
// text is left (or right) aligned, so shadow text need a small offset to be draw
|
||||
// around the basic text
|
||||
int shadowXoffset = 0;
|
||||
|
||||
if( aDrawingDropShadows )
|
||||
{
|
||||
labelDims.StrokeWidth += 2 * labelDims.ShadowWidth;
|
||||
shadowXoffset = labelDims.ShadowWidth;
|
||||
// Due to the fact a shadow text is drawn left or right aligned,
|
||||
// it needs an offset = shadowXoffset to be drawn at the same place as normal text
|
||||
// But for some reason we need to slightly modify this offset
|
||||
// for a better look for KiCad font (better alignment of shadow shape)
|
||||
const float adjust = 1.2f; // Value chosen after tests
|
||||
shadowXoffset *= adjust;
|
||||
}
|
||||
|
||||
if( aView->IsMirroredX() )
|
||||
{
|
||||
labelOffset = -labelOffset;
|
||||
shadowXoffset = -shadowXoffset;
|
||||
}
|
||||
|
||||
TEXT_ATTRIBUTES labelAttrs;
|
||||
labelAttrs.m_Size = labelDims.GlyphSize;
|
||||
labelAttrs.m_StrokeWidth = labelDims.StrokeWidth;
|
||||
labelAttrs.m_Mirrored = aView->IsMirroredX(); // Prevent text mirrored when view is mirrored
|
||||
|
||||
if( EDA_ANGLE( aLine ) > ANGLE_0 )
|
||||
{
|
||||
labelAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
|
||||
labelAttrs.m_Angle = labelAngle;
|
||||
|
||||
// Adjust the text position of the shadow shape:
|
||||
labelOffset.x -= shadowXoffset * labelAttrs.m_Angle.Cos();;
|
||||
labelOffset.y += shadowXoffset * labelAttrs.m_Angle.Sin();;
|
||||
}
|
||||
else
|
||||
{
|
||||
labelAttrs.m_Halign = GR_TEXT_H_ALIGN_RIGHT;
|
||||
labelAttrs.m_Angle = labelAngle + ANGLE_180;
|
||||
|
||||
// Adjust the text position of the shadow shape:
|
||||
labelOffset.x += shadowXoffset * labelAttrs.m_Angle.Cos();;
|
||||
labelOffset.y -= shadowXoffset * labelAttrs.m_Angle.Sin();;
|
||||
}
|
||||
|
||||
BOX2D viewportD = aView->GetViewport();
|
||||
@@ -194,6 +219,8 @@ void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECT
|
||||
viewport.Inflate( majorTickLen * 2 ); // Doesn't have to be accurate, just big enough not
|
||||
// to exclude anything that should be partially drawn
|
||||
|
||||
int isign = aView->IsMirroredX() ? -1 : 1;
|
||||
|
||||
for( int i = 0; i < numTicks; ++i )
|
||||
{
|
||||
const VECTOR2D tickPos = aOrigin + aLine.Resize( tickSpace * i );
|
||||
@@ -216,7 +243,7 @@ void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECT
|
||||
}
|
||||
|
||||
gal->SetLineWidth( labelAttrs.m_StrokeWidth / 2 );
|
||||
gal->DrawLine( tickPos, tickPos + tickLine.Resize( length ) );
|
||||
gal->DrawLine( tickPos, tickPos + tickLine.Resize( length*isign ) );
|
||||
|
||||
if( drawLabel )
|
||||
{
|
||||
@@ -244,9 +271,10 @@ void drawBacksideTicks( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTO
|
||||
TEXT_DIMS textDims = GetConstantGlyphHeight( gal, -1 );
|
||||
const double backTickSpace = aLine.EuclideanNorm() / aNumDivisions;
|
||||
VECTOR2D backTickVec = aLine;
|
||||
int isign = aView->IsMirroredX() ? -1 : 1;
|
||||
|
||||
RotatePoint( backTickVec, -ANGLE_90 );
|
||||
backTickVec = backTickVec.Resize( aTickLen );
|
||||
backTickVec = backTickVec.Resize( aTickLen * isign );
|
||||
|
||||
BOX2D viewportD = aView->GetViewport();
|
||||
BOX2I viewport( VECTOR2I( viewportD.GetPosition() ), VECTOR2I( viewportD.GetSize() ) );
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user