Compare commits
633 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cc82296118 | |||
| bce055fa21 | |||
| 45471ecfc9 | |||
| ca8633b3db | |||
| fbb70da3c0 | |||
| 8f8c937db5 | |||
| b62a67ceba | |||
| c0c25fb1d7 | |||
| 2b3d3bc41b | |||
| 60d64c8c1b | |||
| b5a54e8822 | |||
| 962aadb859 | |||
| e2a5b8ee74 | |||
| a3f7e5339b | |||
| c5964c59ce | |||
| dcff6e0547 | |||
| 9f6e81e9cc | |||
| 17c867e92f | |||
| 938dec0d6e | |||
| 0107ac0532 | |||
| d4910a66dc | |||
| 89ebfa63c9 | |||
| 451642fa62 | |||
| 8f52e2b685 | |||
| 3597d76c40 | |||
| 6c092d78a3 | |||
| 95bbcc40d4 | |||
| 2ebe4cc9e2 | |||
| 2f52c4901a | |||
| 689fb262c5 | |||
| 16b0ec206a | |||
| 890735dbe1 | |||
| 3cfb633ea4 | |||
| 92274f1a5d | |||
| 7d03b6bb8c | |||
| 9ae5759e24 | |||
| 11467a7f4b | |||
| f8f051275f | |||
| a167322440 | |||
| 2b1747f80f | |||
| 26b350b51a | |||
| 64821c793f | |||
| 50ddfefbbb | |||
| 49ee909d68 | |||
| 85ebd7c371 | |||
| 12d1f5bdd9 | |||
| 5071295d34 | |||
| 5885b364a3 | |||
| 1a04549321 | |||
| b9819bc8ae | |||
| 7cd534c614 | |||
| f652fbcfcf | |||
| 6085182574 | |||
| 3aa22cd4e4 | |||
| 7e33fc18d3 | |||
| 0503b22617 | |||
| e2562aae5d | |||
| b1b28786af | |||
| 355afb9845 | |||
| 14d2ebc607 | |||
| c48ace68a0 | |||
| c82caa6dc1 | |||
| 50309f0033 | |||
| a588a63778 | |||
| 481e78a29f | |||
| 5e4633545b | |||
| 447be71b65 | |||
| a54ac23bbb | |||
| a017fb265f | |||
| 65e486499e | |||
| ef2f445b14 | |||
| 866d92e1f6 | |||
| 3003c0c509 | |||
| 9b3e14546e | |||
| 1a3bded55e | |||
| bf9d6e2689 | |||
| 24529ef5df | |||
| 4bf59e4b0f | |||
| 2c35d43069 | |||
| a3a00a4932 | |||
| 2fd4406f04 | |||
| d4c262cc40 | |||
| 1767edfd87 | |||
| 704bfa5391 | |||
| ed8a699670 | |||
| 49ca0e5452 | |||
| 844a1b5eb9 | |||
| ff6c1852b4 | |||
| 6d6355c67d | |||
| 3321da2a5d | |||
| 74963bd16c | |||
| 03c67a8033 | |||
| 778d8846d6 | |||
| b5a763fe69 | |||
| af16d38b46 | |||
| d089ecbc02 | |||
| 06b6b51ed8 | |||
| cbaeb2235e | |||
| 833b5fc6e2 | |||
| 22efda6367 | |||
| 964947bc4f | |||
| f032186e43 | |||
| 91f6033982 | |||
| fa1bb05cfa | |||
| 9ac570c622 | |||
| 1e795bee18 | |||
| e9a1792d45 | |||
| c2593c3547 | |||
| c59c1701bb | |||
| 534acc718d | |||
| 7f6557e76a | |||
| b6f21ea2ae | |||
| e906e5e98c | |||
| c5a02c908f | |||
| 9edf3e4005 | |||
| 55a8a075e6 | |||
| 1f95d9bc1c | |||
| 97971957ce | |||
| 662f4c1e89 | |||
| 49a03c7c01 | |||
| ed6319fae0 | |||
| 10f5d88b7a | |||
| 8937681052 | |||
| a0030b4dd3 | |||
| 1fb6254d62 | |||
| 6f0bafa7a0 | |||
| c7e7d3aac8 | |||
| 312dd06216 | |||
| 803ce01795 | |||
| d9cc8ee071 | |||
| 27df4775d0 | |||
| 3071bbd201 | |||
| 6296360047 | |||
| a23c267fb3 | |||
| 85f483c36b | |||
| e99964d652 | |||
| a68a69893c | |||
| 3f528f89ef | |||
| 1a69f21462 | |||
| 47363766c7 | |||
| 1d694eba5d | |||
| dbeaeae919 | |||
| 4f97ce15cc | |||
| d27552a282 | |||
| 0be18638f8 | |||
| a697be4fbf | |||
| ac6dcbe9ae | |||
| d16f784412 | |||
| b12b88fd40 | |||
| bd2152bb3d | |||
| 677750b64e | |||
| d6ddeff443 | |||
| 06e1e4c62c | |||
| aa6fb159b5 | |||
| 3ed9fbe423 | |||
| 8b93d56c14 | |||
| 138f8af8ab | |||
| 00b6f25031 | |||
| fdb333ca8b | |||
| 014a4d040c | |||
| 5818b52a38 | |||
| ea5ae7cc5d | |||
| f230800365 | |||
| 51ba93c680 | |||
| bddc4e5f89 | |||
| bdd98e801f | |||
| a7c69264ad | |||
| 9c16efcb83 | |||
| 89155c488f | |||
| 949be9a63a | |||
| 0685039e0a | |||
| 5ab0ab2bdb | |||
| 95f895b4a9 | |||
| 34a7f64821 | |||
| 95f1630bce | |||
| 85494592d6 | |||
| 4a5c64a036 | |||
| 39e69ffdad | |||
| 48d8c8d0b2 | |||
| 06f48b6c88 | |||
| 96868b2737 | |||
| 4e4a2d1fa1 | |||
| 3c4f582352 | |||
| 7a513cb61a | |||
| 29863a3da1 | |||
| f059596736 | |||
| 19c0bb27f5 | |||
| 7852afc219 | |||
| 32b15a6d8d | |||
| 5eb95e9976 | |||
| 378b7ef2cb | |||
| 1770ce0557 | |||
| 31ce874136 | |||
| c4d3d0e0e2 | |||
| 050df10ad4 | |||
| 2c8d12f9eb | |||
| acc70d85c3 | |||
| 995e313f3a | |||
| c5b6ebaa1a | |||
| 9ce8200750 | |||
| 5bc2f6aa2b | |||
| db2f1a3040 | |||
| 3a77e1377a | |||
| 7a9d9fb5f6 | |||
| d4c25be6c0 | |||
| 11d08ae2c8 | |||
| da8be848e1 | |||
| c3226645c5 | |||
| 144cdd98ce | |||
| 9aa9a618be | |||
| 2cc574ed14 | |||
| 08267916e8 | |||
| 3476553bb2 | |||
| c7fd6a14d6 | |||
| 8c1e3704e7 | |||
| 9eef6cf857 | |||
| 2b662b4ccc | |||
| 8a78d83087 | |||
| c05fe36a0a | |||
| 2cf7288b1b | |||
| 77686f50af | |||
| f84f0b913d | |||
| 8a3464bdf1 | |||
| 51646e6605 | |||
| e962686afb | |||
| 9211d60d7b | |||
| 632c03a874 | |||
| 24d2eded07 | |||
| d3a5bf20db | |||
| 099e0d1312 | |||
| 3c1bc31456 | |||
| 2fffc9780b | |||
| 68bfa2001e | |||
| ebdf4c7719 | |||
| f944b662b6 | |||
| 3ac9bace21 | |||
| 98141d0143 | |||
| d90d86775b | |||
| 578d0a5a4a | |||
| 53075ee9f3 | |||
| 7f19d051ed | |||
| 364cf0808f | |||
| d3cce1e35c | |||
| 1b20a932ad | |||
| 3b0dac9491 | |||
| 4433da15b1 | |||
| e4af447855 | |||
| ecd4326533 | |||
| 73854bc9f1 | |||
| 544c035298 | |||
| c8da489b1f | |||
| da6f97b24f | |||
| 464d248b8c | |||
| b790b46c76 | |||
| b4a5422e54 | |||
| 565d54a184 | |||
| ebcf96dcd6 | |||
| e067a8ddc8 | |||
| 4d8feb94bd | |||
| 2374e5e542 | |||
| a3e4a001bb | |||
| edc25f8ba0 | |||
| 10a03972d4 | |||
| 5a3c210b7c | |||
| 239eb5a1ff | |||
| c1a1bbc96b | |||
| c16076a5c3 | |||
| 77ab6c29bf | |||
| 9366902052 | |||
| 86b687bdaf | |||
| 1da4895619 | |||
| fbf9a45a00 | |||
| c6c2d6468d | |||
| b349140112 | |||
| 5dafadb12c | |||
| da1f71684c | |||
| 563a2d20b7 | |||
| f31450018d | |||
| c329ba2b4c | |||
| fe42b1fd6b | |||
| 66628a3501 | |||
| e21ebbff76 | |||
| 7df0a80eed | |||
| 790dee114b | |||
| 3f17abba60 | |||
| dbca140d17 | |||
| d563588b28 | |||
| 4503abdf80 | |||
| d670be0007 | |||
| f55873fc3d | |||
| 330437ee8d | |||
| 61648be38a | |||
| 58584cb227 | |||
| 4cab605fb6 | |||
| 57f6d1c015 | |||
| 57df0435bf | |||
| 46312674c6 | |||
| 32781c3992 | |||
| 48b3408f9a | |||
| e892783109 | |||
| 5865431759 | |||
| d75d0ef686 | |||
| baf4843a45 | |||
| 57309d4a62 | |||
| a9ad99f513 | |||
| 5a459ce982 | |||
| 32626dfa1d | |||
| 3406f20a5c | |||
| 2fedbaac2e | |||
| b3f7e2e827 | |||
| 6430bd6c61 | |||
| cb51d324b7 | |||
| 1eb9accb1e | |||
| fb8716f16a | |||
| 1bdeebf13d | |||
| 3688a9ca61 | |||
| 94370cc6d8 | |||
| 186839b245 | |||
| c70653c9dc | |||
| ed59993fc3 | |||
| fec37a0f79 | |||
| 7a4ab8971c | |||
| 76cff2e7aa | |||
| e95aab5df6 | |||
| 0b1fee9f7f | |||
| 8a5c51d37f | |||
| d288dce1d0 | |||
| 89b92fe3f5 | |||
| cb7385bf0c | |||
| ec6af273bb | |||
| 0dd4d0e46c | |||
| 2d0c5dc8bd | |||
| 95418742e9 | |||
| 53d0d60f33 | |||
| bf1dbde3c3 | |||
| 2b1b1b4fcb | |||
| a1066bac65 | |||
| a30498a572 | |||
| 5403990121 | |||
| 2deacd59ef | |||
| 7d67775f45 | |||
| c5ef10cf2c | |||
| 04d0719269 | |||
| f143ce563f | |||
| 5792a02825 | |||
| 0dc0061d30 | |||
| 2116e272b5 | |||
| 25c14ae7cb | |||
| 3a8fc4dd82 | |||
| 5558dce259 | |||
| 8fe891a475 | |||
| 501b63028b | |||
| b7d7403e6f | |||
| c0648c4728 | |||
| a33003cf62 | |||
| 1d577cf917 | |||
| d189c6ddbf | |||
| f781ec82c9 | |||
| 3a33a5b506 | |||
| 4436d93446 | |||
| 238612d2c2 | |||
| f787c01b47 | |||
| f8e60b11c9 | |||
| 0f07c4ef78 | |||
| 6fcfcd28ca | |||
| 1773eb2b1c | |||
| 45bdde41b3 | |||
| 292faaa48d | |||
| 44c473c1b3 | |||
| 85474345d6 | |||
| fda292bd08 | |||
| c666bf8626 | |||
| 96f20d102b | |||
| f57cdb52dd | |||
| a5d2294ec3 | |||
| 72fdb41b73 | |||
| 2ca04123d4 | |||
| 07a4710363 | |||
| c01e37304f | |||
| 52b57b1145 | |||
| 7b4e444f6c | |||
| a9f4f85746 | |||
| bc7ece44eb | |||
| 51cc22a4f2 | |||
| 38f2541a3f | |||
| a05e3de852 | |||
| 908e7205e7 | |||
| a80e410683 | |||
| fa234e4b58 | |||
| fb82e722e1 | |||
| b45f9e7392 | |||
| d496b281ef | |||
| 2a46ff370a | |||
| 44d0b27544 | |||
| 7d76868c5c | |||
| e4d9d1829f | |||
| e585948861 | |||
| e31b177335 | |||
| 4624d57bc2 | |||
| 4f2d1ec5a1 | |||
| 5bcb3edae1 | |||
| 30fbfd53c1 | |||
| dc979be459 | |||
| 450c4517b5 | |||
| 47cd4d6b7a | |||
| 8842c575c3 | |||
| 858c23f731 | |||
| 1d879d51c5 | |||
| 6e0df489eb | |||
| a9be5c5759 | |||
| 258e2fd46f | |||
| f5852f0869 | |||
| 1d0adbc5d6 | |||
| 34834fd963 | |||
| 2f095aeafb | |||
| 47bb72179f | |||
| 9f7af4a3a7 | |||
| dda127ceec | |||
| 68e6e0a742 | |||
| a844ba713a | |||
| 5d75bd0f0a | |||
| c492565ee8 | |||
| 879d2bef4b | |||
| 05376a39ac | |||
| 9c01c2aeb8 | |||
| 72db7bfedc | |||
| 95cfe2cc2e | |||
| c6f5daf87f | |||
| b1711d692a | |||
| d538182f1f | |||
| b4b87b5c38 | |||
| eed95e612d | |||
| 68d3c7f5c2 | |||
| 848d5484d8 | |||
| d3b84f219c | |||
| 58ccf62d2f | |||
| 021229647f | |||
| 9a812bc63c | |||
| 8a9201b79c | |||
| f8e9b3402f | |||
| 808c645933 | |||
| ea467c1bac | |||
| c51b6a0cd2 | |||
| 10f16ed82e | |||
| ab9cf326e8 | |||
| 4e6087c183 | |||
| e7abf472ba | |||
| f0c6b57ab9 | |||
| e830709cda | |||
| 415aac7fc5 | |||
| 21f15c3b2a | |||
| 0f8df0bcee | |||
| d6ef6252a2 | |||
| f13c9cbd49 | |||
| c2af66a44b | |||
| 40c50c94fb | |||
| 0103f92d0e | |||
| 0f27f8b7fc | |||
| 5631b61dbc | |||
| da659f5d05 | |||
| 2029c5389f | |||
| 4205e70775 | |||
| 4f66225de7 | |||
| 18e4682c3a | |||
| 6b540ae1e3 | |||
| 1f12b6c17d | |||
| e2c23c70f1 | |||
| f60f0394be | |||
| bd64bcf446 | |||
| 176d0f5820 | |||
| 118ee1c072 | |||
| fd15a1108b | |||
| 43b5d4d91f | |||
| d11ab8201f | |||
| 86bae558b4 | |||
| 68991a7644 | |||
| 0701640c5a | |||
| 9fe656a33c | |||
| 3fb8f22fd3 | |||
| 929930fb3a | |||
| 4195b874d5 | |||
| ae0d6c80dd | |||
| 4e2f84727c | |||
| 35889130e8 | |||
| 2e7145cc4b | |||
| e0d955993c | |||
| cd7a646fcc | |||
| cb2a09d17c | |||
| d0cb210427 | |||
| b89d77bf36 | |||
| 7fdeb4796a | |||
| e82088a59b | |||
| 5a5191361f | |||
| b47f8f4504 | |||
| 00ae91d6b5 | |||
| 097e0eadf1 | |||
| c8c293dca8 | |||
| e6cfd1cdcf | |||
| 905170b4f4 | |||
| 57fa8ea2b9 | |||
| c7730a00c4 | |||
| beaaf3b5be | |||
| b644f15d7f | |||
| af398762db | |||
| dfd40b566d | |||
| e056ef2693 | |||
| 02d0944546 | |||
| 1aba70ca37 | |||
| ff8b82d060 | |||
| 68d1e3223a | |||
| 9e64d52a38 | |||
| f7b3c0226b | |||
| 17fc05ec45 | |||
| b64f1f2bd3 | |||
| b32d8862da | |||
| ff061e51a0 | |||
| 6020e6d6f9 | |||
| a3fffc868f | |||
| 9670aa1b8a | |||
| 85ba5ae406 | |||
| faa3287fd6 | |||
| 33ab1d9242 | |||
| 01aa2d7e42 | |||
| b24e2ac00d | |||
| 2bc3ef82dc | |||
| 672ba5cd41 | |||
| 905b9ae6c5 | |||
| f81a203c22 | |||
| 7aa0431a60 | |||
| 57505674f8 | |||
| 558bef00cc | |||
| 28f9bd797a | |||
| 52d6fc66f1 | |||
| ab49e9b29d | |||
| f6710e64de | |||
| 804154e21d | |||
| 03cb8521bc | |||
| 3ee940e3fb | |||
| 8b25c3b0fe | |||
| 529cf246d2 | |||
| 7e7c281a64 | |||
| 350925f10a | |||
| 5e8982600a | |||
| e633af9216 | |||
| b0f21e5452 | |||
| d2d582cc00 | |||
| 4f11681c4a | |||
| 897ebee00f | |||
| be0a42a09a | |||
| 3069799a2d | |||
| ad22e53518 | |||
| 2ef05eb191 | |||
| 235e583182 | |||
| 76ce4ec535 | |||
| 0226481156 | |||
| 8fab2d8ca3 | |||
| 1c6d8b3f5e | |||
| 32e9ab9b75 | |||
| ca0207016e | |||
| 9ca1bf63d9 | |||
| 7e13870ae3 | |||
| 3c907b5589 | |||
| e9efd9971c | |||
| 2bf9a6f5d1 | |||
| 42c67b40b1 | |||
| 5ae3c55a99 | |||
| 54e9a97b26 | |||
| 1e3b879d93 | |||
| 7ca6a93436 | |||
| 05c11d023f | |||
| 996c3d7fa1 | |||
| b204742fe3 | |||
| 2b8e62e0b9 | |||
| c3d122becf | |||
| 43c828474a | |||
| 8073185c36 | |||
| f1ddcfe799 | |||
| 9d6f9c84d0 | |||
| 680a693c04 | |||
| 4f72dd421a | |||
| bc533de0a3 | |||
| c08109d63e | |||
| b11f0a31b9 | |||
| f6fabdc8ee | |||
| 965abb46d0 | |||
| c9f53c607e | |||
| 7b91b51bcf | |||
| a3354dc352 | |||
| 6723964cdd | |||
| df5f4ba541 | |||
| 926f41a0f5 | |||
| db801c8d7e | |||
| ad433b9468 | |||
| 1eefb2b70a | |||
| 3d6527c1be | |||
| 319530ad01 | |||
| 24efca1db1 | |||
| a009d859d0 | |||
| 44a3bb9274 | |||
| 72e1904708 | |||
| 279a30974e | |||
| efc6c3e45e | |||
| f7380ae015 | |||
| 26b6c28bef | |||
| 8cd7b73b2a | |||
| c2d31699bf | |||
| 47c5918c3d | |||
| 12cf3f9301 | |||
| 013aab58d6 | |||
| 316a9511e8 | |||
| 29fadcb931 | |||
| d73fecd2a1 | |||
| 35caf91c31 | |||
| 352cf21ffc | |||
| 21335f604f | |||
| c6b7f90408 | |||
| a5dee0c2b1 | |||
| bf73ad42ca | |||
| 7d905948f5 | |||
| 5c8c0e0648 | |||
| 4cfa2e3a38 | |||
| eecf0cd685 | |||
| 91e5e81bb4 | |||
| 5b3cd96641 | |||
| db0967d5c9 | |||
| 5165ced528 | |||
| eb4f9fa093 | |||
| 47381f3d90 | |||
| e697339bc6 | |||
| 6159cee2b0 | |||
| 3460b33ccf | |||
| 5baaa89131 | |||
| d45a38f086 |
@@ -8,6 +8,7 @@ win64_build:
|
||||
interruptible: false
|
||||
image: registry.gitlab.com/kicad/kicad-ci/windows-build-image/ltsc2022-msvc:latest
|
||||
variables:
|
||||
VCPKG_BINARY_SOURCES: 'nuget,gitlab,readwrite'
|
||||
# Switch the compressor to fastzip and reduce the compression level
|
||||
FF_USE_FASTZIP: "true"
|
||||
CACHE_COMPRESSION_LEVEL: "fast"
|
||||
@@ -23,6 +24,7 @@ win64_build:
|
||||
script:
|
||||
- C:\builder\build.ps1 -Env -Arch x64
|
||||
- $vcpkgCache=Join-Path -Path (Get-Location) -ChildPath ".vcpkgCache";$env:VCPKG_DEFAULT_BINARY_CACHE=$vcpkgCache;New-Item -ItemType Directory -Force -Path $vcpkgCache
|
||||
- nuget.exe sources add -Name gitlab -Source "https://gitlab.com/api/v4/projects/27426693/packages/nuget/index.json" -UserName gitlab-ci-token -Password $env:CI_JOB_TOKEN
|
||||
- mkdir -p build/windows -Force
|
||||
- cd build/windows
|
||||
- cmake `
|
||||
@@ -34,6 +36,8 @@ win64_build:
|
||||
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON `
|
||||
-DKICAD_USE_3DCONNEXION=ON `
|
||||
-DVCPKG_BUILD_TYPE=debug `
|
||||
-DVCPKG_INSTALL_OPTIONS="--x-abi-tools-use-exact-versions" `
|
||||
-DVCPKG_OVERLAY_TRIPLETS="$Env:CI_PROJECT_DIR/tools/custom_vcpkg_triplets" `
|
||||
../../
|
||||
- cmake --build . 2>&1 | tee compilation_log.txt
|
||||
- cd ../../
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
build_doxygen_docker:
|
||||
image: docker:stable
|
||||
image: docker:24.0.5-cli
|
||||
services:
|
||||
- docker:dind
|
||||
- docker:24.0.5-dind
|
||||
stage: build
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_JOB_NAME == "doxygen"
|
||||
|
||||
@@ -486,9 +486,12 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
|
||||
// Initialize ray packets
|
||||
const SFVEC2UI& blockPos = m_blockPositions[iBlock];
|
||||
const SFVEC2I blockPosI = SFVEC2I( blockPos.x + m_xoffset, blockPos.y + m_yoffset );
|
||||
const SFVEC2F randDisp = ( m_camera.GetProjection() == PROJECTION_TYPE::ORTHO ) ?
|
||||
SFVEC2F( 0.0f, 0.0f ) :
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR );
|
||||
|
||||
RAYPACKET blockPacket( m_camera, (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, DISP_FACTOR ),
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR ) /* Displacement random factor */ );
|
||||
RAYPACKET blockPacket( m_camera, (SFVEC2F) blockPosI + randDisp,
|
||||
randDisp /* Displacement random factor */ );
|
||||
|
||||
|
||||
HITINFO_PACKET hitPacket_X0Y0[RAYPACKET_RAYS_PER_PACKET];
|
||||
@@ -566,7 +569,7 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
|
||||
HITINFO_PACKET_init( hitPacket_AA_X1Y1 );
|
||||
|
||||
RAYPACKET blockPacket_AA_X1Y1( m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f, 0.5f ),
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR ) );
|
||||
randDisp );
|
||||
|
||||
if( !m_accelerator->Intersect( blockPacket_AA_X1Y1, hitPacket_AA_X1Y1 ) )
|
||||
{
|
||||
@@ -603,16 +606,16 @@ void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( uint8_t* ptrPBO, signed int iB
|
||||
RAY blockRayPck_AA_X1Y1_half[RAYPACKET_RAYS_PER_PACKET];
|
||||
|
||||
RAYPACKET_InitRays_with2DDisplacement(
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f - DISP_FACTOR, DISP_FACTOR ),
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y0 );
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.5f - randDisp.x, randDisp.y ),
|
||||
randDisp, blockRayPck_AA_X1Y0 );
|
||||
|
||||
RAYPACKET_InitRays_with2DDisplacement(
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, 0.5f - DISP_FACTOR ),
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X0Y1 );
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( randDisp.x, 0.5f - randDisp.y ),
|
||||
randDisp, blockRayPck_AA_X0Y1 );
|
||||
|
||||
RAYPACKET_InitRays_with2DDisplacement(
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR ),
|
||||
SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y1_half );
|
||||
m_camera, (SFVEC2F) blockPosI + SFVEC2F( 0.25f - randDisp.x, 0.25f - randDisp.y ),
|
||||
randDisp, blockRayPck_AA_X1Y1_half );
|
||||
|
||||
renderAntiAliasPackets( bgColor, hitPacket_X0Y0, hitPacket_AA_X1Y1, blockRayPck_AA_X1Y0,
|
||||
hitColor_AA_X1Y0 );
|
||||
|
||||
@@ -202,6 +202,10 @@ EDA_3D_VIEWER_FRAME::EDA_3D_VIEWER_FRAME( KIWAY* aKiway, PCB_BASE_FRAME* aParent
|
||||
|
||||
EDA_3D_VIEWER_FRAME::~EDA_3D_VIEWER_FRAME()
|
||||
{
|
||||
// Shutdown all running tools
|
||||
if( m_toolManager )
|
||||
m_toolManager->ShutdownAllTools();
|
||||
|
||||
Prj().GetProjectFile().m_Viewports3D = m_appearancePanel->GetUserViewports();
|
||||
|
||||
m_canvas->SetEventDispatcher( nullptr );
|
||||
|
||||
@@ -185,6 +185,10 @@ PANEL_PREVIEW_3D_MODEL::PANEL_PREVIEW_3D_MODEL( wxWindow* aParent, PCB_BASE_FRAM
|
||||
|
||||
PANEL_PREVIEW_3D_MODEL::~PANEL_PREVIEW_3D_MODEL()
|
||||
{
|
||||
// Shutdown all running tools
|
||||
if( m_toolManager )
|
||||
m_toolManager->ShutdownAllTools();
|
||||
|
||||
// Restore the 3D viewer Render settings, that can be modified by the panel tools
|
||||
if( m_boardAdapter.m_Cfg )
|
||||
m_boardAdapter.m_Cfg->m_Render = m_initialRender;
|
||||
@@ -657,6 +661,12 @@ void PANEL_PREVIEW_3D_MODEL::UpdateDummyFootprint( bool aReloadRequired )
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::SetEmbeddedFilesDelegate( EMBEDDED_FILES* aDelegate )
|
||||
{
|
||||
m_dummyBoard->SetEmbeddedFilesDelegate( aDelegate );
|
||||
}
|
||||
|
||||
|
||||
void PANEL_PREVIEW_3D_MODEL::onModify()
|
||||
{
|
||||
KIWAY_HOLDER* kiwayHolder = dynamic_cast<KIWAY_HOLDER*>( wxGetTopLevelParent( this ) );
|
||||
|
||||
@@ -59,6 +59,7 @@ wxDECLARE_EVENT( wxCUSTOM_PANEL_SHOWN_EVENT, wxCommandEvent );
|
||||
class WX_INFOBAR;
|
||||
class S3D_CACHE;
|
||||
class FILENAME_RESOLVER;
|
||||
class EMBEDDED_FILES;
|
||||
class BOARD;
|
||||
class BOARD_ADAPTER;
|
||||
class FOOTPRINT;
|
||||
@@ -97,6 +98,8 @@ public:
|
||||
*/
|
||||
void UpdateDummyFootprint( bool aRelaodRequired = true );
|
||||
|
||||
void SetEmbeddedFilesDelegate( EMBEDDED_FILES* aDelegate );
|
||||
|
||||
/**
|
||||
* Get the dummy footprint that is used for previewing the 3D model.
|
||||
* We use this to hold the temporary 3D model shapes.
|
||||
|
||||
+6
-1
@@ -22,7 +22,12 @@
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
#
|
||||
|
||||
cmake_minimum_required( VERSION 3.21 FATAL_ERROR )
|
||||
if( MSVC )
|
||||
# CMake 3.28.1 or higher required for MSVC ARM builds for armasm64.exe support
|
||||
cmake_minimum_required( VERSION 3.28.1 FATAL_ERROR )
|
||||
else()
|
||||
cmake_minimum_required( VERSION 3.21 FATAL_ERROR )
|
||||
endif()
|
||||
|
||||
# Generate DEPFILES without transforming relative paths
|
||||
cmake_policy( SET CMP0116 OLD )
|
||||
|
||||
@@ -6,7 +6,12 @@
|
||||
},
|
||||
{
|
||||
"environment": "vcpkg",
|
||||
"VcPkgDir": "D:/vcpkg/"
|
||||
"VcPkgDir": "D:/vcpkg/",
|
||||
"VCPKG_BINARY_SOURCES": "nuget,kicad-gitlab,read"
|
||||
},
|
||||
{
|
||||
"environment": "swig",
|
||||
"SwigExePath": "D:/swigwin-4.1.1/swig.exe"
|
||||
}
|
||||
],
|
||||
"configurations": [
|
||||
@@ -14,7 +19,7 @@
|
||||
"name": "x64-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg" ],
|
||||
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg", "swig"],
|
||||
"buildRoot": "${env.BuildDir}\\${name}",
|
||||
"installRoot": "${env.InstallDir}\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
@@ -30,6 +35,21 @@
|
||||
"name": "KICAD_WIN32_DPI_AWARE",
|
||||
"value": "ON",
|
||||
"type": "BOOL"
|
||||
},
|
||||
{
|
||||
"name": "SWIG_EXECUTABLE",
|
||||
"value": "${env.SwigExePath}",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "VCPKG_OVERLAY_TRIPLETS",
|
||||
"value": "${workspaceRoot}/tools/custom_vcpkg_triplets",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "VCPKG_INSTALL_OPTIONS",
|
||||
"value": "--x-abi-tools-use-exact-versions",
|
||||
"type": "STRING"
|
||||
}
|
||||
],
|
||||
"cmakeToolchain": "${env.VcPkgDir}/scripts/buildsystems/vcpkg.cmake"
|
||||
@@ -38,7 +58,7 @@
|
||||
"name": "x64-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg" ],
|
||||
"inheritEnvironments": [ "msvc_x64_x64", "vcpkg", "swig"],
|
||||
"buildRoot": "${env.BuildDir}\\${name}",
|
||||
"installRoot": "${env.InstallDir}\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
@@ -54,6 +74,21 @@
|
||||
"name": "KICAD_WIN32_DPI_AWARE",
|
||||
"value": "ON",
|
||||
"type": "BOOL"
|
||||
},
|
||||
{
|
||||
"name": "SWIG_EXECUTABLE",
|
||||
"value": "${env.SwigExePath}",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "VCPKG_OVERLAY_TRIPLETS",
|
||||
"value": "${workspaceRoot}/tools/custom_vcpkg_triplets",
|
||||
"type": "STRING"
|
||||
},
|
||||
{
|
||||
"name": "VCPKG_INSTALL_OPTIONS",
|
||||
"value": "--x-abi-tools-use-exact-versions",
|
||||
"type": "STRING"
|
||||
}
|
||||
],
|
||||
"cmakeToolchain": "${env.VcPkgDir}/scripts/buildsystems/vcpkg.cmake"
|
||||
|
||||
@@ -42,12 +42,45 @@ message BoardStackupResponse
|
||||
kiapi.board.BoardStackup stackup = 1;
|
||||
}
|
||||
|
||||
// Changes the stackup for the given board according to the contents of the message (**not yet implemented**)
|
||||
// WARNING: any existing content on layers that are removed by this call is deleted. This operation cannot be undone.
|
||||
// Returns BoardStackupResponse with the updated stackup, in normalized form
|
||||
message UpdateBoardStackup
|
||||
{
|
||||
kiapi.common.types.DocumentSpecifier board = 1;
|
||||
kiapi.board.BoardStackup stackup = 2;
|
||||
}
|
||||
|
||||
message GetBoardEnabledLayers
|
||||
{
|
||||
kiapi.common.types.DocumentSpecifier board = 1;
|
||||
}
|
||||
|
||||
message BoardEnabledLayersResponse
|
||||
{
|
||||
// The number of copper layers enabled in this board.
|
||||
uint32 copper_layer_count = 1;
|
||||
|
||||
// A list of all layers enabled in this board, including copper layers and ones which cannot be disabled.
|
||||
repeated kiapi.board.types.BoardLayer layers = 2;
|
||||
}
|
||||
|
||||
// Changes which layers are enabled in the board stackup
|
||||
// WARNING: any existing content on layers that are removed by this call is deleted. This operation cannot be undone.
|
||||
// Returns BoardEnabledLayersResponse with the updated layer set.
|
||||
message SetBoardEnabledLayers
|
||||
{
|
||||
kiapi.common.types.DocumentSpecifier board = 1;
|
||||
|
||||
// The number of copper layers to enable in the board. Currently, this must be an even number >= 2.
|
||||
uint32 copper_layer_count = 2;
|
||||
|
||||
// The non-copper layers to enable. Note that any copper layers in this list are ignored; copper layers are enabled
|
||||
// by setting copper_layer_count. Note that the F/B.Courtyard, Edge.Cuts, and Margin layers cannot be disabled and
|
||||
// will be present in the board even if they are omitted from this list.
|
||||
repeated kiapi.board.types.BoardLayer layers = 3;
|
||||
}
|
||||
|
||||
message GetGraphicsDefaults
|
||||
{
|
||||
kiapi.common.types.DocumentSpecifier board = 1;
|
||||
|
||||
@@ -464,6 +464,18 @@ message ThermalSpokeSettings
|
||||
kiapi.common.types.Distance gap = 3;
|
||||
}
|
||||
|
||||
message SymbolPinInfo
|
||||
{
|
||||
// The pin name for the associated symbol pin, if one exists
|
||||
string name = 1;
|
||||
|
||||
// The electrical type of the associated symbol pin, if one exists (EPT_UNKNOWN if not)
|
||||
kiapi.common.types.ElectricalPinType type = 2;
|
||||
|
||||
// True if the pin is attached to a no-connect marker in the schematic
|
||||
bool no_connect = 3;
|
||||
}
|
||||
|
||||
message Pad
|
||||
{
|
||||
kiapi.common.types.KIID id = 1;
|
||||
@@ -481,6 +493,10 @@ message Pad
|
||||
|
||||
// Since: 9.0.4
|
||||
kiapi.common.types.Distance pad_to_die_length = 9;
|
||||
|
||||
// Information about the associated symbol pin, if one exists
|
||||
// Since: 9.0.7
|
||||
SymbolPinInfo symbol_pin = 10;
|
||||
}
|
||||
|
||||
enum ZoneType
|
||||
@@ -830,6 +846,9 @@ message FootprintAttributes
|
||||
bool exempt_from_courtyard_requirement = 6;
|
||||
bool do_not_populate = 7;
|
||||
FootprintMountingStyle mounting_style = 8;
|
||||
|
||||
// Since: 9.0.7
|
||||
bool allow_soldermask_bridges = 9;
|
||||
}
|
||||
|
||||
message NetTieDefinition
|
||||
@@ -902,4 +921,19 @@ message FootprintInstance
|
||||
|
||||
// The sheet path to the associated symbol for this footprint instance, if one exists
|
||||
kiapi.common.types.SheetPath symbol_path = 13;
|
||||
|
||||
// The name of the hierarchical sheet the associated symbol for this footprint exists on,
|
||||
// or the empty string if there is no associated symbol
|
||||
// Since: 9.0.7
|
||||
string symbol_sheet_name = 14;
|
||||
|
||||
// The filename of the hierarchical sheet the associated symbol for this footprint exists on,
|
||||
// or the empty string if there is no associated symbol
|
||||
// Since: 9.0.7
|
||||
string symbol_sheet_filename = 15;
|
||||
|
||||
// The the footprint filters given by the symbol this footprint is associated with,
|
||||
// or the empty string if there is no associated symbol
|
||||
// Since: 9.0.7
|
||||
string symbol_footprint_filters = 16;
|
||||
}
|
||||
|
||||
@@ -451,3 +451,25 @@ enum MapMergeMode
|
||||
// The existing map will be cleared and replaced with the incoming map
|
||||
MMM_REPLACE = 2;
|
||||
}
|
||||
|
||||
enum ElectricalPinType
|
||||
{
|
||||
EPT_UNKNOWN = 0;
|
||||
EPT_INPUT = 1;
|
||||
EPT_OUTPUT = 2;
|
||||
EPT_BIDIRECTIONAL = 3;
|
||||
EPT_TRISTATE = 4;
|
||||
EPT_PASSIVE = 5;
|
||||
|
||||
// A free pin is not internally connected and may connect to any net (route-through)
|
||||
EPT_FREE = 6;
|
||||
|
||||
EPT_UNSPECIFIED = 7;
|
||||
EPT_POWER_INPUT = 8;
|
||||
EPT_POWER_OUTPUT = 9;
|
||||
EPT_OPEN_COLLECTOR = 10;
|
||||
EPT_OPEN_EMITTER = 11;
|
||||
|
||||
// A no-connect pin should not be connected to any net
|
||||
EPT_NO_CONNECT = 12;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,12 @@ BITMAP2CMP_FRAME::BITMAP2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
|
||||
BITMAP2CMP_FRAME::~BITMAP2CMP_FRAME()
|
||||
{
|
||||
// Shutdown all running tools
|
||||
if( m_toolManager )
|
||||
m_toolManager->ShutdownAllTools();
|
||||
|
||||
SaveSettings( config() );
|
||||
|
||||
/*
|
||||
* This needed for OSX: avoids further OnDraw processing after this
|
||||
* destructor and before the native window is destroyed
|
||||
|
||||
@@ -36,7 +36,13 @@ if( MSVC )
|
||||
set( KICAD_HOST_ARCH "x64" )
|
||||
set( KICAD_HOST_ARCH_X64 1 )
|
||||
else()
|
||||
message(FATAL_ERROR "Failed to determine the host architecture: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
message(FATAL_ERROR "Failed to determine the host architecture: ${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
if( NOT KICAD_BUILD_ARCH STREQUAL KICAD_HOST_ARCH )
|
||||
set( CMAKE_CROSSCOMPILING TRUE )
|
||||
|
||||
string(TOUPPER ${KICAD_BUILD_ARCH} CMAKE_SYSTEM_PROCESSOR)
|
||||
endif()
|
||||
else()
|
||||
if ( NOT CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
@@ -58,38 +64,18 @@ if( MSVC )
|
||||
# cmake release AND when MSVC ships said cmake release
|
||||
if(KICAD_BUILD_ARCH_ARM)
|
||||
message( "Configuring ARM assembler" )
|
||||
# Explicitly specify the assembler to be used for Arm32 compile
|
||||
file(TO_CMAKE_PATH "$ENV{VCToolsInstallDir}\\bin\\HostX86\\arm\\armasm.exe" CMAKE_ASM_COMPILER)
|
||||
|
||||
set(CMAKE_ASM_MASM_COMPILER ${CMAKE_ASM_COMPILER})
|
||||
message("CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER}")
|
||||
|
||||
# Enable generic assembly compilation to avoid CMake generate VS proj files that explicitly
|
||||
# use ml[64].exe as the assembler.
|
||||
enable_language(ASM)
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
|
||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -g <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
|
||||
|
||||
enable_language(ASM_MARMASM)
|
||||
# Bugfix for CMake < 29.1
|
||||
set(ASM_DIALECT "_MARMASM")
|
||||
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
|
||||
elseif(KICAD_BUILD_ARCH_ARM64)
|
||||
message( "Configuring ARM64 assembler" )
|
||||
|
||||
# Explicitly specify the assembler to be used for Arm64 compile
|
||||
file(TO_CMAKE_PATH "$ENV{VCToolsInstallDir}\\bin\\HostX86\\arm64\\armasm64.exe" CMAKE_ASM_COMPILER)
|
||||
|
||||
set(CMAKE_ASM_MASM_COMPILER ${CMAKE_ASM_COMPILER})
|
||||
message("CMAKE_ASM_MASM_COMPILER explicitly set to: ${CMAKE_ASM_MASM_COMPILER}")
|
||||
|
||||
# Enable generic assembly compilation to avoid CMake generate VS proj files that explicitly
|
||||
# use ml[64].exe as the assembler.
|
||||
enable_language(ASM)
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "")
|
||||
set(CMAKE_ASM_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "")
|
||||
set(CMAKE_ASM_COMPILE_OBJECT "<CMAKE_ASM_COMPILER> -g <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
|
||||
enable_language(ASM_MARMASM)
|
||||
# Bugfix for CMake < 29.1
|
||||
set(ASM_DIALECT "_MARMASM")
|
||||
set(CMAKE_ASM${ASM_DIALECT}_COMPILE_OBJECT "<CMAKE_ASM${ASM_DIALECT}_COMPILER> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")
|
||||
else()
|
||||
message( "Configuring MASM assembler" )
|
||||
if(KICAD_BUILD_ARCH_X86)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# This program source code file is part of KICAD, a free EDA CAD application.
|
||||
#
|
||||
# Copyright (C) 2016 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
# Copyright (C) 2016-2023, 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
# Copyright (C) 2016-2023, 2024, 2025 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
|
||||
@@ -37,7 +37,7 @@
|
||||
# KiCad.
|
||||
#
|
||||
# Note: This version string should follow the semantic versioning system
|
||||
set( KICAD_SEMANTIC_VERSION "9.0.4" )
|
||||
set( KICAD_SEMANTIC_VERSION "9.0.7" )
|
||||
|
||||
# Default the version to the semantic version.
|
||||
# This is overridden by the git repository tag though (if using git)
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# compile_asm(TARGET target ASM_FILES file1 [file2 ...] OUTPUT_OBJECTS [variableName])
|
||||
# CMake does not support the ARM or ARM64 assemblers on Windows when using the
|
||||
# MSBuild generator. When the MSBuild generator is in use, we manually compile the assembly files
|
||||
# using this function.
|
||||
#
|
||||
# Borrowed from dotnet/runtime, licensed under MIT
|
||||
# Copyright (c) .NET Foundation and Contributors
|
||||
# https://github.com/dotnet/runtime/blob/main/eng/native/functions.cmake
|
||||
function(compile_asm)
|
||||
set(options "")
|
||||
set(oneValueArgs TARGET OUTPUT_OBJECTS)
|
||||
set(multiValueArgs ASM_FILES)
|
||||
cmake_parse_arguments(COMPILE_ASM "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGV})
|
||||
|
||||
get_include_directories_asm(ASM_INCLUDE_DIRECTORIES)
|
||||
|
||||
set (ASSEMBLED_OBJECTS "")
|
||||
|
||||
foreach(ASM_FILE ${COMPILE_ASM_ASM_FILES})
|
||||
get_filename_component(name ${ASM_FILE} NAME_WE)
|
||||
# Produce object file where CMake would store .obj files for an OBJECT library.
|
||||
# ex: artifacts\obj\coreclr\windows.arm64.Debug\src\vm\wks\cee_wks.dir\Debug\AsmHelpers.obj
|
||||
set (OBJ_FILE "${CMAKE_CURRENT_BINARY_DIR}/${COMPILE_ASM_TARGET}.dir/${CMAKE_CFG_INTDIR}/${name}.obj")
|
||||
|
||||
# Need to compile asm file using custom command as include directories are not provided to asm compiler
|
||||
add_custom_command(OUTPUT ${OBJ_FILE}
|
||||
COMMAND "${CMAKE_ASM_COMPILER}" -g ${ASM_INCLUDE_DIRECTORIES} -o ${OBJ_FILE} ${ASM_FILE}
|
||||
DEPENDS ${ASM_FILE}
|
||||
COMMENT "Assembling ${ASM_FILE} ---> \"${CMAKE_ASM_COMPILER}\" -g ${ASM_INCLUDE_DIRECTORIES} -o ${OBJ_FILE} ${ASM_FILE}")
|
||||
|
||||
# mark obj as source that does not require compile
|
||||
set_source_files_properties(${OBJ_FILE} PROPERTIES EXTERNAL_OBJECT TRUE)
|
||||
|
||||
# Add the generated OBJ in the dependency list so that it gets consumed during linkage
|
||||
list(APPEND ASSEMBLED_OBJECTS ${OBJ_FILE})
|
||||
endforeach()
|
||||
|
||||
set(${COMPILE_ASM_OUTPUT_OBJECTS} ${ASSEMBLED_OBJECTS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
# Build a list of include directories for consumption by the assembler
|
||||
function(get_include_directories_asm IncludeDirectories)
|
||||
get_directory_property(dirs INCLUDE_DIRECTORIES)
|
||||
|
||||
foreach(dir IN LISTS dirs)
|
||||
list(APPEND INC_DIRECTORIES -I${dir};)
|
||||
endforeach()
|
||||
|
||||
set(${IncludeDirectories} ${INC_DIRECTORIES} PARENT_SCOPE)
|
||||
endfunction(get_include_directories_asm)
|
||||
@@ -102,6 +102,7 @@ static const wxChar EnableDesignBlocks[] = wxT( "EnableDesignBlocks" );
|
||||
static const wxChar EnableGenerators[] = wxT( "EnableGenerators" );
|
||||
static const wxChar EnableLibWithText[] = wxT( "EnableLibWithText" );
|
||||
static const wxChar EnableLibDir[] = wxT( "EnableLibDir" );
|
||||
static const wxChar LibraryTableEditor[] = wxT( "LibraryTableEditor" );
|
||||
static const wxChar EnableEeschemaPrintCairo[] = wxT( "EnableEeschemaPrintCairo" );
|
||||
static const wxChar EnableEeschemaExportClipboardCairo[] = wxT( "EnableEeschemaExportClipboardCairo" );
|
||||
static const wxChar DisambiguationTime[] = wxT( "DisambiguationTime" );
|
||||
@@ -120,6 +121,8 @@ static const wxChar EnableExtensionSnaps[] = wxT( "EnableExtensionSnaps" );
|
||||
static const wxChar ExtensionSnapTimeoutMs[] = wxT( "ExtensionSnapTimeoutMs" );
|
||||
static const wxChar ExtensionSnapActivateOnHover[] = wxT( "ExtensionSnapActivateOnHover" );
|
||||
static const wxChar EnableSnapAnchorsDebug[] = wxT( "EnableSnapAnchorsDebug" );
|
||||
static const wxChar SnapHysteresis[] = wxT( "SnapHysteresis" );
|
||||
static const wxChar SnapToAnchorMargin[] = wxT( "SnapToAnchorMargin" );
|
||||
static const wxChar MinParallelAngle[] = wxT( "MinParallelAngle" );
|
||||
static const wxChar HoleWallPaintingMultiplier[] = wxT( "HoleWallPaintingMultiplier" );
|
||||
static const wxChar MsgPanelShowUuids[] = wxT( "MsgPanelShowUuids" );
|
||||
@@ -262,6 +265,7 @@ ADVANCED_CFG::ADVANCED_CFG()
|
||||
m_EnableGenerators = false;
|
||||
m_EnableLibWithText = false;
|
||||
m_EnableLibDir = false;
|
||||
m_LibraryTableEditor = false;
|
||||
|
||||
m_EnableEeschemaPrintCairo = true;
|
||||
m_EnableEeschemaExportClipboardCairo = true;
|
||||
@@ -299,6 +303,8 @@ ADVANCED_CFG::ADVANCED_CFG()
|
||||
m_ExtensionSnapTimeoutMs = 500;
|
||||
m_ExtensionSnapActivateOnHover = true;
|
||||
m_EnableSnapAnchorsDebug = false;
|
||||
m_SnapHysteresis = 5;
|
||||
m_SnapToAnchorMargin = 1.1;
|
||||
|
||||
m_MinParallelAngle = 0.001;
|
||||
m_HoleWallPaintingMultiplier = 1.5;
|
||||
@@ -512,6 +518,9 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableLibDir,
|
||||
&m_EnableLibDir, m_EnableLibDir ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::LibraryTableEditor,
|
||||
&m_LibraryTableEditor, m_LibraryTableEditor ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableEeschemaPrintCairo,
|
||||
&m_EnableEeschemaPrintCairo,
|
||||
m_EnableEeschemaPrintCairo ) );
|
||||
@@ -577,6 +586,14 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
|
||||
&m_EnableSnapAnchorsDebug,
|
||||
m_EnableSnapAnchorsDebug ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::SnapHysteresis,
|
||||
&m_SnapHysteresis, m_SnapHysteresis,
|
||||
0, 100 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::SnapToAnchorMargin,
|
||||
&m_SnapToAnchorMargin, m_SnapToAnchorMargin,
|
||||
1.0, 2.0 ) );
|
||||
|
||||
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::MinParallelAngle,
|
||||
&m_MinParallelAngle, m_MinParallelAngle,
|
||||
0.0, 45.0 ) );
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <core/typeinfo.h>
|
||||
#include <font/text_attributes.h>
|
||||
#include <layer_ids.h>
|
||||
#include <pin_type.h>
|
||||
#include <stroke_params.h>
|
||||
|
||||
using namespace kiapi;
|
||||
@@ -498,3 +499,54 @@ types::StrokeLineStyle ToProtoEnum( LINE_STYLE aValue )
|
||||
"Unhandled case in ToProtoEnum<LINE_STYLE>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
ELECTRICAL_PINTYPE FromProtoEnum( types::ElectricalPinType aValue )
|
||||
{
|
||||
switch( aValue )
|
||||
{
|
||||
case types::ElectricalPinType::EPT_INPUT: return ELECTRICAL_PINTYPE::PT_INPUT;
|
||||
case types::ElectricalPinType::EPT_OUTPUT: return ELECTRICAL_PINTYPE::PT_OUTPUT;
|
||||
case types::ElectricalPinType::EPT_BIDIRECTIONAL: return ELECTRICAL_PINTYPE::PT_BIDI;
|
||||
case types::ElectricalPinType::EPT_TRISTATE: return ELECTRICAL_PINTYPE::PT_TRISTATE;
|
||||
case types::ElectricalPinType::EPT_PASSIVE: return ELECTRICAL_PINTYPE::PT_PASSIVE;
|
||||
case types::ElectricalPinType::EPT_FREE: return ELECTRICAL_PINTYPE::PT_NIC;
|
||||
case types::ElectricalPinType::EPT_UNSPECIFIED: return ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
|
||||
case types::ElectricalPinType::EPT_POWER_INPUT: return ELECTRICAL_PINTYPE::PT_POWER_IN;
|
||||
case types::ElectricalPinType::EPT_POWER_OUTPUT: return ELECTRICAL_PINTYPE::PT_POWER_OUT;
|
||||
case types::ElectricalPinType::EPT_OPEN_COLLECTOR: return ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR;
|
||||
case types::ElectricalPinType::EPT_OPEN_EMITTER: return ELECTRICAL_PINTYPE::PT_OPENEMITTER;
|
||||
case types::ElectricalPinType::EPT_NO_CONNECT: return ELECTRICAL_PINTYPE::PT_NC;
|
||||
case types::ElectricalPinType::EPT_UNKNOWN:
|
||||
default:
|
||||
wxCHECK_MSG( false, ELECTRICAL_PINTYPE::PT_UNSPECIFIED,
|
||||
"Unhandled case in FromProtoEnum<types::ElectricalPinType>" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
types::ElectricalPinType ToProtoEnum( ELECTRICAL_PINTYPE aValue )
|
||||
{
|
||||
switch( aValue )
|
||||
{
|
||||
case ELECTRICAL_PINTYPE::PT_INPUT: return types::ElectricalPinType::EPT_INPUT;
|
||||
case ELECTRICAL_PINTYPE::PT_OUTPUT: return types::ElectricalPinType::EPT_OUTPUT;
|
||||
case ELECTRICAL_PINTYPE::PT_BIDI: return types::ElectricalPinType::EPT_BIDIRECTIONAL;
|
||||
case ELECTRICAL_PINTYPE::PT_TRISTATE: return types::ElectricalPinType::EPT_TRISTATE;
|
||||
case ELECTRICAL_PINTYPE::PT_PASSIVE: return types::ElectricalPinType::EPT_PASSIVE;
|
||||
case ELECTRICAL_PINTYPE::PT_NIC: return types::ElectricalPinType::EPT_FREE;
|
||||
case ELECTRICAL_PINTYPE::PT_UNSPECIFIED: return types::ElectricalPinType::EPT_UNSPECIFIED;
|
||||
case ELECTRICAL_PINTYPE::PT_POWER_IN: return types::ElectricalPinType::EPT_POWER_INPUT;
|
||||
case ELECTRICAL_PINTYPE::PT_POWER_OUT: return types::ElectricalPinType::EPT_POWER_OUTPUT;
|
||||
case ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR: return types::ElectricalPinType::EPT_OPEN_COLLECTOR;
|
||||
case ELECTRICAL_PINTYPE::PT_OPENEMITTER: return types::ElectricalPinType::EPT_OPEN_EMITTER;
|
||||
case ELECTRICAL_PINTYPE::PT_NC: return types::ElectricalPinType::EPT_NO_CONNECT;
|
||||
// Inherit shouldn't be serialized, it's an internal flag
|
||||
case ELECTRICAL_PINTYPE::PT_INHERIT:
|
||||
default:
|
||||
wxCHECK_MSG( false, types::ElectricalPinType::EPT_UNKNOWN,
|
||||
"Unhandled case in ToProtoEnum<ELECTRICAL_PINTYPE>");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,4 +241,14 @@ KICOMMON_API void PackSheetPath( types::SheetPath& aOutput, const KIID_PATH& aIn
|
||||
aOutput.add_path()->set_value( entry.AsStdString() );
|
||||
}
|
||||
|
||||
KICOMMON_API KIID_PATH UnpackSheetPath( const types::SheetPath& aInput )
|
||||
{
|
||||
KIID_PATH output;
|
||||
|
||||
for( const types::KIID& sheet : aInput.path() )
|
||||
output.push_back( KIID( sheet.value() ) );
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
} // namespace kiapi::common
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "clipboard.h"
|
||||
|
||||
#include <wx/clipbrd.h>
|
||||
#include <wx/dataobj.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
@@ -84,10 +85,10 @@ std::unique_ptr<wxImage> GetImageFromClipboard()
|
||||
{
|
||||
if( wxTheClipboard->IsSupported( wxDF_BITMAP ) )
|
||||
{
|
||||
wxImageDataObject data;
|
||||
wxBitmapDataObject data;
|
||||
if( wxTheClipboard->GetData( data ) )
|
||||
{
|
||||
image = std::make_unique<wxImage>( data.GetImage() );
|
||||
image = std::make_unique<wxImage>( data.GetBitmap().ConvertToImage() );
|
||||
}
|
||||
}
|
||||
else if( wxTheClipboard->IsSupported( wxDF_FILENAME ) )
|
||||
|
||||
@@ -161,7 +161,7 @@ bool DATABASE_CONNECTION::Connect()
|
||||
m_conn = std::make_unique<nanodbc::connection>( cs, m_timeout );
|
||||
}
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
return false;
|
||||
@@ -188,7 +188,7 @@ bool DATABASE_CONNECTION::Disconnect()
|
||||
{
|
||||
m_conn->disconnect();
|
||||
}
|
||||
catch( boost::locale::conv::conversion_error& exc )
|
||||
catch( std::exception& exc )
|
||||
{
|
||||
wxLogTrace( traceDatabase, wxT( "Disconnect() error \"%s\" occured." ), exc.what() );
|
||||
return false;
|
||||
@@ -250,7 +250,7 @@ bool DATABASE_CONNECTION::CacheTableInfo( const std::string& aTable,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while caching table info: %s" ), m_lastError );
|
||||
@@ -277,8 +277,9 @@ bool DATABASE_CONNECTION::getQuoteChar()
|
||||
|
||||
wxLogTrace( traceDatabase, wxT( "Quote char retrieved: %c" ), m_quoteChar );
|
||||
}
|
||||
catch( nanodbc::database_error& )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while querying quote char: %s" ), m_lastError );
|
||||
return false;
|
||||
}
|
||||
@@ -401,14 +402,14 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
statement.prepare( *m_conn, query );
|
||||
statement.bind( 0, aWhere.second.c_str() );
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while preparing statement for SelectOne: %s" ),
|
||||
m_lastError );
|
||||
|
||||
// Exception may be due to a connection error; nanodbc won't auto-reconnect
|
||||
m_conn->disconnect();
|
||||
Disconnect();
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -422,14 +423,14 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
{
|
||||
results = nanodbc::execute( statement );
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while executing statement for SelectOne: %s" ),
|
||||
m_lastError );
|
||||
|
||||
// Exception may be due to a connection error; nanodbc won't auto-reconnect
|
||||
m_conn->disconnect();
|
||||
Disconnect();
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -480,7 +481,7 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase, wxT( "Exception while parsing results from SelectOne: %s" ),
|
||||
@@ -507,7 +508,7 @@ bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const st
|
||||
{
|
||||
statement.prepare( query );
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase,
|
||||
@@ -515,7 +516,7 @@ bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const st
|
||||
m_lastError );
|
||||
|
||||
// Exception may be due to a connection error; nanodbc won't auto-reconnect
|
||||
m_conn->disconnect();
|
||||
Disconnect();
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -526,7 +527,7 @@ bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const st
|
||||
{
|
||||
results = nanodbc::execute( statement );
|
||||
}
|
||||
catch( nanodbc::database_error& e )
|
||||
catch( std::exception& e )
|
||||
{
|
||||
m_lastError = e.what();
|
||||
wxLogTrace( traceDatabase,
|
||||
@@ -534,7 +535,7 @@ bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const st
|
||||
m_lastError );
|
||||
|
||||
// Exception may be due to a connection error; nanodbc won't auto-reconnect
|
||||
m_conn->disconnect();
|
||||
Disconnect();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -631,7 +631,8 @@ bool DESIGN_BLOCK_LIB_TABLE::LoadGlobalTable( DESIGN_BLOCK_LIB_TABLE& aTable )
|
||||
{
|
||||
tableExists = false;
|
||||
|
||||
if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
|
||||
if( !wxFileName::DirExists( fn.GetPath() )
|
||||
&& !wxFileName::Mkdir( fn.GetPath(), 0x777, wxPATH_MKDIR_FULL ) )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
|
||||
fn.GetPath() ) );
|
||||
|
||||
@@ -909,7 +909,13 @@ static void buildKicadAboutBanner( EDA_BASE_FRAME* aParent, ABOUT_APP_INFO& aInf
|
||||
#define FOOTPRINT_LIB_CONTRIBUTION _( "Footprints" )
|
||||
aInfo.AddLibrarian( new CONTRIBUTOR( wxS( "Scripts by Maui" ),
|
||||
MODELS_3D_CONTRIBUTION,
|
||||
wxS( "https://gitlab.com/kicad/libraries/kicad-footprint-generator" ) ) );
|
||||
wxS( "https://github.com/easyw" ) ) );
|
||||
aInfo.AddLibrarian( new CONTRIBUTOR( wxS( "Hasan Yavuz Özderya" ),
|
||||
MODELS_3D_CONTRIBUTION,
|
||||
wxS( "https://bitbucket.org/hyOzd/freecad-macros/src/master/" ) ) );
|
||||
aInfo.AddLibrarian( new CONTRIBUTOR( wxS( "GitHub contributors" ),
|
||||
MODELS_3D_CONTRIBUTION,
|
||||
wxS( "https://github.com/easyw/kicad-3d-models-in-freecad/graphs/contributors" ) ) );
|
||||
aInfo.AddLibrarian( new CONTRIBUTOR( wxS( "GitLab contributors" ),
|
||||
MODELS_3D_CONTRIBUTION,
|
||||
wxS( "https://gitlab.com/kicad/libraries/kicad-packages3D/-/graphs/master" ) ) );
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
|
||||
#include <build_version.h>
|
||||
#include <eda_base_frame.h>
|
||||
#include <wx/clipbrd.h>
|
||||
@@ -108,8 +107,20 @@ DIALOG_ABOUT::DIALOG_ABOUT( EDA_BASE_FRAME *aParent, ABOUT_APP_INFO& aAppInfo )
|
||||
m_titleName = aParent->GetAboutTitle();
|
||||
m_untranslatedTitleName = aParent->GetUntranslatedAboutTitle();
|
||||
m_staticTextAppTitle->SetLabel( m_titleName );
|
||||
|
||||
// On windows, display the number of GDI objects in use. Can be useful when some GDI objects
|
||||
// are not displayed because the max count of GDI objects (usually 10000) is reached
|
||||
// So displaying this number can help to diagnose strange display issues
|
||||
wxString extraInfo;
|
||||
|
||||
#if defined( _WIN32 )
|
||||
uint32_t gdi_count = GetGuiResources( GetCurrentProcess(), GR_GDIOBJECTS );
|
||||
extraInfo.Printf( _( "GDI objects in use %u" ), gdi_count );
|
||||
extraInfo.Prepend( wxT( "\n" ) );
|
||||
#endif
|
||||
|
||||
m_staticTextBuildVersion->SetLabel( wxS( "Version: " ) + m_info.GetBuildVersion() );
|
||||
m_staticTextLibVersion->SetLabel( m_info.GetLibVersion() );
|
||||
m_staticTextLibVersion->SetLabel( m_info.GetLibVersion() + extraInfo );
|
||||
|
||||
SetTitle( wxString::Format( _( "About %s" ), m_titleName ) );
|
||||
createNotebooks();
|
||||
|
||||
@@ -494,14 +494,17 @@ int DIALOG_SHIM::ShowModal()
|
||||
}
|
||||
|
||||
/*
|
||||
Quasi-Modal Mode Explained:
|
||||
QuasiModal Mode Explained:
|
||||
|
||||
The gtk calls in wxDialog::ShowModal() cause event routing problems if that
|
||||
modal dialog then tries to use KIWAY_PLAYER::ShowModal(). The latter shows up
|
||||
and mostly works but does not respond to the window decoration close button.
|
||||
There is no way to get around this without reversing the gtk calls temporarily.
|
||||
|
||||
Quasi-Modal mode is our own almost modal mode which disables only the parent
|
||||
There are also issues with the Scintilla text editor putting up autocomplete
|
||||
popups, which appear behind the dialog window if QuasiModal is not used.
|
||||
|
||||
QuasiModal mode is our own almost modal mode which disables only the parent
|
||||
of the DIALOG_SHIM, leaving other frames operable and while staying captured in the
|
||||
nested event loop. This avoids the gtk calls and leaves event routing pure
|
||||
and sufficient to operate the KIWAY_PLAYER::ShowModal() properly. When using
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "design_block_lib_table.h"
|
||||
|
||||
#include <kiplatform/io.h>
|
||||
|
||||
|
||||
DIALOG_GLOBAL_DESIGN_BLOCK_LIB_TABLE_CONFIG::DIALOG_GLOBAL_DESIGN_BLOCK_LIB_TABLE_CONFIG(
|
||||
wxWindow* aParent ) :
|
||||
@@ -106,8 +108,8 @@ bool DIALOG_GLOBAL_DESIGN_BLOCK_LIB_TABLE_CONFIG::TransferDataFromWindow()
|
||||
// Create the config path if it doesn't already exist.
|
||||
wxFileName designBlockTableFileName = DESIGN_BLOCK_LIB_TABLE::GetGlobalTableFileName();
|
||||
|
||||
if( !designBlockTableFileName.DirExists()
|
||||
&& !designBlockTableFileName.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
|
||||
if( !wxFileName::DirExists( designBlockTableFileName.GetPath() )
|
||||
&& !wxFileName::Mkdir( designBlockTableFileName.GetPath(), 0x777, wxPATH_MKDIR_FULL ) )
|
||||
{
|
||||
DisplayError( this, wxString::Format( _( "Cannot create global library table '%s'." ),
|
||||
designBlockTableFileName.GetPath() ) );
|
||||
@@ -124,6 +126,9 @@ bool DIALOG_GLOBAL_DESIGN_BLOCK_LIB_TABLE_CONFIG::TransferDataFromWindow()
|
||||
fn.GetFullPath(), designBlockTableFileName.GetFullPath() ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure the copied file is writable
|
||||
KIPLATFORM::IO::MakeWriteable( designBlockTableFileName.GetFullPath() );
|
||||
}
|
||||
|
||||
// Load the successfully copied design block library table file. This should not fail since the
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
EDA_VIEW_SWITCHER::EDA_VIEW_SWITCHER( wxWindow* aParent, const wxArrayString& aItems,
|
||||
wxKeyCode aCtrlKey ) :
|
||||
EDA_VIEW_SWITCHER_BASE( aParent ),
|
||||
m_tabState( true ),
|
||||
// Start with the tab marked as "up" so the initial ctrl-tab press advances selection.
|
||||
m_tabState( false ),
|
||||
m_receivingEvents( false ),
|
||||
m_ctrlKey( aCtrlKey )
|
||||
{
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <eda_item.h>
|
||||
#include <confirm.h>
|
||||
#include <bitmaps.h>
|
||||
#include <dialogs/panel_embedded_files.h>
|
||||
#include <embedded_files.h>
|
||||
@@ -161,9 +163,7 @@ void PANEL_EMBEDDED_FILES::resizeGrid()
|
||||
bool PANEL_EMBEDDED_FILES::TransferDataToWindow()
|
||||
{
|
||||
m_files_grid->ClearGrid();
|
||||
|
||||
if( m_files_grid->GetNumberRows() > 0 )
|
||||
m_files_grid->DeleteRows( 0, m_files_grid->GetNumberRows() );
|
||||
m_files_grid->ClearRows();
|
||||
|
||||
int ii = 0;
|
||||
for( auto& [name, file] : m_localFiles->EmbeddedFileMap() )
|
||||
@@ -187,6 +187,51 @@ bool PANEL_EMBEDDED_FILES::TransferDataToWindow()
|
||||
|
||||
bool PANEL_EMBEDDED_FILES::TransferDataFromWindow()
|
||||
{
|
||||
std::optional<bool> deleteReferences;
|
||||
|
||||
auto confirmDelete =
|
||||
[&]() -> bool
|
||||
{
|
||||
if( EDA_ITEM* parent = dynamic_cast<EDA_ITEM*>( m_files ) )
|
||||
{
|
||||
if( parent->Type() == PCB_T )
|
||||
{
|
||||
return IsOK( m_parent, _( "Deleted embedded files are also referenced in some footprints.\n"
|
||||
"Delete from footprints as well?" ) );
|
||||
}
|
||||
else if( parent->Type() == SCHEMATIC_T )
|
||||
{
|
||||
return IsOK( m_parent, _( "Deleted embedded files are also referenced in some symbols.\n"
|
||||
"Delete from symbols as well?" ) );
|
||||
}
|
||||
}
|
||||
|
||||
wxFAIL_MSG( wxT( "Unexpected embedded files owner" ) );
|
||||
return false;
|
||||
};
|
||||
|
||||
for( const auto& [name, file] : m_files->EmbeddedFileMap() )
|
||||
{
|
||||
if( !m_localFiles->HasFile( name ) )
|
||||
{
|
||||
m_files->RunOnNestedEmbeddedFiles(
|
||||
[&]( EMBEDDED_FILES* nested_files )
|
||||
{
|
||||
if( nested_files->HasFile( name ) )
|
||||
{
|
||||
if( !deleteReferences.has_value() )
|
||||
deleteReferences = confirmDelete();
|
||||
|
||||
if( deleteReferences.value() )
|
||||
nested_files->RemoveFile( name, true );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
if( deleteReferences.has_value() && deleteReferences.value() == false )
|
||||
break;
|
||||
}
|
||||
|
||||
m_files->ClearEmbeddedFiles();
|
||||
|
||||
std::vector<EMBEDDED_FILES::EMBEDDED_FILE*> files;
|
||||
@@ -247,11 +292,6 @@ void PANEL_EMBEDDED_FILES::onFontEmbedClick( wxCommandEvent& event )
|
||||
font->GetFileName() ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
m_files_grid->AppendRows( 1 );
|
||||
int ii = m_files_grid->GetNumberRows() - 1;
|
||||
m_files_grid->SetCellValue( ii, 0, result->name );
|
||||
m_files_grid->SetCellValue( ii, 1, result->GetLink() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -141,6 +141,7 @@ void EDA_BASE_FRAME::commonInit( FRAME_T aFrameType )
|
||||
m_isNonUserClose = false;
|
||||
m_autoSaveTimer = new wxTimer( this, ID_AUTO_SAVE_TIMER );
|
||||
m_autoSaveRequired = false;
|
||||
m_autoSavePermissionError = false;
|
||||
m_mruPath = PATHS::GetDefaultUserProjectsPath();
|
||||
m_frameSize = defaultSize( aFrameType, this );
|
||||
m_displayIndex = -1;
|
||||
|
||||
@@ -2339,10 +2339,10 @@ static struct EDA_SHAPE_DESC
|
||||
|
||||
if( lineStyleEnum.Choices().GetCount() == 0 )
|
||||
{
|
||||
lineStyleEnum.Map( LINE_STYLE::SOLID, _HKI( "Solid" ) )
|
||||
.Map( LINE_STYLE::DASH, _HKI( "Dashed" ) )
|
||||
.Map( LINE_STYLE::DOT, _HKI( "Dotted" ) )
|
||||
.Map( LINE_STYLE::DASHDOT, _HKI( "Dash-Dot" ) )
|
||||
lineStyleEnum.Map( LINE_STYLE::SOLID, _HKI( "Solid" ) )
|
||||
.Map( LINE_STYLE::DASH, _HKI( "Dashed" ) )
|
||||
.Map( LINE_STYLE::DOT, _HKI( "Dotted" ) )
|
||||
.Map( LINE_STYLE::DASHDOT, _HKI( "Dash-Dot" ) )
|
||||
.Map( LINE_STYLE::DASHDOTDOT, _HKI( "Dash-Dot-Dot" ) );
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -1323,18 +1323,18 @@ static struct EDA_TEXT_DESC
|
||||
|
||||
if( h_inst.Choices().GetCount() == 0)
|
||||
{
|
||||
h_inst.Map( GR_TEXT_H_ALIGN_LEFT, _( "Left" ) );
|
||||
h_inst.Map( GR_TEXT_H_ALIGN_CENTER, _( "Center" ) );
|
||||
h_inst.Map( GR_TEXT_H_ALIGN_RIGHT, _( "Right" ) );
|
||||
h_inst.Map( GR_TEXT_H_ALIGN_LEFT, _HKI( "Left" ) );
|
||||
h_inst.Map( GR_TEXT_H_ALIGN_CENTER, _HKI( "Center" ) );
|
||||
h_inst.Map( GR_TEXT_H_ALIGN_RIGHT, _HKI( "Right" ) );
|
||||
}
|
||||
|
||||
auto& v_inst = ENUM_MAP<GR_TEXT_V_ALIGN_T>::Instance();
|
||||
|
||||
if( v_inst.Choices().GetCount() == 0)
|
||||
{
|
||||
v_inst.Map( GR_TEXT_V_ALIGN_TOP, _( "Top" ) );
|
||||
v_inst.Map( GR_TEXT_V_ALIGN_CENTER, _( "Center" ) );
|
||||
v_inst.Map( GR_TEXT_V_ALIGN_BOTTOM, _( "Bottom" ) );
|
||||
v_inst.Map( GR_TEXT_V_ALIGN_TOP, _HKI( "Top" ) );
|
||||
v_inst.Map( GR_TEXT_V_ALIGN_CENTER, _HKI( "Center" ) );
|
||||
v_inst.Map( GR_TEXT_V_ALIGN_BOTTOM, _HKI( "Bottom" ) );
|
||||
}
|
||||
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
|
||||
@@ -599,6 +599,85 @@ double EDA_UNIT_UTILS::UI::DoubleValueFromString( const EDA_IU_SCALE& aIuScale,
|
||||
}
|
||||
|
||||
|
||||
bool EDA_UNIT_UTILS::UI::DoubleValueFromString( const EDA_IU_SCALE& aIuScale, const wxString& aTextValue,
|
||||
double& aDoubleValue )
|
||||
{
|
||||
double dtmp = 0;
|
||||
|
||||
// Acquire the 'right' decimal point separator
|
||||
const struct lconv* lc = localeconv();
|
||||
|
||||
wxChar decimal_point = lc->decimal_point[0];
|
||||
wxString buf( aTextValue.Strip( wxString::both ) );
|
||||
|
||||
// Convert any entered decimal point separators to the 'right' one
|
||||
buf.Replace( wxT( "." ), wxString( decimal_point, 1 ) );
|
||||
buf.Replace( wxT( "," ), wxString( decimal_point, 1 ) );
|
||||
|
||||
// Find the end of the numeric part
|
||||
unsigned brk_point = 0;
|
||||
|
||||
while( brk_point < buf.Len() )
|
||||
{
|
||||
wxChar ch = buf[brk_point];
|
||||
|
||||
if( !( (ch >= '0' && ch <= '9') || (ch == decimal_point) || (ch == '-') || (ch == '+') ) )
|
||||
break;
|
||||
|
||||
++brk_point;
|
||||
}
|
||||
|
||||
if( brk_point == 0 )
|
||||
return false;
|
||||
|
||||
// Extract the numeric part
|
||||
buf.Left( brk_point ).ToDouble( &dtmp );
|
||||
|
||||
// Check the unit designator
|
||||
wxString unit( buf.Mid( brk_point ).Strip( wxString::both ).Lower() );
|
||||
EDA_UNITS units;
|
||||
|
||||
//check for um, μm (µ is MICRO SIGN) and µm (µ is GREEK SMALL LETTER MU) for micrometre
|
||||
if( unit == wxT( "um" ) || unit == wxT( "\u00B5m" ) || unit == wxT( "\u03BCm" ) )
|
||||
{
|
||||
units = EDA_UNITS::UM;
|
||||
}
|
||||
else if( unit == wxT( "mm" ) )
|
||||
{
|
||||
units = EDA_UNITS::MM;
|
||||
}
|
||||
else if( unit == wxT( "cm" ) )
|
||||
{
|
||||
units = EDA_UNITS::CM;
|
||||
}
|
||||
else if( unit == wxT( "mil" ) || unit == wxT( "mils" ) || unit == wxT( "thou" ) )
|
||||
{
|
||||
units = EDA_UNITS::MILS;
|
||||
}
|
||||
else if( unit == wxT( "in" ) || unit == wxT( "\"" ) )
|
||||
{
|
||||
units = EDA_UNITS::INCH;
|
||||
}
|
||||
else if( unit == wxT( "oz" ) ) // 1 oz = 1.37 mils
|
||||
{
|
||||
units = EDA_UNITS::MILS;
|
||||
dtmp *= 1.37;
|
||||
}
|
||||
else if( unit == wxT( "ra" ) ) // Radians
|
||||
{
|
||||
units = EDA_UNITS::DEGREES;
|
||||
dtmp *= 180.0f / M_PI;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
aDoubleValue = FromUserUnit( aIuScale, units, dtmp );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
long long int EDA_UNIT_UTILS::UI::ValueFromString( const EDA_IU_SCALE& aIuScale, EDA_UNITS aUnits,
|
||||
const wxString& aTextValue, EDA_DATA_TYPE aType )
|
||||
{
|
||||
|
||||
@@ -355,7 +355,7 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
// contents
|
||||
|
||||
hb_font_t* referencedFont = hb_ft_font_create_referenced( face );
|
||||
hb_ft_font_set_funcs( referencedFont );
|
||||
|
||||
hb_shape( referencedFont, buf, nullptr, 0 );
|
||||
|
||||
unsigned int glyphCount;
|
||||
@@ -376,10 +376,6 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
|
||||
|
||||
for( unsigned int i = 0; i < glyphCount; i++ )
|
||||
{
|
||||
// Don't process glyphs that were already included in a previous cluster
|
||||
if( i > 0 && glyphInfo[i].cluster == glyphInfo[i-1].cluster )
|
||||
continue;
|
||||
|
||||
if( aGlyphs )
|
||||
{
|
||||
GLYPH_CACHE_KEY key = { face, glyphInfo[i].codepoint, scaleFactor, m_forDrawingSheet,
|
||||
@@ -557,9 +553,8 @@ void OUTLINE_FONT::RenderToOpenGLCanvas( KIGFX::OPENGL_GAL& aGal, const wxString
|
||||
|
||||
std::lock_guard<std::mutex> guard( m_freeTypeMutex );
|
||||
|
||||
hb_font_t* referencedFont = hb_ft_font_create_referenced( m_face );
|
||||
hb_font_t* referencedFont = hb_ft_font_create_referenced( m_face );
|
||||
|
||||
hb_ft_font_set_funcs( referencedFont );
|
||||
hb_shape( referencedFont, buf, nullptr, 0 );
|
||||
|
||||
const double mirror_factor = ( aIsMirrored ? 1 : -1 );
|
||||
|
||||
@@ -628,7 +628,8 @@ bool FP_LIB_TABLE::LoadGlobalTable( FP_LIB_TABLE& aTable )
|
||||
{
|
||||
tableExists = false;
|
||||
|
||||
if( !fn.DirExists() && !fn.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
|
||||
if( !wxFileName::DirExists( fn.GetPath() )
|
||||
&& !wxFileName::Mkdir( fn.GetPath(), 0x777, wxPATH_MKDIR_FULL ) )
|
||||
{
|
||||
THROW_IO_ERROR( wxString::Format( _( "Cannot create global library table path '%s'." ),
|
||||
fn.GetPath() ) );
|
||||
|
||||
@@ -322,6 +322,12 @@ void CAIRO_GAL_BASE::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& a
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL_BASE::DrawHoleWall( const VECTOR2D& aCenterPoint, double aRadius, double aWallWidth )
|
||||
{
|
||||
DrawCircle( aCenterPoint, aRadius + aWallWidth );
|
||||
}
|
||||
|
||||
|
||||
void CAIRO_GAL_BASE::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
||||
{
|
||||
syncLineWidth();
|
||||
@@ -1740,6 +1746,8 @@ void CAIRO_GAL_BASE::DrawGrid()
|
||||
return;
|
||||
|
||||
VECTOR2D gridScreenSize( m_gridSize );
|
||||
gridScreenSize = VECTOR2D( std::max( 1.0, gridScreenSize.x ),
|
||||
std::max( 1.0, gridScreenSize.y ) );
|
||||
|
||||
double gridThreshold = KiROUND( computeMinGridSpacing() / m_worldScale );
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
|
||||
SetLayerDepth( 0.0 );
|
||||
SetFlip( false, false );
|
||||
SetLineWidth( 1.0f );
|
||||
SetMinLineWidth( 1.0f );
|
||||
computeWorldScale();
|
||||
SetAxesEnabled( false );
|
||||
|
||||
@@ -75,6 +76,8 @@ GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
|
||||
SetCoarseGrid( 10 );
|
||||
m_gridLineWidth = 0.5f;
|
||||
m_gridStyle = GRID_STYLE::LINES;
|
||||
m_gridSize = VECTOR2D( 1.0, 1.0 );
|
||||
m_gridOffset = VECTOR2D( 0.0, 0.0 );
|
||||
m_gridMinSpacing = 10;
|
||||
|
||||
// Initialize the cursor shape
|
||||
|
||||
@@ -413,10 +413,13 @@ OPENGL_GAL::OPENGL_GAL( const KIGFX::VC_SETTINGS& aVcSettings, GAL_DISPLAY_OPTIO
|
||||
SetTarget( TARGET_NONCACHED );
|
||||
|
||||
// Avoid uninitialized variables:
|
||||
ufm_worldPixelSize = 1;
|
||||
ufm_screenPixelSize = 1;
|
||||
ufm_pixelSizeMultiplier = 1;
|
||||
ufm_antialiasingOffset = 1;
|
||||
ufm_worldPixelSize = -1;
|
||||
ufm_screenPixelSize = -1;
|
||||
ufm_pixelSizeMultiplier = -1;
|
||||
ufm_antialiasingOffset = -1;
|
||||
ufm_minLinePixelWidth = -1;
|
||||
ufm_fontTexture = -1;
|
||||
ufm_fontTextureWidth = -1;
|
||||
m_swapInterval = 0;
|
||||
}
|
||||
|
||||
@@ -672,14 +675,6 @@ void OPENGL_GAL::BeginDrawing()
|
||||
glActiveTexture( GL_TEXTURE0 );
|
||||
}
|
||||
|
||||
// Set shader parameter
|
||||
GLint ufm_fontTexture = m_shader->AddParameter( "u_fontTexture" );
|
||||
GLint ufm_fontTextureWidth = m_shader->AddParameter( "u_fontTextureWidth" );
|
||||
ufm_worldPixelSize = m_shader->AddParameter( "u_worldPixelSize" );
|
||||
ufm_screenPixelSize = m_shader->AddParameter( "u_screenPixelSize" );
|
||||
ufm_pixelSizeMultiplier = m_shader->AddParameter( "u_pixelSizeMultiplier" );
|
||||
ufm_antialiasingOffset = m_shader->AddParameter( "u_antialiasingOffset" );
|
||||
|
||||
m_shader->Use();
|
||||
m_shader->SetParameter( ufm_fontTexture, (int) FONT_TEXTURE_UNIT );
|
||||
m_shader->SetParameter( ufm_fontTextureWidth, (int) font_image.width );
|
||||
@@ -700,6 +695,7 @@ void OPENGL_GAL::BeginDrawing()
|
||||
renderingOffset.x *= screenPixelSize.x;
|
||||
renderingOffset.y *= screenPixelSize.y;
|
||||
m_shader->SetParameter( ufm_antialiasingOffset, renderingOffset );
|
||||
m_shader->SetParameter( ufm_minLinePixelWidth, GetMinLineWidth() );
|
||||
m_shader->Deactivate();
|
||||
|
||||
// Something between BeginDrawing and EndDrawing seems to depend on
|
||||
@@ -716,6 +712,18 @@ void OPENGL_GAL::BeginDrawing()
|
||||
#endif /* KICAD_GAL_PROFILE */
|
||||
}
|
||||
|
||||
void OPENGL_GAL::SetMinLineWidth( float aLineWidth )
|
||||
{
|
||||
GAL::SetMinLineWidth( aLineWidth );
|
||||
|
||||
if( m_shader && ufm_minLinePixelWidth != -1 )
|
||||
{
|
||||
m_shader->Use();
|
||||
m_shader->SetParameter( ufm_minLinePixelWidth, aLineWidth );
|
||||
m_shader->Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::EndDrawing()
|
||||
{
|
||||
@@ -907,6 +915,25 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::DrawHoleWall( const VECTOR2D& aCenterPoint, double aHoleRadius,
|
||||
double aWallWidth )
|
||||
{
|
||||
if( m_isFillEnabled )
|
||||
{
|
||||
m_currentManager->Color( m_fillColor.r, m_fillColor.g, m_fillColor.b, m_fillColor.a );
|
||||
|
||||
m_currentManager->Shader( SHADER_HOLE_WALL, 1.0, aHoleRadius, aWallWidth );
|
||||
m_currentManager->Vertex( aCenterPoint.x, aCenterPoint.y, m_layerDepth );
|
||||
|
||||
m_currentManager->Shader( SHADER_HOLE_WALL, 2.0, aHoleRadius, aWallWidth );
|
||||
m_currentManager->Vertex( aCenterPoint.x, aCenterPoint.y, m_layerDepth );
|
||||
|
||||
m_currentManager->Shader( SHADER_HOLE_WALL, 3.0, aHoleRadius, aWallWidth );
|
||||
m_currentManager->Vertex( aCenterPoint.x, aCenterPoint.y, m_layerDepth );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::drawCircle( const VECTOR2D& aCenterPoint, double aRadius, bool aReserve )
|
||||
{
|
||||
if( m_isFillEnabled )
|
||||
@@ -2662,6 +2689,10 @@ void OPENGL_GAL::blitCursor()
|
||||
glLineWidth( 1.0 );
|
||||
glColor4d( color.r, color.g, color.b, color.a );
|
||||
|
||||
glMatrixMode( GL_PROJECTION );
|
||||
glPushMatrix();
|
||||
glTranslated( 0, 0, -0.5 );
|
||||
|
||||
glBegin( GL_LINES );
|
||||
glVertex2d( cursorCenter.x, cursorBegin.y );
|
||||
glVertex2d( cursorCenter.x, cursorEnd.y );
|
||||
@@ -2669,6 +2700,8 @@ void OPENGL_GAL::blitCursor()
|
||||
glVertex2d( cursorBegin.x, cursorCenter.y );
|
||||
glVertex2d( cursorEnd.x, cursorCenter.y );
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
@@ -2753,6 +2786,9 @@ void OPENGL_GAL::init()
|
||||
if( !m_shader->IsLinked() && !m_shader->Link() )
|
||||
throw std::runtime_error( "Cannot link the shaders!" );
|
||||
|
||||
// Set up shader parameters after linking
|
||||
setupShaderParameters();
|
||||
|
||||
// Check if video card supports textures big enough to fit the font atlas
|
||||
int maxTextureSize;
|
||||
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &maxTextureSize );
|
||||
@@ -2781,6 +2817,19 @@ void OPENGL_GAL::init()
|
||||
}
|
||||
|
||||
|
||||
void OPENGL_GAL::setupShaderParameters()
|
||||
{
|
||||
// Initialize shader uniform parameter locations
|
||||
ufm_fontTexture = m_shader->AddParameter( "u_fontTexture" );
|
||||
ufm_fontTextureWidth = m_shader->AddParameter( "u_fontTextureWidth" );
|
||||
ufm_worldPixelSize = m_shader->AddParameter( "u_worldPixelSize" );
|
||||
ufm_screenPixelSize = m_shader->AddParameter( "u_screenPixelSize" );
|
||||
ufm_pixelSizeMultiplier = m_shader->AddParameter( "u_pixelSizeMultiplier" );
|
||||
ufm_antialiasingOffset = m_shader->AddParameter( "u_antialiasingOffset" );
|
||||
ufm_minLinePixelWidth = m_shader->AddParameter( "u_minLinePixelWidth" );
|
||||
}
|
||||
|
||||
|
||||
// Callback functions for the tesselator. Compare Redbook Chapter 11.
|
||||
void CALLBACK VertexCallback( GLvoid* aVertexPtr, void* aData )
|
||||
{
|
||||
|
||||
@@ -35,6 +35,7 @@ const float SHADER_FILLED_CIRCLE = 2.0;
|
||||
const float SHADER_STROKED_CIRCLE = 3.0;
|
||||
const float SHADER_FONT = 4.0;
|
||||
const float SHADER_LINE_A = 5.0;
|
||||
const float SHADER_HOLE_WALL = 11.0;
|
||||
|
||||
varying vec4 v_shaderParams;
|
||||
varying vec2 v_circleCoords;
|
||||
@@ -124,6 +125,10 @@ void main()
|
||||
{
|
||||
strokedCircle( v_circleCoords, v_shaderParams[2], v_shaderParams[3] );
|
||||
}
|
||||
else if( mode == SHADER_HOLE_WALL )
|
||||
{
|
||||
strokedCircle( v_circleCoords, v_shaderParams[2], v_shaderParams[3] );
|
||||
}
|
||||
else if( mode == SHADER_FONT )
|
||||
{
|
||||
vec2 tex = v_shaderParams.yz;
|
||||
|
||||
@@ -36,6 +36,7 @@ const float SHADER_LINE_C = 7.0;
|
||||
const float SHADER_LINE_D = 8.0;
|
||||
const float SHADER_LINE_E = 9.0;
|
||||
const float SHADER_LINE_F = 10.0;
|
||||
const float SHADER_HOLE_WALL = 11.0;
|
||||
|
||||
// Minimum line width
|
||||
const float MIN_WIDTH = 1.0;
|
||||
@@ -72,8 +73,8 @@ void computeLineCoords( bool posture, vec2 vs, vec2 vp, vec2 texcoord, vec2 dir,
|
||||
vec2 s = sign( vec2( gl_ModelViewProjectionMatrix[0][0], gl_ModelViewProjectionMatrix[1][1] ) );
|
||||
|
||||
|
||||
if( pixelWidth < 1.0 )
|
||||
pixelWidth = 1.0;
|
||||
if( pixelWidth < u_minLinePixelWidth )
|
||||
pixelWidth = u_minLinePixelWidth;
|
||||
|
||||
if ( pixelWidth > 1.0 || u_pixelSizeMultiplier > 1.0 )
|
||||
{
|
||||
@@ -126,8 +127,59 @@ void computeCircleCoords( float mode, float vertexIndex, float radius, float lin
|
||||
|
||||
vec4 adjust = vec4(-1, -1, 0, 0);
|
||||
|
||||
if( pixelWidth < 1.0 )
|
||||
pixelWidth = 1.0;
|
||||
if( pixelWidth < u_minLinePixelWidth )
|
||||
pixelWidth = u_minLinePixelWidth;
|
||||
|
||||
if( vertexIndex == 1.0 )
|
||||
{
|
||||
v_circleCoords = vec2( -sqrt( 3.0 ), -1.0 );
|
||||
delta = vec4( -pixelR * sqrt(3.0), -pixelR, 0, 0 );
|
||||
}
|
||||
else if( vertexIndex == 2.0 )
|
||||
{
|
||||
v_circleCoords = vec2( sqrt( 3.0 ), -1.0 );
|
||||
delta = vec4( pixelR * sqrt( 3.0 ), -pixelR, 0, 0 );
|
||||
}
|
||||
else if( vertexIndex == 3.0 )
|
||||
{
|
||||
v_circleCoords = vec2( 0.0, 2.0 );
|
||||
delta = vec4( 0, 2 * pixelR, 0, 0 );
|
||||
}
|
||||
else if( vertexIndex == 4.0 )
|
||||
{
|
||||
v_circleCoords = vec2( -sqrt( 3.0 ), 0.0 );
|
||||
delta = vec4( 0, 0, 0, 0 );
|
||||
}
|
||||
else if( vertexIndex == 5.0 )
|
||||
{
|
||||
v_circleCoords = vec2( sqrt( 3.0 ), 0.0 );
|
||||
delta = vec4( 0, 0, 0, 0 );
|
||||
}
|
||||
else if( vertexIndex == 6.0 )
|
||||
{
|
||||
v_circleCoords = vec2( 0.0, 2.0 );
|
||||
delta = vec4( 0, 0, 0, 0 );
|
||||
}
|
||||
|
||||
v_shaderParams[2] = pixelR;
|
||||
v_shaderParams[3] = pixelWidth;
|
||||
|
||||
delta.x *= u_screenPixelSize.x;
|
||||
delta.y *= u_screenPixelSize.y;
|
||||
|
||||
gl_Position = center + delta + adjust;
|
||||
gl_FrontColor = gl_Color;
|
||||
}
|
||||
|
||||
void computeHoleWallCoords( float vertexIndex, float radius, float lineWidth )
|
||||
{
|
||||
vec4 delta;
|
||||
vec4 center = roundv( gl_ModelViewProjectionMatrix * gl_Vertex + vec4(1, 1, 0, 0), u_screenPixelSize );
|
||||
float pixelWidth = roundr( lineWidth / u_worldPixelSize, 1.0 );
|
||||
if( pixelWidth < u_minLinePixelWidth )
|
||||
pixelWidth = u_minLinePixelWidth;
|
||||
float pixelR = roundr( radius / u_worldPixelSize, 1.0 ) + pixelWidth;
|
||||
vec4 adjust = vec4(-1, -1, 0, 0);
|
||||
|
||||
if( vertexIndex == 1.0 )
|
||||
{
|
||||
@@ -195,6 +247,8 @@ void main()
|
||||
computeLineCoords( posture, vs, vp, vec2( -1, 1 ), vec2( -1, 0 ), lineWidth, true );
|
||||
else if( mode == SHADER_LINE_F )
|
||||
computeLineCoords( posture, -vs, vp, vec2( 1, 1 ), vec2( -1, 0 ), lineWidth, false );
|
||||
else if( mode == SHADER_HOLE_WALL )
|
||||
computeHoleWallCoords( v_shaderParams.y, v_shaderParams.z, v_shaderParams.w );
|
||||
else if( mode == SHADER_FILLED_CIRCLE || mode == SHADER_STROKED_CIRCLE)
|
||||
computeCircleCoords( mode, v_shaderParams.y, v_shaderParams.z, v_shaderParams.w );
|
||||
else
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
KIGIT_COMMON::KIGIT_COMMON( git_repository* aRepo ) :
|
||||
m_repo( aRepo ), m_connType( GIT_CONN_TYPE::GIT_CONN_LOCAL ), m_testedTypes( 0 ),
|
||||
m_nextPublicKey( 0 )
|
||||
m_nextPublicKey( 0 ), m_secretFetched( false )
|
||||
{}
|
||||
|
||||
KIGIT_COMMON::KIGIT_COMMON( const KIGIT_COMMON& aOther ) :
|
||||
@@ -55,7 +55,8 @@ KIGIT_COMMON::KIGIT_COMMON( const KIGIT_COMMON& aOther ) :
|
||||
// The mutex is default-initialized, not copied
|
||||
m_gitActionMutex(),
|
||||
m_publicKeys( aOther.m_publicKeys ),
|
||||
m_nextPublicKey( aOther.m_nextPublicKey )
|
||||
m_nextPublicKey( aOther.m_nextPublicKey ),
|
||||
m_secretFetched( aOther.m_secretFetched )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -100,6 +101,25 @@ wxString KIGIT_COMMON::GetCurrentBranchName() const
|
||||
}
|
||||
|
||||
|
||||
wxString KIGIT_COMMON::GetPassword()
|
||||
{
|
||||
if( !m_secretFetched )
|
||||
{
|
||||
if( m_connType != GIT_CONN_TYPE::GIT_CONN_LOCAL && !m_remote.IsEmpty() )
|
||||
{
|
||||
wxString secret;
|
||||
|
||||
if( KIPLATFORM::SECRETS::GetSecret( m_remote, m_username, secret ) )
|
||||
m_password = secret;
|
||||
}
|
||||
|
||||
m_secretFetched = true;
|
||||
}
|
||||
|
||||
return m_password;
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxString> KIGIT_COMMON::GetBranchNames() const
|
||||
{
|
||||
if( !m_repo )
|
||||
@@ -645,6 +665,10 @@ void KIGIT_COMMON::UpdateCurrentBranchInfo()
|
||||
wxString remote_name = GetRemotename();
|
||||
git_remote* remote = nullptr;
|
||||
|
||||
m_remote.clear();
|
||||
m_password.clear();
|
||||
m_secretFetched = false;
|
||||
|
||||
if( git_remote_lookup( &remote, m_repo, remote_name.ToStdString().c_str() ) == GIT_OK )
|
||||
{
|
||||
const char* url = git_remote_url( remote );
|
||||
@@ -655,9 +679,6 @@ void KIGIT_COMMON::UpdateCurrentBranchInfo()
|
||||
git_remote_free( remote );
|
||||
}
|
||||
|
||||
// Find the stored password if it exists
|
||||
KIPLATFORM::SECRETS::GetSecret( m_remote, m_username, m_password );
|
||||
|
||||
updateConnectionType();
|
||||
updatePublicKeys();
|
||||
}
|
||||
@@ -748,6 +769,8 @@ void KIGIT_COMMON::updateConnectionType()
|
||||
m_hostname = host;
|
||||
}
|
||||
}
|
||||
|
||||
m_secretFetched = !m_password.IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -89,11 +89,11 @@ public:
|
||||
};
|
||||
|
||||
wxString GetUsername() const { return m_username; }
|
||||
wxString GetPassword() const { return m_password; }
|
||||
wxString GetPassword();
|
||||
GIT_CONN_TYPE GetConnType() const;
|
||||
|
||||
void SetUsername( const wxString& aUsername ) { m_username = aUsername; }
|
||||
void SetPassword( const wxString& aPassword ) { m_password = aPassword; }
|
||||
void SetUsername( const wxString& aUsername ) { m_username = aUsername; m_secretFetched = false; }
|
||||
void SetPassword( const wxString& aPassword ) { m_password = aPassword; m_secretFetched = true; }
|
||||
void SetSSHKey( const wxString& aSSHKey );
|
||||
|
||||
// Holds a temporary variable that can be used by the authentication callback
|
||||
@@ -127,6 +127,8 @@ public:
|
||||
void SetRemote( const wxString& aRemote )
|
||||
{
|
||||
m_remote = aRemote;
|
||||
m_password.clear();
|
||||
m_secretFetched = false;
|
||||
updateConnectionType();
|
||||
}
|
||||
|
||||
@@ -170,6 +172,7 @@ private:
|
||||
|
||||
std::vector<wxString> m_publicKeys;
|
||||
int m_nextPublicKey;
|
||||
bool m_secretFetched;
|
||||
|
||||
// Create a dummy flag to tell if we have tested ssh agent credentials separately
|
||||
// from the ssh key credentials
|
||||
|
||||
@@ -40,19 +40,11 @@ HTTP_LIB_CONNECTION::HTTP_LIB_CONNECTION( const HTTP_LIB_SOURCE& aSource, bool a
|
||||
m_source = aSource;
|
||||
|
||||
if( aTestConnectionNow )
|
||||
{
|
||||
ValidateHTTPLibraryEndpoints();
|
||||
}
|
||||
validateHttpLibraryEndpoints();
|
||||
}
|
||||
|
||||
|
||||
HTTP_LIB_CONNECTION::~HTTP_LIB_CONNECTION()
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
||||
bool HTTP_LIB_CONNECTION::ValidateHTTPLibraryEndpoints()
|
||||
bool HTTP_LIB_CONNECTION::validateHttpLibraryEndpoints()
|
||||
{
|
||||
m_endpointValid = false;
|
||||
std::string res = "";
|
||||
@@ -78,11 +70,8 @@ bool HTTP_LIB_CONNECTION::ValidateHTTPLibraryEndpoints()
|
||||
nlohmann::json response = nlohmann::json::parse( res );
|
||||
|
||||
// Check that the endpoints exist, if not fail.
|
||||
if( !response.at( http_endpoint_categories ).empty()
|
||||
&& !response.at( http_endpoint_parts ).empty() )
|
||||
{
|
||||
if( !response.at( "categories" ).empty() && !response.at( "parts" ).empty() )
|
||||
m_endpointValid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
@@ -90,29 +79,19 @@ bool HTTP_LIB_CONNECTION::ValidateHTTPLibraryEndpoints()
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
e.what(), res );
|
||||
|
||||
wxLogTrace( traceHTTPLib,
|
||||
wxT( "ValidateHTTPLibraryEndpoints: Exception occurred while testing the API "
|
||||
"connection: %s" ),
|
||||
wxLogTrace( traceHTTPLib, wxT( "validateHttpLibraryEndpoints: Exception while testing API connection: %s" ),
|
||||
m_lastError );
|
||||
|
||||
m_endpointValid = false;
|
||||
}
|
||||
|
||||
if( m_endpointValid )
|
||||
{
|
||||
syncCategories();
|
||||
}
|
||||
|
||||
return m_endpointValid;
|
||||
}
|
||||
|
||||
|
||||
bool HTTP_LIB_CONNECTION::IsValidEndpoint() const
|
||||
{
|
||||
return m_endpointValid;
|
||||
}
|
||||
|
||||
|
||||
bool HTTP_LIB_CONNECTION::syncCategories()
|
||||
{
|
||||
if( !IsValidEndpoint() )
|
||||
@@ -124,7 +103,7 @@ bool HTTP_LIB_CONNECTION::syncCategories()
|
||||
std::string res = "";
|
||||
|
||||
std::unique_ptr<KICAD_CURL_EASY> curl = createCurlEasyObject();
|
||||
curl->SetURL( m_source.root_url + http_endpoint_categories + ".json" );
|
||||
curl->SetURL( m_source.root_url + "categories.json" );
|
||||
|
||||
try
|
||||
{
|
||||
@@ -133,9 +112,7 @@ bool HTTP_LIB_CONNECTION::syncCategories()
|
||||
res = curl->GetBuffer();
|
||||
|
||||
if( !checkServerResponse( curl ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
nlohmann::json response = nlohmann::json::parse( res );
|
||||
|
||||
@@ -162,9 +139,7 @@ bool HTTP_LIB_CONNECTION::syncCategories()
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
e.what(), res );
|
||||
|
||||
wxLogTrace( traceHTTPLib,
|
||||
wxT( "syncCategories: Exception occurred while syncing categories: %s" ),
|
||||
m_lastError );
|
||||
wxLogTrace( traceHTTPLib, wxT( "syncCategories: Exception while syncing categories: %s" ), m_lastError );
|
||||
|
||||
m_categories.clear();
|
||||
|
||||
@@ -187,8 +162,7 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
if( m_cachedParts.find( aPartID ) != m_cachedParts.end() )
|
||||
{
|
||||
// check if it's outdated, if so re-fetch
|
||||
if( std::difftime( std::time( nullptr ), m_cachedParts[aPartID].lastCached )
|
||||
< m_source.timeout_parts )
|
||||
if( std::difftime( std::time( nullptr ), m_cachedParts[aPartID].lastCached ) < m_source.timeout_parts )
|
||||
{
|
||||
aFetchedPart = m_cachedParts[aPartID];
|
||||
return true;
|
||||
@@ -198,7 +172,7 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
std::string res = "";
|
||||
|
||||
std::unique_ptr<KICAD_CURL_EASY> curl = createCurlEasyObject();
|
||||
std::string url = m_source.root_url + fmt::format( "{}/{}.json", http_endpoint_parts, aPartID );
|
||||
std::string url = m_source.root_url + fmt::format( "parts/{}.json", aPartID );
|
||||
curl->SetURL( url );
|
||||
|
||||
try
|
||||
@@ -208,9 +182,7 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
res = curl->GetBuffer();
|
||||
|
||||
if( !checkServerResponse( curl ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
nlohmann::ordered_json response = nlohmann::ordered_json::parse( res );
|
||||
std::string key = "";
|
||||
@@ -225,13 +197,9 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
|
||||
// API might not want to return an optional name.
|
||||
if( response.contains( "name" ) )
|
||||
{
|
||||
aFetchedPart.name = response.at( "name" );
|
||||
}
|
||||
else
|
||||
{
|
||||
aFetchedPart.name = aFetchedPart.id;
|
||||
}
|
||||
|
||||
aFetchedPart.symbolIdStr = response.at( "symbolIdStr" );
|
||||
|
||||
@@ -285,18 +253,36 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
}
|
||||
|
||||
// Add field to fields list
|
||||
aFetchedPart.fields.push_back(
|
||||
std::make_pair( key, std::make_tuple( value, visible ) ) );
|
||||
aFetchedPart.fields.push_back( std::make_pair( key, std::make_tuple( value, visible ) ) );
|
||||
}
|
||||
|
||||
if( response.contains( "description" ) )
|
||||
aFetchedPart.desc = response.at( "description" );
|
||||
|
||||
if( response.contains( "keywords" ) )
|
||||
aFetchedPart.keywords = response.at( "keywords" );
|
||||
|
||||
if( response.contains( "footprint_filters" ) )
|
||||
{
|
||||
nlohmann::json filters_json = response.at( "footprint_filters" );
|
||||
|
||||
if( filters_json.is_array() )
|
||||
{
|
||||
for( const auto& val : filters_json )
|
||||
aFetchedPart.fp_filters.push_back( val );
|
||||
}
|
||||
else
|
||||
{
|
||||
aFetchedPart.fp_filters.push_back( filters_json );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
e.what(), res );
|
||||
|
||||
wxLogTrace( traceHTTPLib,
|
||||
wxT( "SelectOne: Exception occurred while retrieving part from REST API: %s" ),
|
||||
m_lastError );
|
||||
wxLogTrace( traceHTTPLib, wxT( "SelectOne: Exception while fetching part: %s" ), m_lastError );
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -307,8 +293,7 @@ bool HTTP_LIB_CONNECTION::SelectOne( const std::string& aPartID, HTTP_LIB_PART&
|
||||
}
|
||||
|
||||
|
||||
bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory,
|
||||
std::vector<HTTP_LIB_PART>& aParts )
|
||||
bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory, std::vector<HTTP_LIB_PART>& aParts )
|
||||
{
|
||||
if( !IsValidEndpoint() )
|
||||
{
|
||||
@@ -320,8 +305,7 @@ bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory,
|
||||
|
||||
std::unique_ptr<KICAD_CURL_EASY> curl = createCurlEasyObject();
|
||||
|
||||
curl->SetURL( m_source.root_url
|
||||
+ fmt::format( "{}/category/{}.json", http_endpoint_parts, aCategory.id ) );
|
||||
curl->SetURL( m_source.root_url + fmt::format( "parts/category/{}.json", aCategory.id ) );
|
||||
|
||||
try
|
||||
{
|
||||
@@ -339,21 +323,13 @@ bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory,
|
||||
part.id = item.at( "id" );
|
||||
|
||||
if( item.contains( "description" ) )
|
||||
{
|
||||
// At this point we don't display anything so just set it to false
|
||||
part.fields.push_back( std::make_pair(
|
||||
"description", std::make_tuple( item.at( "description" ), false ) ) );
|
||||
}
|
||||
part.desc = item.at( "description" );
|
||||
|
||||
// API might not want to return an optional name.
|
||||
if( item.contains( "name" ) )
|
||||
{
|
||||
part.name = item.at( "name" );
|
||||
}
|
||||
else
|
||||
{
|
||||
part.name = part.id;
|
||||
}
|
||||
|
||||
// add to cache
|
||||
m_cache[part.name] = std::make_tuple( part.id, aCategory.id );
|
||||
@@ -363,11 +339,10 @@ bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory,
|
||||
}
|
||||
catch( const std::exception& e )
|
||||
{
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
m_lastError += wxString::Format( _( "Error: %s" ) + "\n" + _( "API Response: %s" ) + "\n",
|
||||
e.what(), res );
|
||||
|
||||
wxLogTrace( traceHTTPLib, wxT( "Exception occurred while syncing parts from REST API: %s" ),
|
||||
m_lastError );
|
||||
wxLogTrace( traceHTTPLib, wxT( "Exception occurred while syncing parts: %s" ), m_lastError );
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -379,6 +354,7 @@ bool HTTP_LIB_CONNECTION::SelectAll( const HTTP_LIB_CATEGORY& aCategory,
|
||||
bool HTTP_LIB_CONNECTION::checkServerResponse( std::unique_ptr<KICAD_CURL_EASY>& aCurl )
|
||||
{
|
||||
int statusCode = aCurl->GetResponseStatusCode();
|
||||
|
||||
if( statusCode != 200 )
|
||||
{
|
||||
m_lastError += wxString::Format( _( "API responded with error code: %s" ) + "\n",
|
||||
|
||||
@@ -35,10 +35,9 @@ const int httplibSchemaVersion = 1;
|
||||
HTTP_LIB_SETTINGS::HTTP_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
JSON_SETTINGS( aFilename, SETTINGS_LOC::NONE, httplibSchemaVersion )
|
||||
{
|
||||
m_params.emplace_back( new PARAM<std::string>( "source.type", &sourceType, "" ) );
|
||||
m_params.emplace_back( new PARAM<std::string>( "source.type", &m_sourceType, "" ) );
|
||||
|
||||
m_params.emplace_back(
|
||||
new PARAM<std::string>( "source.api_version", &m_Source.api_version, "" ) );
|
||||
m_params.emplace_back( new PARAM<std::string>( "source.api_version", &m_Source.api_version, "" ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<std::string>( "source.root_url", &m_Source.root_url, "" ) );
|
||||
|
||||
@@ -46,8 +45,7 @@ HTTP_LIB_SETTINGS::HTTP_LIB_SETTINGS( const std::string& aFilename ) :
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "source.timeout_parts_seconds", &m_Source.timeout_parts, 30 ) );
|
||||
|
||||
m_params.emplace_back( new PARAM<int>( "source.timeout_categories_seconds",
|
||||
&m_Source.timeout_categories, 600 ) );
|
||||
m_params.emplace_back( new PARAM<int>( "source.timeout_categories_seconds", &m_Source.timeout_categories, 600 ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,10 @@ std::map<wxString, wxString> ALTIUM_ASCII_PARSER::ReadProperties()
|
||||
if( canonicalKey == wxT( "DESIGNATOR" ) || canonicalKey == wxT( "NAME" )
|
||||
|| canonicalKey == wxT( "TEXT" ) )
|
||||
{
|
||||
if( kv[ wxT( "RECORD" ) ] != wxT( "4" ) )
|
||||
wxString recordType = kv[ wxT( "RECORD" ) ];
|
||||
|
||||
// RECORD=33 (FILE_NAME) stores Windows-formatted paths; keep the backslashes intact.
|
||||
if( recordType != wxT( "4" ) && recordType != wxT( "33" ) )
|
||||
value = AltiumPropertyToKiCadString( value );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,7 +327,8 @@ bool EURN::IsValid() const
|
||||
"footprint",
|
||||
"library",
|
||||
"package",
|
||||
"symbol"
|
||||
"symbol",
|
||||
"fs.file"
|
||||
};
|
||||
|
||||
if( validAssetTypes.count( assetType ) == 0 )
|
||||
@@ -407,11 +408,29 @@ EROT Convert<EROT>( const wxString& aRot )
|
||||
|
||||
value.spin = aRot.find( 'S' ) != aRot.npos;
|
||||
value.mirror = aRot.find( 'M' ) != aRot.npos;
|
||||
value.degrees = strtod( aRot.c_str()
|
||||
+ 1 // skip leading 'R'
|
||||
+ int( value.spin ) // skip optional leading 'S'
|
||||
+ int( value.mirror ), // skip optional leading 'M'
|
||||
nullptr );
|
||||
|
||||
size_t rPos = aRot.find( 'R' );
|
||||
|
||||
if( rPos == wxString::npos )
|
||||
{
|
||||
value.degrees = 0.0;
|
||||
return value;
|
||||
}
|
||||
|
||||
// Calculate the offset after 'R', 'S', and 'M'
|
||||
size_t offset;
|
||||
|
||||
for( offset = 0; offset < aRot.size(); offset++ )
|
||||
{
|
||||
if( wxIsdigit( aRot[offset] ) )
|
||||
break;
|
||||
}
|
||||
|
||||
wxString degreesStr = aRot.Mid( offset );
|
||||
|
||||
// Use locale-independent conversion
|
||||
if( !degreesStr.ToCDouble( &value.degrees ) )
|
||||
value.degrees = 0.0;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -428,6 +428,9 @@ struct EAGLE_BASE
|
||||
* The "/<VERSION>" is omitted when referencing the asset without specifying a particular version.
|
||||
* For example, "urn:adsk.eagle:component:60986/2" references version 2 of component 60986 and
|
||||
* "urn:adsk.eagle:library:60968" references library 60986 without specifying a version.
|
||||
*
|
||||
* Autodesk Fusion can use a different format instead, e.g.:
|
||||
* "urn:adsk.wipprod:fs.file:vf.RSKzNVZVQPeDNm7Bnfr3WQ"
|
||||
*/
|
||||
struct EURN : public EAGLE_BASE
|
||||
{
|
||||
|
||||
@@ -72,7 +72,17 @@ EASYEDAPRO::ProjectToSelectorDialog( const nlohmann::json& aProject, bool aPcbOn
|
||||
|
||||
std::map<wxString, EASYEDAPRO::PRJ_SCHEMATIC> prjSchematics = aProject.at( "schematics" );
|
||||
std::map<wxString, EASYEDAPRO::PRJ_BOARD> prjBoards = aProject.at( "boards" );
|
||||
std::map<wxString, wxString> prjPcbNames = aProject.at( "pcbs" );
|
||||
|
||||
std::map<wxString, wxString> prjPcbNames;
|
||||
std::map<wxString, nlohmann::json> prjPcbs = aProject.at( "pcbs" );
|
||||
|
||||
for( const auto& [pcbUuid, pcbJsonEntry] : prjPcbs )
|
||||
{
|
||||
if( pcbJsonEntry.is_string() )
|
||||
prjPcbNames.emplace( pcbUuid, pcbJsonEntry );
|
||||
else if( pcbJsonEntry.is_object() )
|
||||
prjPcbNames.emplace( pcbUuid, pcbJsonEntry.at( "title" ) );
|
||||
}
|
||||
|
||||
for( const auto& [prjName, board] : prjBoards )
|
||||
{
|
||||
|
||||
@@ -220,7 +220,7 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_SYMBOL& d )
|
||||
if( j.at( "type" ).is_number() )
|
||||
d.type = j.at( "type" );
|
||||
|
||||
if( j.at( "tags" ).is_object() )
|
||||
if( j.find( "tags" ) != j.end() && j.at( "tags" ).is_object() )
|
||||
d.tags = j.at( "tags" );
|
||||
|
||||
if( j.find( "custom_tags" ) != j.end() && j.at( "custom_tags" ).is_object() )
|
||||
@@ -249,7 +249,7 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_FOOTPRINT&
|
||||
if( j.at( "type" ).is_number() )
|
||||
d.type = j.at( "type" );
|
||||
|
||||
if( j.at( "tags" ).is_object() )
|
||||
if( j.find( "tags" ) != j.end() && j.at( "tags" ).is_object() )
|
||||
d.tags = j.at( "tags" );
|
||||
|
||||
if( j.find( "custom_tags" ) != j.end() && j.at( "custom_tags" ).is_object() )
|
||||
@@ -275,7 +275,7 @@ void EASYEDAPRO::from_json( const nlohmann::json& j, EASYEDAPRO::PRJ_DEVICE& d )
|
||||
if( j.at( "version" ).is_string() )
|
||||
d.version = j.at( "version" ).get<wxString>();
|
||||
|
||||
if( j.at( "tags" ).is_object() )
|
||||
if( j.find( "tags" ) != j.end() && j.at( "tags" ).is_object() )
|
||||
d.tags = j.at( "tags" );
|
||||
|
||||
if( j.find( "custom_tags" ) != j.end() && j.at( "custom_tags" ).is_object() )
|
||||
|
||||
@@ -41,7 +41,7 @@ JOB_EXPORT_PCB_ODB::JOB_EXPORT_PCB_ODB() :
|
||||
m_filename(),
|
||||
m_drawingSheet(),
|
||||
m_units( ODB_UNITS::MM ),
|
||||
m_precision( 2 ),
|
||||
m_precision( 4 ),
|
||||
m_compressionMode( ODB_COMPRESSION::ZIP )
|
||||
{
|
||||
m_params.emplace_back( new JOB_PARAM<wxString>( "drawing_sheet", &m_drawingSheet, m_drawingSheet ) );
|
||||
|
||||
@@ -85,6 +85,7 @@ JOB_PCB_RENDER::JOB_PCB_RENDER() :
|
||||
{
|
||||
m_params.emplace_back( new JOB_PARAM<FORMAT>( "format", &m_format, m_format ) );
|
||||
m_params.emplace_back( new JOB_PARAM<std::string>( "preset", &m_appearancePreset, m_appearancePreset ) );
|
||||
m_params.emplace_back( new JOB_PARAM<bool>( "use_board_stackup_colors", &m_useBoardStackupColors, m_useBoardStackupColors ) );
|
||||
m_params.emplace_back( new JOB_PARAM<QUALITY>( "quality", &m_quality, m_quality ) );
|
||||
m_params.emplace_back( new JOB_PARAM<BG_STYLE>( "bg_style", &m_bgStyle, m_bgStyle ) );
|
||||
m_params.emplace_back( new JOB_PARAM<SIDE>( "side", &m_side, m_side ) );
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
std::string m_appearancePreset;
|
||||
bool m_useBoardStackupColors = true;
|
||||
SIDE m_side = SIDE::TOP;
|
||||
double m_zoom = 1.0;
|
||||
bool m_perspective = false;
|
||||
|
||||
@@ -39,7 +39,7 @@ JOB_RC::JOB_RC( const std::string& aType ) :
|
||||
m_units( JOB_RC::UNITS::MM ),
|
||||
m_severity( RPT_SEVERITY_ERROR | RPT_SEVERITY_WARNING ),
|
||||
m_format( OUTPUT_FORMAT::REPORT ),
|
||||
m_exitCodeViolations( false )
|
||||
m_exitCodeViolations( true ) // this ensures GUI jobs default to treat violations as job failure, cli will default false elsewhere
|
||||
{
|
||||
m_params.emplace_back( new JOB_PARAM<UNITS>( "units", &m_units, m_units ) );
|
||||
m_params.emplace_back( new JOB_PARAM<int>( "severity", &m_severity, m_severity ) );
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <wx/zipstrm.h>
|
||||
#include <gestfich.h>
|
||||
#include <common.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
JOBS_OUTPUT_ARCHIVE::JOBS_OUTPUT_ARCHIVE() :
|
||||
JOBS_OUTPUT_HANDLER(),
|
||||
@@ -52,6 +53,8 @@ bool JOBS_OUTPUT_ARCHIVE::HandleOutputs( const wxString& baseTempPath, PROJECT*
|
||||
if( outputPath.StartsWith( "~" ) )
|
||||
outputPath.Replace( "~", wxGetHomeDir(), false );
|
||||
|
||||
outputPath = EnsureFileExtension( outputPath, FILEEXT::ArchiveFileExtension );
|
||||
|
||||
wxFFileOutputStream ostream( outputPath );
|
||||
|
||||
if( !ostream.IsOk() ) // issue to create the file. Perhaps not writable dir
|
||||
|
||||
@@ -134,29 +134,12 @@ LIB_TREE_NODE::LIB_TREE_NODE()
|
||||
|
||||
LIB_TREE_NODE_UNIT::LIB_TREE_NODE_UNIT( LIB_TREE_NODE* aParent, LIB_TREE_ITEM* aItem, int aUnit )
|
||||
{
|
||||
static void* locale = nullptr;
|
||||
static wxString namePrefix;
|
||||
|
||||
// Fetching translations can take a surprising amount of time when loading libraries,
|
||||
// so only do it when necessary.
|
||||
if( Pgm().GetLocale() != locale )
|
||||
{
|
||||
namePrefix = _( "Unit" );
|
||||
locale = Pgm().GetLocale();
|
||||
}
|
||||
|
||||
m_Parent = aParent;
|
||||
m_Type = TYPE::UNIT;
|
||||
|
||||
m_Unit = aUnit;
|
||||
m_LibId = aParent->m_LibId;
|
||||
|
||||
m_Name = namePrefix + " " + aItem->GetUnitReference( aUnit );
|
||||
|
||||
if( aItem->HasUnitDisplayName( aUnit ) )
|
||||
m_Desc = aItem->GetUnitDisplayName( aUnit );
|
||||
else
|
||||
m_Desc = wxEmptyString;
|
||||
m_Name = aItem->GetUnitName( aUnit );
|
||||
|
||||
m_IntrinsicRank = -aUnit;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <wx/wupdlock.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/dc.h>
|
||||
#include <wx/log.h>
|
||||
#include <string_utils.h>
|
||||
|
||||
|
||||
@@ -308,6 +309,15 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool a
|
||||
|
||||
const LIB_TREE_NODE* firstMatch = ShowResults();
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// Ensure the control is repainted with the updated data. Without an explicit
|
||||
// refresh the Gtk port can display stale rows until the user interacts with
|
||||
// them, leading to mismatched tree contents.
|
||||
m_widget->Refresh();
|
||||
m_widget->Update();
|
||||
wxYield();
|
||||
#endif
|
||||
|
||||
if( firstMatch )
|
||||
{
|
||||
wxDataViewItem item = ToItem( firstMatch );
|
||||
|
||||
@@ -1150,7 +1150,9 @@ void UOP::Exec( CONTEXT* ctx )
|
||||
return;
|
||||
|
||||
case TR_OP_METHOD_CALL:
|
||||
m_func( ctx, m_ref.get() );
|
||||
if( m_func )
|
||||
m_func( ctx, m_ref.get() );
|
||||
|
||||
return;
|
||||
|
||||
default:
|
||||
@@ -1283,9 +1285,8 @@ VALUE* UCODE::Run( CONTEXT* ctx )
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
// rules which fail outright should not be fired
|
||||
std::unique_ptr<VALUE> temp_false = std::make_unique<VALUE>( 0 );
|
||||
return ctx->StoreValue( temp_false.get() );
|
||||
// rules which fail outright should not be fired; return 0/false
|
||||
return ctx->StoreValue( new VALUE( 0 ) );
|
||||
}
|
||||
|
||||
if( ctx->SP() == 1 )
|
||||
@@ -1301,8 +1302,7 @@ VALUE* UCODE::Run( CONTEXT* ctx )
|
||||
wxASSERT( ctx->SP() == 1 );
|
||||
|
||||
// non-well-formed rules should not be fired on a release build
|
||||
std::unique_ptr<VALUE> temp_false = std::make_unique<VALUE>( 0 );
|
||||
return ctx->StoreValue( temp_false.get() );
|
||||
return ctx->StoreValue( new VALUE( 0 ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -278,7 +278,7 @@ bool NETCLASS::ContainsNetclassWithName( const wxString& netclass ) const
|
||||
return std::any_of( m_constituents.begin(), m_constituents.end(),
|
||||
[&netclass]( const NETCLASS* nc )
|
||||
{
|
||||
return nc && nc->GetName() == netclass;
|
||||
return nc && nc->GetName().Matches( netclass );
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/utils.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
#include <kiplatform/environment.h>
|
||||
#include <paths.h>
|
||||
@@ -502,6 +503,25 @@ void PATHS::EnsureUserPathsExist()
|
||||
EnsurePathExists( GetDefaultUserFootprintsPath() );
|
||||
EnsurePathExists( GetDefaultUser3DModelsPath() );
|
||||
EnsurePathExists( GetDefault3rdPartyPath() );
|
||||
|
||||
#ifdef _WIN32
|
||||
// Warn about Controlled folder access
|
||||
wxFileName tmp;
|
||||
getUserDocumentPath( tmp );
|
||||
|
||||
if( !tmp.DirExists() )
|
||||
{
|
||||
wxString msg = wxString::Format(
|
||||
_( "KiCad was unable to use '%s'.\n"
|
||||
"\n"
|
||||
"1. Disable 'Controlled folder access' in Windows settings or Group Policy\n"
|
||||
"2. Make sure no other antivirus software interferes with KiCad\n"
|
||||
"3. Make sure you have correct permissions set up" ),
|
||||
tmp.GetPath() );
|
||||
|
||||
wxMessageBox( msg, _( "Warning" ), wxICON_WARNING );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -55,6 +55,31 @@ enum class ELECTRICAL_PINTYPE
|
||||
|
||||
#define ELECTRICAL_PINTYPES_TOTAL ( static_cast<int>( ELECTRICAL_PINTYPE::PT_LAST_OPTION ) + 1 )
|
||||
|
||||
inline wxString GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE aType )
|
||||
{
|
||||
// These strings are the canonical name of the electrictal type
|
||||
// Not translated, no space in name, only ASCII chars.
|
||||
// to use when the string name must be known and well defined
|
||||
// must have same order than enum ELECTRICAL_PINTYPE (see sch_pin.h)
|
||||
static const wxChar* msgPinElectricType[] =
|
||||
{
|
||||
wxT( "input" ),
|
||||
wxT( "output" ),
|
||||
wxT( "bidirectional" ),
|
||||
wxT( "tri_state" ),
|
||||
wxT( "passive" ),
|
||||
wxT( "free" ),
|
||||
wxT( "unspecified" ),
|
||||
wxT( "power_in" ),
|
||||
wxT( "power_out" ),
|
||||
wxT( "open_collector" ),
|
||||
wxT( "open_emitter" ),
|
||||
wxT( "no_connect" )
|
||||
};
|
||||
|
||||
return msgPinElectricType[static_cast<int>( aType )];
|
||||
}
|
||||
|
||||
enum class GRAPHIC_PINSHAPE
|
||||
{
|
||||
LINE,
|
||||
@@ -415,7 +415,7 @@ void PDF_PLOTTER::PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFi
|
||||
if( aFill == FILL_T::NO_FILL )
|
||||
fputs( "S\n", m_workFile );
|
||||
else if( aWidth == 0 )
|
||||
fputs( "f\n", m_workFile );
|
||||
fputs( "h f\n", m_workFile );
|
||||
else
|
||||
fputs( "b\n", m_workFile );
|
||||
}
|
||||
|
||||
@@ -683,10 +683,10 @@ void SVG_PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double
|
||||
img_stream.CopyTo( buffer.data(), buffer.size() );
|
||||
base64::encode( buffer, encoded );
|
||||
|
||||
VECTOR2D pos = userToDeviceCoordinates( start );
|
||||
fprintf( m_outputFile,
|
||||
"<image x=\"%f\" y=\"%f\" xlink:href=\"data:image/png;base64,",
|
||||
userToDeviceSize( start.x ),
|
||||
userToDeviceSize( start.y ) );
|
||||
pos.x, pos.y );
|
||||
|
||||
for( size_t i = 0; i < encoded.size(); i++ )
|
||||
{
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "preview_items/construction_geom.h"
|
||||
|
||||
#include <layer_ids.h>
|
||||
#include <utility>
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <geometry/shape_utils.h>
|
||||
#include <preview_items/item_drawing_utils.h>
|
||||
@@ -39,9 +40,15 @@ CONSTRUCTION_GEOM::CONSTRUCTION_GEOM() :
|
||||
}
|
||||
|
||||
|
||||
void CONSTRUCTION_GEOM::AddDrawable( const DRAWABLE& aItem, bool aPersistent )
|
||||
void CONSTRUCTION_GEOM::AddDrawable( const DRAWABLE& aItem, bool aPersistent, int aLineWidth )
|
||||
{
|
||||
m_drawables.push_back( { aItem, aPersistent } );
|
||||
m_drawables.push_back( { aItem, aPersistent, aLineWidth } );
|
||||
}
|
||||
|
||||
|
||||
void CONSTRUCTION_GEOM::SetSnapGuides( std::vector<SNAP_GUIDE> aGuides )
|
||||
{
|
||||
m_snapGuides = std::move( aGuides );
|
||||
}
|
||||
|
||||
|
||||
@@ -90,6 +97,7 @@ void CONSTRUCTION_GEOM::ViewDraw( int aLayer, VIEW* aView ) const
|
||||
for( const DRAWABLE_INFO& drawable : m_drawables )
|
||||
{
|
||||
gal.SetStrokeColor( drawable.IsPersistent ? m_persistentColor : m_color );
|
||||
gal.SetLineWidth( drawable.LineWidth );
|
||||
|
||||
std::visit(
|
||||
[&]( const auto& visited )
|
||||
@@ -139,9 +147,17 @@ void CONSTRUCTION_GEOM::ViewDraw( int aLayer, VIEW* aView ) const
|
||||
drawable.Item );
|
||||
}
|
||||
|
||||
for( const SNAP_GUIDE& guide : m_snapGuides )
|
||||
{
|
||||
gal.SetStrokeColor( guide.Color );
|
||||
gal.SetLineWidth( guide.LineWidth );
|
||||
gal.DrawLine( guide.Segment.A, guide.Segment.B );
|
||||
}
|
||||
|
||||
if( haveSnapLine )
|
||||
{
|
||||
gal.SetStrokeColor( m_persistentColor );
|
||||
gal.SetLineWidth( 2 );
|
||||
|
||||
const int dashSizeBasis = aView->ToWorld( 12 );
|
||||
const int snapOriginMarkerSize = aView->ToWorld( 16 );
|
||||
|
||||
@@ -335,7 +335,86 @@ void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
|
||||
VECTOR2D rulerVec( end - origin );
|
||||
|
||||
wxArrayString cursorStrings = GetDimensionStrings();
|
||||
DrawTextNextToCursor( aView, end, -rulerVec, cursorStrings, drawingDropShadows );
|
||||
|
||||
// Choose a text quadrant that keeps the measurement text on-screen while avoiding
|
||||
// overlapping the ruler geometry. Start with the preferred direction (away from the
|
||||
// origin) and fall back to other quadrants as needed to keep the label visible.
|
||||
int prefX = rulerVec.y < 0.0 ? -1 : 1;
|
||||
int prefY = rulerVec.x < 0.0 ? 1 : -1;
|
||||
|
||||
double scale = gal->GetWorldScale();
|
||||
|
||||
TEXT_DIMS dims = GetConstantGlyphHeight( gal );
|
||||
KIFONT::FONT* font = KIFONT::FONT::GetFont();
|
||||
double width = 0.0;
|
||||
|
||||
for( const wxString& s : cursorStrings )
|
||||
{
|
||||
VECTOR2I extents = font->StringBoundaryLimits( s, dims.GlyphSize, dims.StrokeWidth, false, false,
|
||||
KIFONT::METRICS::Default() );
|
||||
width = std::max( width, (double) extents.x );
|
||||
}
|
||||
|
||||
double height = dims.LinePitch * cursorStrings.size();
|
||||
|
||||
// Convert to screen coordinates for visibility checks
|
||||
VECTOR2D cursorScreen = gal->ToScreen( end );
|
||||
VECTOR2I screenSize = gal->GetScreenPixelSize();
|
||||
double offsetX = 15.0; // same as DrawTextNextToCursor()
|
||||
double offsetY = dims.LinePitch * scale; // vertical spacing from cursor
|
||||
|
||||
auto fits = [&]( int sx, int sy )
|
||||
{
|
||||
double left, right, top, bottom;
|
||||
double xStart = cursorScreen.x + ( sx < 0 ? offsetX : -offsetX );
|
||||
|
||||
if( sx < 0 )
|
||||
{
|
||||
left = xStart;
|
||||
right = left + width * scale;
|
||||
}
|
||||
else
|
||||
{
|
||||
right = xStart;
|
||||
left = right - width * scale;
|
||||
}
|
||||
|
||||
if( sy > 0 ) // above cursor
|
||||
{
|
||||
bottom = cursorScreen.y - offsetY;
|
||||
top = bottom - height * scale;
|
||||
}
|
||||
else // below cursor
|
||||
{
|
||||
top = cursorScreen.y + offsetY;
|
||||
bottom = top + height * scale;
|
||||
}
|
||||
|
||||
return left >= 0 && right <= screenSize.x && top >= 0 && bottom <= screenSize.y;
|
||||
};
|
||||
|
||||
std::vector<VECTOR2I> candidates = { { prefX, prefY }, { -prefX, prefY },
|
||||
{ prefX, -prefY }, { -prefX, -prefY } };
|
||||
|
||||
VECTOR2I chosen = candidates[0];
|
||||
double bestDot = -1.0;
|
||||
|
||||
for( const VECTOR2I& c : candidates )
|
||||
{
|
||||
double dot = c.x * prefX + c.y * prefY;
|
||||
|
||||
if( dot >= 0 && fits( c.x, c.y ) )
|
||||
{
|
||||
if( dot > bestDot )
|
||||
{
|
||||
bestDot = dot;
|
||||
chosen = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VECTOR2D quadrant( chosen.x, chosen.y );
|
||||
DrawTextNextToCursor( aView, end, quadrant, cursorStrings, drawingDropShadows );
|
||||
|
||||
// basic tick size
|
||||
double minorTickLen = 5.0 / gal->GetWorldScale();
|
||||
|
||||
@@ -254,9 +254,11 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME*
|
||||
// Enum property
|
||||
if( aProperty->HasChoices() )
|
||||
{
|
||||
const_cast<PROPERTY_BASE*>( aProperty )->TranslateChoices();
|
||||
|
||||
// I do not know why enum property takes a non-const reference to wxPGChoices..
|
||||
ret = new wxEnumProperty( wxPG_LABEL, wxPG_LABEL,
|
||||
const_cast<wxPGChoices&>( aProperty->Choices() ) );
|
||||
const_cast<wxPGChoices&>( aProperty->Choices() ) );
|
||||
}
|
||||
else if( typeId == TYPE_HASH( int ) || typeId == TYPE_HASH( long ) )
|
||||
{
|
||||
|
||||
@@ -25,10 +25,15 @@
|
||||
#include <properties/property.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
#include <utility>
|
||||
#include <wx/wx.h>
|
||||
|
||||
static wxString EMPTY_STRING( wxEmptyString );
|
||||
|
||||
// Global to prevent simultaneous multi-threaded static initialization
|
||||
static const std::vector<PROPERTY_BASE*> EMPTY_PROP_LIST;
|
||||
static const std::map<PROPERTY_BASE*, int> EMPTY_PROP_DISPLAY_ORDER;
|
||||
std::vector<wxString> EMPTY_GROUP_DISPLAY_ORDER;
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::RegisterType( TYPE_ID aType, const wxString& aName )
|
||||
@@ -38,13 +43,6 @@ void PROPERTY_MANAGER::RegisterType( TYPE_ID aType, const wxString& aName )
|
||||
}
|
||||
|
||||
|
||||
const wxString& PROPERTY_MANAGER::ResolveType( TYPE_ID aType ) const
|
||||
{
|
||||
auto it = m_classNames.find( aType );
|
||||
return it != m_classNames.end() ? it->second : EMPTY_STRING;
|
||||
}
|
||||
|
||||
|
||||
PROPERTY_BASE* PROPERTY_MANAGER::GetProperty( TYPE_ID aType, const wxString& aProperty ) const
|
||||
{
|
||||
if( m_dirty )
|
||||
@@ -67,31 +65,29 @@ PROPERTY_BASE* PROPERTY_MANAGER::GetProperty( TYPE_ID aType, const wxString& aPr
|
||||
}
|
||||
|
||||
|
||||
const PROPERTY_LIST& PROPERTY_MANAGER::GetProperties( TYPE_ID aType ) const
|
||||
const std::vector<PROPERTY_BASE*>& PROPERTY_MANAGER::GetProperties( TYPE_ID aType ) const
|
||||
{
|
||||
if( m_dirty )
|
||||
const_cast<PROPERTY_MANAGER*>( this )->Rebuild();
|
||||
|
||||
static const PROPERTY_LIST empty;
|
||||
auto it = m_classes.find( aType );
|
||||
|
||||
if( it == m_classes.end() )
|
||||
return empty;
|
||||
return EMPTY_PROP_LIST;
|
||||
|
||||
return it->second.m_allProperties;
|
||||
}
|
||||
|
||||
|
||||
const PROPERTY_DISPLAY_ORDER& PROPERTY_MANAGER::GetDisplayOrder( TYPE_ID aType ) const
|
||||
const std::map<PROPERTY_BASE*, int>& PROPERTY_MANAGER::GetDisplayOrder( TYPE_ID aType ) const
|
||||
{
|
||||
if( m_dirty )
|
||||
const_cast<PROPERTY_MANAGER*>( this )->Rebuild();
|
||||
|
||||
static const PROPERTY_DISPLAY_ORDER empty;
|
||||
auto it = m_classes.find( aType );
|
||||
|
||||
if( it == m_classes.end() )
|
||||
return empty;
|
||||
return EMPTY_PROP_DISPLAY_ORDER;
|
||||
|
||||
return it->second.m_displayOrder;
|
||||
}
|
||||
@@ -102,11 +98,10 @@ const std::vector<wxString>& PROPERTY_MANAGER::GetGroupDisplayOrder( TYPE_ID aTy
|
||||
if( m_dirty )
|
||||
const_cast<PROPERTY_MANAGER*>( this )->Rebuild();
|
||||
|
||||
static const std::vector<wxString> empty;
|
||||
auto it = m_classes.find( aType );
|
||||
|
||||
if( it == m_classes.end() )
|
||||
return empty;
|
||||
return EMPTY_GROUP_DISPLAY_ORDER;
|
||||
|
||||
return it->second.m_groupDisplayOrder;
|
||||
}
|
||||
@@ -122,7 +117,7 @@ const void* PROPERTY_MANAGER::TypeCast( const void* aSource, TYPE_ID aBase, TYPE
|
||||
if( classDesc == m_classes.end() )
|
||||
return aSource;
|
||||
|
||||
auto& converters = classDesc->second.m_typeCasts;
|
||||
const std::map<TYPE_ID, std::unique_ptr<TYPE_CAST_BASE>>& converters = classDesc->second.m_typeCasts;
|
||||
auto converter = converters.find( aTarget );
|
||||
|
||||
if( converter == converters.end() ) // explicit type cast not found
|
||||
@@ -135,8 +130,9 @@ const void* PROPERTY_MANAGER::TypeCast( const void* aSource, TYPE_ID aBase, TYPE
|
||||
PROPERTY_BASE& PROPERTY_MANAGER::AddProperty( PROPERTY_BASE* aProperty, const wxString& aGroup )
|
||||
{
|
||||
const wxString& name = aProperty->Name();
|
||||
TYPE_ID hash = aProperty->OwnerHash();
|
||||
CLASS_DESC& classDesc = getClass( hash );
|
||||
TYPE_ID hash = aProperty->OwnerHash();
|
||||
CLASS_DESC& classDesc = getClass( hash );
|
||||
|
||||
classDesc.m_ownProperties.emplace( name, aProperty );
|
||||
classDesc.m_ownDisplayOrder.emplace_back( aProperty );
|
||||
|
||||
@@ -153,8 +149,8 @@ PROPERTY_BASE& PROPERTY_MANAGER::AddProperty( PROPERTY_BASE* aProperty, const wx
|
||||
}
|
||||
|
||||
|
||||
PROPERTY_BASE& PROPERTY_MANAGER::ReplaceProperty( size_t aBase, const wxString& aName,
|
||||
PROPERTY_BASE* aNew, const wxString& aGroup )
|
||||
PROPERTY_BASE& PROPERTY_MANAGER::ReplaceProperty( size_t aBase, const wxString& aName, PROPERTY_BASE* aNew,
|
||||
const wxString& aGroup )
|
||||
{
|
||||
CLASS_DESC& classDesc = getClass( aNew->OwnerHash() );
|
||||
classDesc.m_replaced.insert( std::make_pair( aBase, aName ) );
|
||||
@@ -164,31 +160,30 @@ PROPERTY_BASE& PROPERTY_MANAGER::ReplaceProperty( size_t aBase, const wxString&
|
||||
|
||||
void PROPERTY_MANAGER::AddTypeCast( TYPE_CAST_BASE* aCast )
|
||||
{
|
||||
TYPE_ID derivedHash = aCast->DerivedHash();
|
||||
TYPE_ID derivedHash = aCast->DerivedHash();
|
||||
CLASS_DESC& classDesc = getClass( aCast->BaseHash() );
|
||||
auto& typeCasts = classDesc.m_typeCasts;
|
||||
wxASSERT_MSG( typeCasts.count( derivedHash ) == 0, "Such converter already exists" );
|
||||
typeCasts.emplace( derivedHash, aCast );
|
||||
|
||||
wxASSERT_MSG( classDesc.m_typeCasts.count( derivedHash ) == 0, wxT( "Such converter already exists" ) );
|
||||
classDesc.m_typeCasts.emplace( derivedHash, aCast );
|
||||
}
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::InheritsAfter( TYPE_ID aDerived, TYPE_ID aBase )
|
||||
{
|
||||
wxASSERT_MSG( aDerived != aBase, "Class cannot inherit from itself" );
|
||||
wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot inherit from itself" ) );
|
||||
|
||||
CLASS_DESC& derived = getClass( aDerived );
|
||||
CLASS_DESC& base = getClass( aBase );
|
||||
derived.m_bases.push_back( base );
|
||||
derived.m_bases.push_back( getClass( aBase ) );
|
||||
m_dirty = true;
|
||||
|
||||
wxASSERT_MSG( derived.m_bases.size() == 1 || derived.m_typeCasts.count( aBase ) == 1,
|
||||
"You need to add a TYPE_CAST for classes inheriting from multiple bases" );
|
||||
wxT( "You need to add a TYPE_CAST for classes inheriting from multiple bases" ) );
|
||||
}
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::Mask( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName )
|
||||
{
|
||||
wxASSERT_MSG( aDerived != aBase, "Class cannot mask from itself" );
|
||||
wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot mask from itself" ) );
|
||||
|
||||
CLASS_DESC& derived = getClass( aDerived );
|
||||
derived.m_maskedBaseProperties.insert( std::make_pair( aBase, aName ) );
|
||||
@@ -196,11 +191,10 @@ void PROPERTY_MANAGER::Mask( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aN
|
||||
}
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase,
|
||||
const wxString& aName,
|
||||
void PROPERTY_MANAGER::OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName,
|
||||
std::function<bool( INSPECTABLE* )> aFunc )
|
||||
{
|
||||
wxASSERT_MSG( aDerived != aBase, "Class cannot override from itself" );
|
||||
wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot override from itself" ) );
|
||||
|
||||
CLASS_DESC& derived = getClass( aDerived );
|
||||
derived.m_availabilityOverrides[std::make_pair( aBase, aName )] = std::move( aFunc );
|
||||
@@ -208,11 +202,10 @@ void PROPERTY_MANAGER::OverrideAvailability( TYPE_ID aDerived, TYPE_ID aBase,
|
||||
}
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::OverrideWriteability( TYPE_ID aDerived, TYPE_ID aBase,
|
||||
const wxString& aName,
|
||||
void PROPERTY_MANAGER::OverrideWriteability( TYPE_ID aDerived, TYPE_ID aBase, const wxString& aName,
|
||||
std::function<bool( INSPECTABLE* )> aFunc )
|
||||
{
|
||||
wxASSERT_MSG( aDerived != aBase, "Class cannot override from itself" );
|
||||
wxASSERT_MSG( aDerived != aBase, wxT( "Class cannot override from itself" ) );
|
||||
|
||||
CLASS_DESC& derived = getClass( aDerived );
|
||||
derived.m_writeabilityOverrides[std::make_pair( aBase, aName )] = std::move( aFunc );
|
||||
@@ -220,16 +213,14 @@ void PROPERTY_MANAGER::OverrideWriteability( TYPE_ID aDerived, TYPE_ID aBase,
|
||||
}
|
||||
|
||||
|
||||
bool PROPERTY_MANAGER::IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp,
|
||||
INSPECTABLE* aItem )
|
||||
bool PROPERTY_MANAGER::IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, INSPECTABLE* aItem )
|
||||
{
|
||||
if( !aProp->Available( aItem ) )
|
||||
return false;
|
||||
|
||||
CLASS_DESC& derived = getClass( aItemClass );
|
||||
|
||||
auto it = derived.m_availabilityOverrides.find( std::make_pair( aProp->BaseHash(),
|
||||
aProp->Name() ) );
|
||||
auto it = derived.m_availabilityOverrides.find( std::make_pair( aProp->BaseHash(), aProp->Name() ) );
|
||||
|
||||
if( it != derived.m_availabilityOverrides.end() )
|
||||
return it->second( aItem );
|
||||
@@ -238,16 +229,14 @@ bool PROPERTY_MANAGER::IsAvailableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp,
|
||||
}
|
||||
|
||||
|
||||
bool PROPERTY_MANAGER::IsWriteableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp,
|
||||
INSPECTABLE* aItem )
|
||||
bool PROPERTY_MANAGER::IsWriteableFor( TYPE_ID aItemClass, PROPERTY_BASE* aProp, INSPECTABLE* aItem )
|
||||
{
|
||||
if( !aProp->Writeable( aItem ) )
|
||||
return false;
|
||||
|
||||
CLASS_DESC& derived = getClass( aItemClass );
|
||||
|
||||
auto it = derived.m_writeabilityOverrides.find( std::make_pair( aProp->BaseHash(),
|
||||
aProp->Name() ) );
|
||||
auto it = derived.m_writeabilityOverrides.find( std::make_pair( aProp->BaseHash(), aProp->Name() ) );
|
||||
|
||||
if( it != derived.m_writeabilityOverrides.end() )
|
||||
return it->second( aItem );
|
||||
@@ -265,7 +254,7 @@ bool PROPERTY_MANAGER::IsOfType( TYPE_ID aDerived, TYPE_ID aBase ) const
|
||||
wxCHECK( derived != m_classes.end(), false ); // missing class description
|
||||
|
||||
// traverse the hierarchy seeking for the base class
|
||||
for( auto& base : derived->second.m_bases )
|
||||
for( const std::reference_wrapper<CLASS_DESC>& base : derived->second.m_bases )
|
||||
{
|
||||
if( IsOfType( base.get().m_id, aBase ) )
|
||||
return true;
|
||||
@@ -297,8 +286,8 @@ PROPERTY_MANAGER::CLASS_DESC& PROPERTY_MANAGER::getClass( TYPE_ID aTypeId )
|
||||
|
||||
void PROPERTY_MANAGER::CLASS_DESC::rebuild()
|
||||
{
|
||||
PROPERTY_SET replaced;
|
||||
PROPERTY_SET masked;
|
||||
std::set<std::pair<size_t, wxString>> replaced;
|
||||
std::set<std::pair<size_t, wxString>> masked;
|
||||
m_allProperties.clear();
|
||||
collectPropsRecur( m_allProperties, replaced, m_displayOrder, masked );
|
||||
|
||||
@@ -338,10 +327,10 @@ void PROPERTY_MANAGER::CLASS_DESC::rebuild()
|
||||
}
|
||||
|
||||
|
||||
void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( PROPERTY_LIST& aResult,
|
||||
PROPERTY_SET& aReplaced,
|
||||
PROPERTY_DISPLAY_ORDER& aDisplayOrder,
|
||||
PROPERTY_SET& aMasked ) const
|
||||
void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( std::vector<PROPERTY_BASE*>& aResult,
|
||||
std::set<std::pair<size_t, wxString>>& aReplaced,
|
||||
std::map<PROPERTY_BASE*, int>& aDisplayOrder,
|
||||
std::set<std::pair<size_t, wxString>>& aMasked ) const
|
||||
{
|
||||
for( const std::pair<size_t, wxString>& replacedEntry : m_replaced )
|
||||
aReplaced.emplace( replacedEntry );
|
||||
@@ -371,8 +360,8 @@ void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( PROPERTY_LIST& aResult,
|
||||
|
||||
for( PROPERTY_BASE* property : m_ownDisplayOrder )
|
||||
{
|
||||
PROPERTY_SET::key_type propertyKey = std::make_pair( property->OwnerHash(),
|
||||
property->Name() );
|
||||
std::set<std::pair<size_t, wxString>>::key_type propertyKey = std::make_pair( property->OwnerHash(),
|
||||
property->Name() );
|
||||
// Do not store replaced properties
|
||||
if( aReplaced.count( propertyKey ) )
|
||||
continue;
|
||||
@@ -386,28 +375,8 @@ void PROPERTY_MANAGER::CLASS_DESC::collectPropsRecur( PROPERTY_LIST& aResult,
|
||||
}
|
||||
|
||||
// Iterate backwards so that replaced properties appear before base properties
|
||||
for( auto it = m_bases.rbegin(); it != m_bases.rend(); ++it )
|
||||
it->get().collectPropsRecur( aResult, aReplaced, aDisplayOrder, aMasked );
|
||||
}
|
||||
|
||||
|
||||
std::vector<TYPE_ID> PROPERTY_MANAGER::GetMatchingClasses( PROPERTY_BASE* aProperty )
|
||||
{
|
||||
std::vector<TYPE_ID> ids;
|
||||
|
||||
/*
|
||||
for( auto& cls : m_classes )
|
||||
{
|
||||
CLASS_INFO info;
|
||||
|
||||
for( auto prop : cls.second.m_allProperties )
|
||||
info.properties.push_back(prop);
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
return ids;
|
||||
for( std::reference_wrapper<CLASS_DESC> base : std::ranges::reverse_view( m_bases ) )
|
||||
base.get().collectPropsRecur( aResult, aReplaced, aDisplayOrder, aMasked );
|
||||
}
|
||||
|
||||
|
||||
@@ -458,7 +427,7 @@ void PROPERTY_MANAGER::PropertyChanged( INSPECTABLE* aObject, PROPERTY_BASE* aPr
|
||||
PROPERTY_COMMIT_HANDLER::PROPERTY_COMMIT_HANDLER( COMMIT* aCommit )
|
||||
{
|
||||
wxCHECK2_MSG( PROPERTY_MANAGER::Instance().m_managedCommit == nullptr,
|
||||
return, "Can't have more than one managed commit at a time!" );
|
||||
return, wxT( "Can't have more than one managed commit at a time!" ) );
|
||||
|
||||
PROPERTY_MANAGER::Instance().m_managedCommit = aCommit;
|
||||
}
|
||||
@@ -467,7 +436,7 @@ PROPERTY_COMMIT_HANDLER::PROPERTY_COMMIT_HANDLER( COMMIT* aCommit )
|
||||
PROPERTY_COMMIT_HANDLER::~PROPERTY_COMMIT_HANDLER()
|
||||
{
|
||||
wxASSERT_MSG( PROPERTY_MANAGER::Instance().m_managedCommit != nullptr,
|
||||
"Something went wrong: m_managedCommit already null!" );
|
||||
wxT( "Something went wrong: m_managedCommit already null!" ) );
|
||||
|
||||
PROPERTY_MANAGER::Instance().m_managedCommit = nullptr;
|
||||
}
|
||||
|
||||
@@ -174,6 +174,9 @@ void RC_ITEM::GetJsonViolation( RC_JSON::VIOLATION& aViolation, UNITS_PROVIDER*
|
||||
aViolation.type = GetSettingsKey();
|
||||
aViolation.excluded = ( m_parent && m_parent->IsExcluded() );
|
||||
|
||||
if( m_parent && m_parent->IsExcluded() && !m_parent->GetComment().IsEmpty() )
|
||||
aViolation.comment = m_parent->GetComment();
|
||||
|
||||
EDA_ITEM* mainItem = nullptr;
|
||||
EDA_ITEM* auxItem = nullptr;
|
||||
|
||||
|
||||
+11
-21
@@ -65,12 +65,6 @@ REPORTER& WX_TEXT_CTRL_REPORTER::Report( const wxString& aText, SEVERITY aSeveri
|
||||
}
|
||||
|
||||
|
||||
bool WX_TEXT_CTRL_REPORTER::HasMessage() const
|
||||
{
|
||||
return !m_textCtrl->IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
REPORTER& WX_STRING_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aText, aSeverity );
|
||||
@@ -93,12 +87,6 @@ void WX_STRING_REPORTER::Clear()
|
||||
}
|
||||
|
||||
|
||||
bool WX_STRING_REPORTER::HasMessage() const
|
||||
{
|
||||
return !m_string.IsEmpty();
|
||||
}
|
||||
|
||||
|
||||
REPORTER& NULL_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
return REPORTER::Report( aText, aSeverity );
|
||||
@@ -211,6 +199,17 @@ REPORTER& WXLOG_REPORTER::GetInstance()
|
||||
}
|
||||
|
||||
|
||||
REPORTER& REDIRECT_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aText, aSeverity );
|
||||
|
||||
if( m_redirectTarget )
|
||||
m_redirectTarget->Report( aText, aSeverity );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
REPORTER& STATUSBAR_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
|
||||
{
|
||||
REPORTER::Report( aText, aSeverity );
|
||||
@@ -220,12 +219,3 @@ REPORTER& STATUSBAR_REPORTER::Report( const wxString& aText, SEVERITY aSeverity
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool STATUSBAR_REPORTER::HasMessage() const
|
||||
{
|
||||
if( m_statusBar )
|
||||
return !m_statusBar->GetStatusText( m_position ).IsEmpty();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -799,6 +799,12 @@ TOOL_ACTION ACTIONS::unpinLibrary( TOOL_ACTION_ARGS()
|
||||
.FriendlyName( _( "Unpin Library" ) )
|
||||
.Tooltip( _( "No longer keep the library at the top of the list" ) ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::showLibraryTable( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.showLibraryTable" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Library Table" ) )
|
||||
.Icon( BITMAPS::table ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::showLibraryTree( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.showLibraryTree" )
|
||||
.Scope( AS_GLOBAL )
|
||||
|
||||
@@ -23,12 +23,21 @@
|
||||
|
||||
#include "tool/construction_manager.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <numeric>
|
||||
#include <utility>
|
||||
|
||||
#include <wx/timer.h>
|
||||
#include <wx/debug.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <math/util.h>
|
||||
#include <hash.h>
|
||||
#include <trace_helpers.h>
|
||||
|
||||
|
||||
/**
|
||||
@@ -329,9 +338,9 @@ void CONSTRUCTION_MANAGER::acceptConstructionItems( std::unique_ptr<PENDING_BATC
|
||||
{
|
||||
for( const CONSTRUCTION_ITEM& item : batch )
|
||||
{
|
||||
for( const KIGFX::CONSTRUCTION_GEOM::DRAWABLE& drawable : item.Constructions )
|
||||
for( const CONSTRUCTION_ITEM::DRAWABLE_ENTRY& drawable : item.Constructions )
|
||||
{
|
||||
geom.AddDrawable( drawable, aIsPersistent );
|
||||
geom.AddDrawable( drawable.Drawable, aIsPersistent, drawable.LineWidth );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -383,16 +392,111 @@ bool CONSTRUCTION_MANAGER::HasActiveConstruction() const
|
||||
|
||||
|
||||
SNAP_LINE_MANAGER::SNAP_LINE_MANAGER( CONSTRUCTION_VIEW_HANDLER& aViewHandler ) :
|
||||
m_viewHandler( aViewHandler )
|
||||
m_viewHandler( aViewHandler ), m_snapManager( static_cast<SNAP_MANAGER*>( &aViewHandler ) )
|
||||
{
|
||||
wxASSERT( m_snapManager );
|
||||
SetDirections( { VECTOR2I( 1, 0 ), VECTOR2I( 0, 1 ) } );
|
||||
}
|
||||
|
||||
|
||||
static VECTOR2I normalizeDirection( const VECTOR2I& aDir )
|
||||
{
|
||||
if( aDir.x == 0 && aDir.y == 0 )
|
||||
return VECTOR2I( 0, 0 );
|
||||
|
||||
int dx = aDir.x;
|
||||
int dy = aDir.y;
|
||||
|
||||
int gcd = std::gcd( std::abs( dx ), std::abs( dy ) );
|
||||
|
||||
if( gcd > 0 )
|
||||
{
|
||||
dx /= gcd;
|
||||
dy /= gcd;
|
||||
}
|
||||
|
||||
if( dx < 0 || ( dx == 0 && dy < 0 ) )
|
||||
{
|
||||
dx = -dx;
|
||||
dy = -dy;
|
||||
}
|
||||
|
||||
return VECTOR2I( dx, dy );
|
||||
}
|
||||
|
||||
|
||||
static std::optional<int> findDirectionIndex( const std::vector<VECTOR2I>& aDirections,
|
||||
const VECTOR2I& aDelta )
|
||||
{
|
||||
VECTOR2I normalized = normalizeDirection( aDelta );
|
||||
|
||||
if( normalized.x == 0 && normalized.y == 0 )
|
||||
return std::nullopt;
|
||||
|
||||
for( size_t i = 0; i < aDirections.size(); ++i )
|
||||
{
|
||||
if( aDirections[i] == normalized )
|
||||
return static_cast<int>( i );
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
void SNAP_LINE_MANAGER::SetDirections( const std::vector<VECTOR2I>& aDirections )
|
||||
{
|
||||
std::vector<VECTOR2I> uniqueDirections;
|
||||
uniqueDirections.reserve( aDirections.size() );
|
||||
|
||||
for( const VECTOR2I& direction : aDirections )
|
||||
{
|
||||
VECTOR2I normalized = normalizeDirection( direction );
|
||||
|
||||
if( normalized.x == 0 && normalized.y == 0 )
|
||||
continue;
|
||||
|
||||
if( std::find( uniqueDirections.begin(), uniqueDirections.end(), normalized )
|
||||
== uniqueDirections.end() )
|
||||
{
|
||||
uniqueDirections.push_back( normalized );
|
||||
}
|
||||
}
|
||||
|
||||
if( uniqueDirections != m_directions )
|
||||
{
|
||||
m_directions = std::move( uniqueDirections );
|
||||
m_activeDirection.reset();
|
||||
|
||||
if( m_snapLineOrigin && m_snapLineEnd )
|
||||
{
|
||||
if( !findDirectionIndex( m_directions, *m_snapLineEnd - *m_snapLineOrigin ) )
|
||||
m_snapLineEnd.reset();
|
||||
}
|
||||
|
||||
if( m_directions.empty() )
|
||||
{
|
||||
ClearSnapLine();
|
||||
return;
|
||||
}
|
||||
|
||||
notifyGuideChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SNAP_LINE_MANAGER::SetSnapLineOrigin( const VECTOR2I& aOrigin )
|
||||
{
|
||||
// Setting the origin clears the snap line as the end point is no longer valid
|
||||
ClearSnapLine();
|
||||
if( m_snapLineOrigin && *m_snapLineOrigin == aOrigin && !m_snapLineEnd )
|
||||
{
|
||||
notifyGuideChange();
|
||||
return;
|
||||
}
|
||||
|
||||
m_snapLineOrigin = aOrigin;
|
||||
m_snapLineEnd.reset();
|
||||
m_activeDirection.reset();
|
||||
m_viewHandler.GetViewItem().ClearSnapLine();
|
||||
notifyGuideChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -402,12 +506,17 @@ void SNAP_LINE_MANAGER::SetSnapLineEnd( const OPT_VECTOR2I& aSnapEnd )
|
||||
{
|
||||
m_snapLineEnd = aSnapEnd;
|
||||
|
||||
if( m_snapLineEnd )
|
||||
m_activeDirection = findDirectionIndex( m_directions, *m_snapLineEnd - *m_snapLineOrigin );
|
||||
else
|
||||
m_activeDirection.reset();
|
||||
|
||||
if( m_snapLineEnd )
|
||||
m_viewHandler.GetViewItem().SetSnapLine( SEG{ *m_snapLineOrigin, *m_snapLineEnd } );
|
||||
else
|
||||
m_viewHandler.GetViewItem().ClearSnapLine();
|
||||
|
||||
m_viewHandler.updateView();
|
||||
notifyGuideChange();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,8 +525,9 @@ void SNAP_LINE_MANAGER::ClearSnapLine()
|
||||
{
|
||||
m_snapLineOrigin.reset();
|
||||
m_snapLineEnd.reset();
|
||||
m_activeDirection.reset();
|
||||
m_viewHandler.GetViewItem().ClearSnapLine();
|
||||
m_viewHandler.updateView();
|
||||
notifyGuideChange();
|
||||
}
|
||||
|
||||
|
||||
@@ -425,7 +535,7 @@ void SNAP_LINE_MANAGER::SetSnappedAnchor( const VECTOR2I& aAnchorPos )
|
||||
{
|
||||
if( m_snapLineOrigin.has_value() )
|
||||
{
|
||||
if( aAnchorPos.x == m_snapLineOrigin->x || aAnchorPos.y == m_snapLineOrigin->y )
|
||||
if( findDirectionIndex( m_directions, aAnchorPos - *m_snapLineOrigin ) )
|
||||
{
|
||||
SetSnapLineEnd( aAnchorPos );
|
||||
}
|
||||
@@ -444,93 +554,206 @@ void SNAP_LINE_MANAGER::SetSnappedAnchor( const VECTOR2I& aAnchorPos )
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the cursor has moved far enough away from the snap line origin to escape snapping
|
||||
* in the X direction.
|
||||
*
|
||||
* This is defined as within aEscapeRange of the snap line origin, and within aLongRangeEscapeAngle
|
||||
* of the vertical line passing through the snap line origin.
|
||||
*/
|
||||
static bool pointHasEscapedSnapLineX( const VECTOR2I& aCursor, const VECTOR2I& aSnapLineOrigin,
|
||||
int aEscapeRange, EDA_ANGLE aLongRangeEscapeAngle )
|
||||
{
|
||||
if( std::abs( aCursor.x - aSnapLineOrigin.x ) < aEscapeRange )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
EDA_ANGLE angle = EDA_ANGLE( aCursor - aSnapLineOrigin ) + EDA_ANGLE( 90, DEGREES_T );
|
||||
return std::abs( angle.Normalize90() ) > aLongRangeEscapeAngle;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* As above, but for the Y direction.
|
||||
*/
|
||||
static bool pointHasEscapedSnapLineY( const VECTOR2I& aCursor, const VECTOR2I& aSnapLineOrigin,
|
||||
int aEscapeRange, EDA_ANGLE aLongRangeEscapeAngle )
|
||||
{
|
||||
if( std::abs( aCursor.y - aSnapLineOrigin.y ) < aEscapeRange )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
EDA_ANGLE angle = EDA_ANGLE( aCursor - aSnapLineOrigin );
|
||||
return std::abs( angle.Normalize90() ) > aLongRangeEscapeAngle;
|
||||
}
|
||||
|
||||
|
||||
OPT_VECTOR2I SNAP_LINE_MANAGER::GetNearestSnapLinePoint( const VECTOR2I& aCursor,
|
||||
const VECTOR2I& aNearestGrid,
|
||||
std::optional<int> aDistToNearest,
|
||||
int aSnapRange ) const
|
||||
int aSnapRange,
|
||||
const VECTOR2D& aGridSize,
|
||||
const VECTOR2I& aGridOrigin ) const
|
||||
{
|
||||
// return std::nullopt;
|
||||
if( m_snapLineOrigin )
|
||||
wxLogTrace( traceSnap, "GetNearestSnapLinePoint: cursor=(%d, %d), nearestGrid=(%d, %d), distToNearest=%s, snapRange=%d",
|
||||
aCursor.x, aCursor.y, aNearestGrid.x, aNearestGrid.y,
|
||||
aDistToNearest ? wxString::Format( "%d", *aDistToNearest ) : wxString( "none" ), aSnapRange );
|
||||
|
||||
if( !m_snapLineOrigin || m_directions.empty() )
|
||||
{
|
||||
bool snapLine = false;
|
||||
VECTOR2I bestSnapPoint = aNearestGrid;
|
||||
wxLogTrace( traceSnap, " No snap line origin or no directions, returning nullopt" );
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// If there's no snap anchor, or it's too far away, prefer the grid
|
||||
const bool gridBetterThanNearest = !aDistToNearest || *aDistToNearest > aSnapRange;
|
||||
const bool gridBetterThanNearest = !aDistToNearest || *aDistToNearest > aSnapRange;
|
||||
const bool gridActive = aGridSize.x > 0 && aGridSize.y > 0;
|
||||
|
||||
// The escape range is how far you go before the snap line is de-activated.
|
||||
// Make this a bit more forgiving than the snap range, as you can easily cancel
|
||||
// deliberately with a mouse move.
|
||||
// These are both a bit arbitrary, and can be adjusted as preferred
|
||||
const int escapeRange = 2 * aSnapRange;
|
||||
const EDA_ANGLE longRangeEscapeAngle( 4, DEGREES_T );
|
||||
wxLogTrace( traceSnap, " snapLineOrigin=(%d, %d), directions count=%zu, gridBetterThanNearest=%d, gridActive=%d",
|
||||
m_snapLineOrigin->x, m_snapLineOrigin->y, m_directions.size(), gridBetterThanNearest, gridActive );
|
||||
|
||||
const bool escapedX = pointHasEscapedSnapLineX( aCursor, *m_snapLineOrigin, escapeRange,
|
||||
longRangeEscapeAngle );
|
||||
const bool escapedY = pointHasEscapedSnapLineY( aCursor, *m_snapLineOrigin, escapeRange,
|
||||
longRangeEscapeAngle );
|
||||
if( !gridBetterThanNearest )
|
||||
{
|
||||
wxLogTrace( traceSnap, " Grid not better than nearest, returning nullopt" );
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
/// Allows de-snapping from the line if you are closer to another snap point
|
||||
/// Or if you have moved far enough away from the line
|
||||
if( !escapedX && gridBetterThanNearest )
|
||||
const int escapeRange = 2 * aSnapRange;
|
||||
const EDA_ANGLE longRangeEscapeAngle( 4, DEGREES_T );
|
||||
|
||||
wxLogTrace( traceSnap, " escapeRange=%d, longRangeEscapeAngle=%.1f deg",
|
||||
escapeRange, longRangeEscapeAngle.AsDegrees() );
|
||||
|
||||
const VECTOR2D origin( *m_snapLineOrigin );
|
||||
const VECTOR2D cursor( aCursor );
|
||||
const VECTOR2D delta = cursor - origin;
|
||||
|
||||
double bestPerpDistance = std::numeric_limits<double>::max();
|
||||
std::optional<VECTOR2I> bestSnapPoint;
|
||||
|
||||
for( size_t ii = 0; ii < m_directions.size(); ++ii )
|
||||
{
|
||||
const VECTOR2I& direction = m_directions[ii];
|
||||
VECTOR2D dirVector( direction );
|
||||
double dirLength = dirVector.EuclideanNorm();
|
||||
|
||||
if( dirLength == 0.0 )
|
||||
{
|
||||
bestSnapPoint.x = m_snapLineOrigin->x;
|
||||
snapLine = true;
|
||||
wxLogTrace( traceSnap, " Direction %zu: zero length, skipping", ii );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !escapedY && gridBetterThanNearest )
|
||||
VECTOR2D dirUnit = dirVector / dirLength;
|
||||
|
||||
double distanceAlong = delta.Dot( dirUnit );
|
||||
VECTOR2D projection = origin + dirUnit * distanceAlong;
|
||||
VECTOR2D offset = delta - dirUnit * distanceAlong;
|
||||
double perpDistance = offset.EuclideanNorm();
|
||||
|
||||
wxLogTrace( traceSnap, " Direction %zu: dir=(%d, %d), perpDist=%.1f, distAlong=%.1f",
|
||||
ii, direction.x, direction.y, perpDistance, distanceAlong );
|
||||
|
||||
if( perpDistance > aSnapRange )
|
||||
{
|
||||
bestSnapPoint.y = m_snapLineOrigin->y;
|
||||
snapLine = true;
|
||||
wxLogTrace( traceSnap, " perpDistance > snapRange, skipping" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( snapLine )
|
||||
bool escaped = false;
|
||||
|
||||
if( perpDistance >= escapeRange )
|
||||
{
|
||||
return bestSnapPoint;
|
||||
EDA_ANGLE deltaAngle( delta );
|
||||
EDA_ANGLE directionAngle( dirVector );
|
||||
double angleDiff = ( deltaAngle - directionAngle ).Normalize180().AsDegrees();
|
||||
|
||||
wxLogTrace( traceSnap, " In escape range: deltaAngle=%.1f, dirAngle=%.1f, angleDiff=%.1f",
|
||||
deltaAngle.AsDegrees(), directionAngle.AsDegrees(), angleDiff );
|
||||
|
||||
if( std::abs( angleDiff ) > longRangeEscapeAngle.AsDegrees() )
|
||||
{
|
||||
escaped = true;
|
||||
wxLogTrace( traceSnap, " ESCAPED (angle diff too large)" );
|
||||
}
|
||||
}
|
||||
|
||||
if( escaped )
|
||||
{
|
||||
wxLogTrace( traceSnap, " Not updating (escaped)" );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Now snap the projection to the grid if the grid is active
|
||||
VECTOR2D snapPoint = projection;
|
||||
|
||||
if( gridActive )
|
||||
{
|
||||
// For horizontal/vertical lines, snap to grid intersections
|
||||
if( direction.x == 0 && direction.y != 0 )
|
||||
{
|
||||
// Vertical line: keep origin X, snap Y to grid
|
||||
snapPoint.x = origin.x;
|
||||
snapPoint.y = aNearestGrid.y;
|
||||
wxLogTrace( traceSnap, " Vertical line: snapping to grid Y, snapPoint=(%.1f, %.1f)",
|
||||
snapPoint.x, snapPoint.y );
|
||||
}
|
||||
else if( direction.y == 0 && direction.x != 0 )
|
||||
{
|
||||
// Horizontal line: snap X to grid, keep origin Y
|
||||
snapPoint.x = aNearestGrid.x;
|
||||
snapPoint.y = origin.y;
|
||||
wxLogTrace( traceSnap, " Horizontal line: snapping to grid X, snapPoint=(%.1f, %.1f)",
|
||||
snapPoint.x, snapPoint.y );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Diagonal line: find nearest grid intersection along the line
|
||||
VECTOR2D gridOriginD( aGridOrigin );
|
||||
VECTOR2D relProjection = projection - gridOriginD;
|
||||
|
||||
// Find nearby grid points (check 3x3 grid around projection)
|
||||
double bestGridScore = std::numeric_limits<double>::max();
|
||||
VECTOR2D bestGridPoint = projection;
|
||||
|
||||
for( int dx = -1; dx <= 1; ++dx )
|
||||
{
|
||||
for( int dy = -1; dy <= 1; ++dy )
|
||||
{
|
||||
double gridX = std::round( relProjection.x / aGridSize.x ) * aGridSize.x + dx * aGridSize.x;
|
||||
double gridY = std::round( relProjection.y / aGridSize.y ) * aGridSize.y + dy * aGridSize.y;
|
||||
VECTOR2D gridPt( gridX + gridOriginD.x, gridY + gridOriginD.y );
|
||||
|
||||
// Calculate perpendicular distance from grid point to construction line
|
||||
VECTOR2D gridDelta = gridPt - origin;
|
||||
double gridDistAlong = gridDelta.Dot( dirUnit );
|
||||
VECTOR2D gridProjection = origin + dirUnit * gridDistAlong;
|
||||
double gridPerpDist = ( gridPt - gridProjection ).EuclideanNorm();
|
||||
|
||||
// Also consider distance from cursor
|
||||
double distFromCursor = ( gridPt - cursor ).EuclideanNorm();
|
||||
|
||||
// Prefer grid points that are close to the line and close to cursor
|
||||
double score = gridPerpDist + distFromCursor * 0.1;
|
||||
|
||||
if( score < bestGridScore )
|
||||
{
|
||||
bestGridScore = score;
|
||||
bestGridPoint = gridPt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
snapPoint = bestGridPoint;
|
||||
wxLogTrace( traceSnap, " Diagonal line: snapping to grid intersection, snapPoint=(%.1f, %.1f)",
|
||||
snapPoint.x, snapPoint.y );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( traceSnap, " Grid not active, using projection" );
|
||||
}
|
||||
|
||||
if( perpDistance < bestPerpDistance )
|
||||
{
|
||||
bestPerpDistance = perpDistance;
|
||||
bestSnapPoint = VECTOR2I( KiROUND( snapPoint.x ), KiROUND( snapPoint.y ) );
|
||||
wxLogTrace( traceSnap, " NEW BEST: perpDist=%.1f, snapPoint=(%d, %d)",
|
||||
bestPerpDistance, bestSnapPoint->x, bestSnapPoint->y );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( traceSnap, " Not updating (perpDist=%.1f >= bestPerp=%.1f)",
|
||||
perpDistance, bestPerpDistance );
|
||||
}
|
||||
}
|
||||
|
||||
if( bestSnapPoint )
|
||||
{
|
||||
wxLogTrace( traceSnap, " RETURNING bestSnapPoint=(%d, %d)", bestSnapPoint->x, bestSnapPoint->y );
|
||||
return *bestSnapPoint;
|
||||
}
|
||||
|
||||
wxLogTrace( traceSnap, " RETURNING nullopt (no valid snap found)" );
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
void SNAP_LINE_MANAGER::notifyGuideChange()
|
||||
{
|
||||
if( m_snapManager )
|
||||
m_snapManager->UpdateSnapGuides();
|
||||
}
|
||||
|
||||
|
||||
SNAP_MANAGER::SNAP_MANAGER( KIGFX::CONSTRUCTION_GEOM& aHelper ) :
|
||||
CONSTRUCTION_VIEW_HANDLER( aHelper ), m_snapLineManager( *this ),
|
||||
m_constructionManager( *this )
|
||||
m_constructionManager( *this ), m_snapGuideColor( KIGFX::COLOR4D::WHITE ),
|
||||
m_snapGuideHighlightColor( KIGFX::COLOR4D::WHITE )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -540,13 +763,67 @@ void SNAP_MANAGER::updateView()
|
||||
if( m_updateCallback )
|
||||
{
|
||||
bool showAnything = m_constructionManager.HasActiveConstruction()
|
||||
|| m_snapLineManager.HasCompleteSnapLine();
|
||||
|| m_snapLineManager.HasCompleteSnapLine()
|
||||
|| ( m_snapLineManager.GetSnapLineOrigin()
|
||||
&& !m_snapLineManager.GetDirections().empty() );
|
||||
|
||||
m_updateCallback( showAnything );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SNAP_MANAGER::SetSnapGuideColors( const KIGFX::COLOR4D& aBase, const KIGFX::COLOR4D& aHighlight )
|
||||
{
|
||||
m_snapGuideColor = aBase;
|
||||
m_snapGuideHighlightColor = aHighlight;
|
||||
UpdateSnapGuides();
|
||||
}
|
||||
|
||||
|
||||
void SNAP_MANAGER::UpdateSnapGuides()
|
||||
{
|
||||
std::vector<KIGFX::CONSTRUCTION_GEOM::SNAP_GUIDE> guides;
|
||||
|
||||
const OPT_VECTOR2I& origin = m_snapLineManager.GetSnapLineOrigin();
|
||||
const std::vector<VECTOR2I>& directions = m_snapLineManager.GetDirections();
|
||||
|
||||
if( origin && !directions.empty() )
|
||||
{
|
||||
const std::optional<int> activeDirection = m_snapLineManager.GetActiveDirection();
|
||||
const int guideLength = 500000;
|
||||
|
||||
for( size_t ii = 0; ii < directions.size(); ++ii )
|
||||
{
|
||||
const VECTOR2I& direction = directions[ii];
|
||||
|
||||
if( direction.x == 0 && direction.y == 0 )
|
||||
continue;
|
||||
|
||||
VECTOR2I scaled = direction * guideLength;
|
||||
|
||||
KIGFX::CONSTRUCTION_GEOM::SNAP_GUIDE guide;
|
||||
guide.Segment = SEG( *origin - scaled, *origin + scaled );
|
||||
|
||||
if( activeDirection && *activeDirection == static_cast<int>( ii ) )
|
||||
{
|
||||
guide.LineWidth = 2;
|
||||
guide.Color = m_snapGuideHighlightColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
guide.LineWidth = 1;
|
||||
guide.Color = m_snapGuideColor;
|
||||
}
|
||||
|
||||
guides.push_back( guide );
|
||||
}
|
||||
}
|
||||
|
||||
GetViewItem().SetSnapGuides( std::move( guides ) );
|
||||
updateView();
|
||||
}
|
||||
|
||||
|
||||
std::vector<CONSTRUCTION_MANAGER::CONSTRUCTION_ITEM_BATCH>
|
||||
SNAP_MANAGER::GetConstructionItems() const
|
||||
{
|
||||
@@ -566,14 +843,44 @@ SNAP_MANAGER::GetConstructionItems() const
|
||||
{},
|
||||
} );
|
||||
|
||||
// One horizontal and one vertical infinite line from the snap point
|
||||
snapPointItem.Constructions.push_back(
|
||||
LINE{ *snapLineOrigin, *snapLineOrigin + VECTOR2I( 100000, 0 ) } );
|
||||
snapPointItem.Constructions.push_back(
|
||||
LINE{ *snapLineOrigin, *snapLineOrigin + VECTOR2I( 0, 100000 ) } );
|
||||
const std::vector<VECTOR2I>& directions = m_snapLineManager.GetDirections();
|
||||
const std::optional<int> activeDirection = m_snapLineManager.GetActiveDirection();
|
||||
|
||||
batches.push_back( std::move( batch ) );
|
||||
for( size_t ii = 0; ii < directions.size(); ++ii )
|
||||
{
|
||||
const VECTOR2I& direction = directions[ii];
|
||||
|
||||
VECTOR2I scaledDirection = direction * 100000;
|
||||
|
||||
CONSTRUCTION_MANAGER::CONSTRUCTION_ITEM::DRAWABLE_ENTRY entry;
|
||||
entry.Drawable = LINE{ *snapLineOrigin, *snapLineOrigin + scaledDirection };
|
||||
entry.LineWidth = ( activeDirection && *activeDirection == static_cast<int>( ii ) ) ? 2 : 1;
|
||||
|
||||
snapPointItem.Constructions.push_back( entry );
|
||||
}
|
||||
|
||||
if( !snapPointItem.Constructions.empty() )
|
||||
batches.push_back( std::move( batch ) );
|
||||
}
|
||||
|
||||
return batches;
|
||||
}
|
||||
|
||||
|
||||
void CONSTRUCTION_MANAGER::Clear()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( m_batchesMutex );
|
||||
|
||||
m_persistentConstructionBatch.reset();
|
||||
m_temporaryConstructionBatches.clear();
|
||||
m_involvedItems.clear();
|
||||
CancelProposal();
|
||||
}
|
||||
|
||||
|
||||
void SNAP_MANAGER::Clear()
|
||||
{
|
||||
m_snapLineManager.ClearSnapLine();
|
||||
m_constructionManager.Clear();
|
||||
UpdateSnapGuides();
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ void EC_45DEGREE::Apply( EDIT_POINT& aHandle, const GRID_HELPER& aGrid )
|
||||
VECTOR2I lineVector( aHandle.GetPosition() - m_constrainer.GetPosition() );
|
||||
VECTOR2I newLineVector = GetVectorSnapped45( lineVector );
|
||||
|
||||
if( aHandle.GetGridConstraint() == SNAP_TO_GRID
|
||||
if( aHandle.GetGridConstraint() == SNAP_TO_GRID && !aGrid.GetSnappedPoint()
|
||||
&& ( newLineVector.x == 0 || newLineVector.y == 0 ) )
|
||||
{
|
||||
VECTOR2I snap = aGrid.AlignGrid( m_constrainer.GetPosition() + newLineVector );
|
||||
|
||||
+273
-28
@@ -24,21 +24,23 @@
|
||||
#include "tool/grid_helper.h"
|
||||
|
||||
#include <functional>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
#include <advanced_config.h>
|
||||
#include <trace_helpers.h>
|
||||
#include <wx/log.h>
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <gal/painter.h>
|
||||
#include <math/util.h> // for KiROUND
|
||||
#include <math/vector2d.h>
|
||||
#include <render_settings.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tool/tools_holder.h>
|
||||
#include <view/view.h>
|
||||
#include <settings/app_settings.h>
|
||||
|
||||
|
||||
GRID_HELPER::GRID_HELPER( TOOL_MANAGER* aToolMgr, int aConstructionLayer ) :
|
||||
m_toolMgr( aToolMgr ), m_snapManager( m_constructionGeomPreview )
|
||||
GRID_HELPER::GRID_HELPER() :
|
||||
m_toolMgr( nullptr ), m_snapManager( m_constructionGeomPreview )
|
||||
{
|
||||
m_maskTypes = ALL;
|
||||
m_enableSnap = true;
|
||||
@@ -46,12 +48,23 @@ GRID_HELPER::GRID_HELPER( TOOL_MANAGER* aToolMgr, int aConstructionLayer ) :
|
||||
m_enableGrid = true;
|
||||
m_snapItem = std::nullopt;
|
||||
|
||||
KIGFX::VIEW* view = m_toolMgr->GetView();
|
||||
KIGFX::RENDER_SETTINGS* settings = view->GetPainter()->GetSettings();
|
||||
m_manualGrid = VECTOR2D( 1, 1 );
|
||||
m_manualVisibleGrid = VECTOR2D( 1, 1 );
|
||||
m_manualOrigin = VECTOR2I( 0, 0 );
|
||||
m_manualGridSnapping = true;
|
||||
}
|
||||
|
||||
const KIGFX::COLOR4D constructionColour = settings->GetLayerColor( aConstructionLayer );
|
||||
m_constructionGeomPreview.SetPersistentColor( constructionColour );
|
||||
m_constructionGeomPreview.SetColor( constructionColour.WithAlpha( 0.7 ) );
|
||||
|
||||
GRID_HELPER::GRID_HELPER( TOOL_MANAGER* aToolMgr, int aConstructionLayer ) :
|
||||
GRID_HELPER()
|
||||
{
|
||||
m_toolMgr = aToolMgr;
|
||||
|
||||
if( !m_toolMgr )
|
||||
return;
|
||||
|
||||
KIGFX::VIEW* view = m_toolMgr->GetView();
|
||||
wxUnusedVar( aConstructionLayer );
|
||||
|
||||
view->Add( &m_constructionGeomPreview );
|
||||
view->SetVisible( &m_constructionGeomPreview, false );
|
||||
@@ -72,11 +85,20 @@ GRID_HELPER::GRID_HELPER( TOOL_MANAGER* aToolMgr, int aConstructionLayer ) :
|
||||
|
||||
m_toolMgr->GetToolHolder()->RefreshCanvas();
|
||||
} );
|
||||
|
||||
// Initialise manual values from view for compatibility
|
||||
m_manualGrid = view->GetGAL()->GetGridSize();
|
||||
m_manualVisibleGrid = view->GetGAL()->GetVisibleGridSize();
|
||||
m_manualOrigin = VECTOR2I( view->GetGAL()->GetGridOrigin() );
|
||||
m_manualGridSnapping = view->GetGAL()->GetGridSnapping();
|
||||
}
|
||||
|
||||
|
||||
GRID_HELPER::~GRID_HELPER()
|
||||
{
|
||||
if( !m_toolMgr )
|
||||
return;
|
||||
|
||||
KIGFX::VIEW& view = *m_toolMgr->GetView();
|
||||
view.Remove( &m_constructionGeomPreview );
|
||||
|
||||
@@ -89,6 +111,9 @@ KIGFX::ANCHOR_DEBUG* GRID_HELPER::enableAndGetAnchorDebug()
|
||||
{
|
||||
static bool permitted = ADVANCED_CFG::GetCfg().m_EnableSnapAnchorsDebug;
|
||||
|
||||
if( !m_toolMgr )
|
||||
return nullptr;
|
||||
|
||||
if( permitted && !m_anchorDebug )
|
||||
{
|
||||
KIGFX::VIEW& view = *m_toolMgr->GetView();
|
||||
@@ -103,12 +128,223 @@ KIGFX::ANCHOR_DEBUG* GRID_HELPER::enableAndGetAnchorDebug()
|
||||
|
||||
void GRID_HELPER::showConstructionGeometry( bool aShow )
|
||||
{
|
||||
m_toolMgr->GetView()->SetVisible( &m_constructionGeomPreview, aShow );
|
||||
if( m_toolMgr )
|
||||
m_toolMgr->GetView()->SetVisible( &m_constructionGeomPreview, aShow );
|
||||
}
|
||||
|
||||
|
||||
void GRID_HELPER::SetSnapLineDirections( const std::vector<VECTOR2I>& aDirections )
|
||||
{
|
||||
m_snapManager.GetSnapLineManager().SetDirections( aDirections );
|
||||
}
|
||||
|
||||
|
||||
void GRID_HELPER::SetSnapLineOrigin( const VECTOR2I& aOrigin )
|
||||
{
|
||||
m_snapManager.GetSnapLineManager().SetSnapLineOrigin( aOrigin );
|
||||
}
|
||||
|
||||
|
||||
void GRID_HELPER::ClearSnapLine()
|
||||
{
|
||||
m_snapManager.GetSnapLineManager().ClearSnapLine();
|
||||
}
|
||||
|
||||
|
||||
std::optional<VECTOR2I> GRID_HELPER::SnapToConstructionLines( const VECTOR2I& aPoint,
|
||||
const VECTOR2I& aNearestGrid,
|
||||
const VECTOR2D& aGrid,
|
||||
double aSnapRange ) const
|
||||
{
|
||||
const SNAP_LINE_MANAGER& snapLineManager = m_snapManager.GetSnapLineManager();
|
||||
const OPT_VECTOR2I& snapOrigin = snapLineManager.GetSnapLineOrigin();
|
||||
|
||||
wxLogTrace( traceSnap, "SnapToConstructionLines: aPoint=(%d, %d), nearestGrid=(%d, %d), snapRange=%.1f",
|
||||
aPoint.x, aPoint.y, aNearestGrid.x, aNearestGrid.y, aSnapRange );
|
||||
|
||||
if( !snapOrigin || snapLineManager.GetDirections().empty() )
|
||||
{
|
||||
wxLogTrace( traceSnap, " No snap origin or no directions, returning nullopt" );
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const VECTOR2I& origin = *snapOrigin;
|
||||
|
||||
wxLogTrace( traceSnap, " snapOrigin=(%d, %d), directions count=%zu",
|
||||
origin.x, origin.y, snapLineManager.GetDirections().size() );
|
||||
|
||||
const std::vector<VECTOR2I>& directions = snapLineManager.GetDirections();
|
||||
const std::optional<int> activeDirection = snapLineManager.GetActiveDirection();
|
||||
|
||||
if( activeDirection )
|
||||
wxLogTrace( traceSnap, " activeDirection=%d", *activeDirection );
|
||||
|
||||
const VECTOR2D originVec( origin );
|
||||
const VECTOR2D cursorVec( aPoint );
|
||||
const VECTOR2D delta = cursorVec - originVec;
|
||||
|
||||
std::optional<VECTOR2I> bestPoint;
|
||||
double bestPerp = std::numeric_limits<double>::max();
|
||||
double bestDistance = std::numeric_limits<double>::max();
|
||||
|
||||
for( size_t ii = 0; ii < directions.size(); ++ii )
|
||||
{
|
||||
const VECTOR2I& dir = directions[ii];
|
||||
VECTOR2D dirVector( dir );
|
||||
double dirLength = dirVector.EuclideanNorm();
|
||||
|
||||
if( dirLength == 0.0 )
|
||||
{
|
||||
wxLogTrace( traceSnap, " Direction %zu: zero length, skipping", ii );
|
||||
continue;
|
||||
}
|
||||
|
||||
VECTOR2D dirUnit = dirVector / dirLength;
|
||||
|
||||
double distanceAlong = delta.Dot( dirUnit );
|
||||
VECTOR2D projection = originVec + dirUnit * distanceAlong;
|
||||
VECTOR2D offset = delta - dirUnit * distanceAlong;
|
||||
double perpDistance = offset.EuclideanNorm();
|
||||
|
||||
double snapThreshold = aSnapRange;
|
||||
|
||||
if( activeDirection && *activeDirection == static_cast<int>( ii ) )
|
||||
{
|
||||
snapThreshold *= 1.5;
|
||||
wxLogTrace( traceSnap, " Direction %zu: ACTIVE, increased snapThreshold=%.1f", ii, snapThreshold );
|
||||
}
|
||||
|
||||
wxLogTrace( traceSnap, " Direction %zu: dir=(%d, %d), perpDist=%.1f, threshold=%.1f",
|
||||
ii, dir.x, dir.y, perpDistance, snapThreshold );
|
||||
|
||||
if( perpDistance > snapThreshold )
|
||||
{
|
||||
wxLogTrace( traceSnap, " perpDistance > threshold, skipping" );
|
||||
continue;
|
||||
}
|
||||
|
||||
VECTOR2D candidate = projection;
|
||||
|
||||
if( canUseGrid() )
|
||||
{
|
||||
if( dir.x == 0 && dir.y != 0 )
|
||||
{
|
||||
// Vertical construction line: snap to grid intersection
|
||||
candidate.x = origin.x;
|
||||
candidate.y = aNearestGrid.y;
|
||||
wxLogTrace( traceSnap, " Vertical snap: candidate=(%d, %d)",
|
||||
(int)candidate.x, (int)candidate.y );
|
||||
}
|
||||
else if( dir.y == 0 && dir.x != 0 )
|
||||
{
|
||||
// Horizontal construction line: snap to grid intersection
|
||||
candidate.x = aNearestGrid.x;
|
||||
candidate.y = origin.y;
|
||||
wxLogTrace( traceSnap, " Horizontal snap: candidate=(%d, %d)",
|
||||
(int)candidate.x, (int)candidate.y );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Diagonal construction line: find nearest grid intersection along the line
|
||||
// We need to find grid points near the projection point and pick the closest
|
||||
// one that lies on the construction line
|
||||
|
||||
// Get the grid origin for proper alignment
|
||||
VECTOR2D gridOrigin( GetOrigin() );
|
||||
|
||||
// Calculate the projection point relative to grid
|
||||
VECTOR2D relProjection = projection - gridOrigin;
|
||||
|
||||
// Find nearby grid points (check 9 points in a 3x3 grid around the projection)
|
||||
std::vector<VECTOR2D> gridPoints;
|
||||
for( int dx = -1; dx <= 1; ++dx )
|
||||
{
|
||||
for( int dy = -1; dy <= 1; ++dy )
|
||||
{
|
||||
double gridX = std::round( relProjection.x / aGrid.x ) * aGrid.x + dx * aGrid.x;
|
||||
double gridY = std::round( relProjection.y / aGrid.y ) * aGrid.y + dy * aGrid.y;
|
||||
gridPoints.push_back( VECTOR2D( gridX + gridOrigin.x, gridY + gridOrigin.y ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Find the grid point closest to the construction line
|
||||
double bestGridDist = std::numeric_limits<double>::max();
|
||||
VECTOR2D bestGridPt = projection;
|
||||
|
||||
for( const VECTOR2D& gridPt : gridPoints )
|
||||
{
|
||||
// Calculate perpendicular distance from grid point to construction line
|
||||
VECTOR2D gridDelta = gridPt - originVec;
|
||||
double gridDistAlong = gridDelta.Dot( dirUnit );
|
||||
VECTOR2D gridProjection = originVec + dirUnit * gridDistAlong;
|
||||
double gridPerpDist = ( gridPt - gridProjection ).EuclideanNorm();
|
||||
|
||||
// Also consider distance from cursor
|
||||
double distFromCursor = ( gridPt - cursorVec ).EuclideanNorm();
|
||||
|
||||
// Prefer grid points that are close to the line and close to cursor
|
||||
double score = gridPerpDist + distFromCursor * 0.1;
|
||||
|
||||
if( score < bestGridDist )
|
||||
{
|
||||
bestGridDist = score;
|
||||
bestGridPt = gridPt;
|
||||
}
|
||||
}
|
||||
|
||||
candidate = bestGridPt;
|
||||
wxLogTrace( traceSnap, " Diagonal snap: candidate=(%.1f, %.1f), perpDist=%.1f",
|
||||
candidate.x, candidate.y, bestGridDist );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( traceSnap, " Grid disabled, using projection candidate=(%.1f, %.1f)",
|
||||
candidate.x, candidate.y );
|
||||
}
|
||||
|
||||
VECTOR2I candidateInt( KiROUND( candidate.x ), KiROUND( candidate.y ) );
|
||||
|
||||
if( candidateInt == m_skipPoint )
|
||||
{
|
||||
wxLogTrace( traceSnap, " candidateInt matches m_skipPoint, skipping" );
|
||||
continue;
|
||||
}
|
||||
|
||||
VECTOR2D candidateDelta( candidateInt.x - aPoint.x, candidateInt.y - aPoint.y );
|
||||
double candidateDistance = candidateDelta.EuclideanNorm();
|
||||
|
||||
wxLogTrace( traceSnap, " candidateInt=(%d, %d), candidateDist=%.1f",
|
||||
candidateInt.x, candidateInt.y, candidateDistance );
|
||||
|
||||
if( perpDistance < bestPerp
|
||||
|| ( std::abs( perpDistance - bestPerp ) < 1e-9 && candidateDistance < bestDistance ) )
|
||||
{
|
||||
wxLogTrace( traceSnap, " NEW BEST: perpDist=%.1f, candDist=%.1f", perpDistance, candidateDistance );
|
||||
bestPerp = perpDistance;
|
||||
bestDistance = candidateDistance;
|
||||
bestPoint = candidateInt;
|
||||
}
|
||||
}
|
||||
|
||||
if( bestPoint )
|
||||
{
|
||||
wxLogTrace( traceSnap, " RETURNING bestPoint=(%d, %d)", bestPoint->x, bestPoint->y );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogTrace( traceSnap, " RETURNING nullopt (no valid snap found)" );
|
||||
}
|
||||
|
||||
return bestPoint;
|
||||
}
|
||||
|
||||
|
||||
void GRID_HELPER::updateSnapPoint( const TYPED_POINT2I& aPoint )
|
||||
{
|
||||
if( !m_toolMgr )
|
||||
return;
|
||||
|
||||
m_viewSnapPoint.SetPosition( aPoint.m_point );
|
||||
m_viewSnapPoint.SetSnapTypes( aPoint.m_types );
|
||||
|
||||
@@ -121,23 +357,26 @@ void GRID_HELPER::updateSnapPoint( const TYPED_POINT2I& aPoint )
|
||||
|
||||
VECTOR2I GRID_HELPER::GetGrid() const
|
||||
{
|
||||
VECTOR2D size = m_toolMgr->GetView()->GetGAL()->GetGridSize();
|
||||
|
||||
VECTOR2D size = m_toolMgr ? m_toolMgr->GetView()->GetGAL()->GetGridSize() : m_manualGrid;
|
||||
return VECTOR2I( KiROUND( size.x ), KiROUND( size.y ) );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2D GRID_HELPER::GetVisibleGrid() const
|
||||
{
|
||||
return m_toolMgr->GetView()->GetGAL()->GetVisibleGridSize();
|
||||
return m_toolMgr ? m_toolMgr->GetView()->GetGAL()->GetVisibleGridSize() : m_manualVisibleGrid;
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::GetOrigin() const
|
||||
{
|
||||
VECTOR2D origin = m_toolMgr->GetView()->GetGAL()->GetGridOrigin();
|
||||
if( m_toolMgr )
|
||||
{
|
||||
VECTOR2D origin = m_toolMgr->GetView()->GetGAL()->GetGridOrigin();
|
||||
return VECTOR2I( origin );
|
||||
}
|
||||
|
||||
return VECTOR2I( origin );
|
||||
return m_manualOrigin;
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +399,7 @@ GRID_HELPER_GRIDS GRID_HELPER::GetSelectionGrid( const SELECTION& aSelection ) c
|
||||
|
||||
VECTOR2D GRID_HELPER::GetGridSize( GRID_HELPER_GRIDS aGrid ) const
|
||||
{
|
||||
return m_toolMgr->GetView()->GetGAL()->GetGridSize();
|
||||
return m_toolMgr ? m_toolMgr->GetView()->GetGAL()->GetGridSize() : m_manualGrid;
|
||||
}
|
||||
|
||||
|
||||
@@ -170,47 +409,52 @@ void GRID_HELPER::SetAuxAxes( bool aEnable, const VECTOR2I& aOrigin )
|
||||
{
|
||||
m_auxAxis = aOrigin;
|
||||
m_viewAxis.SetPosition( aOrigin );
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewAxis, true );
|
||||
if( m_toolMgr )
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewAxis, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_auxAxis = std::optional<VECTOR2I>();
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewAxis, false );
|
||||
if( m_toolMgr )
|
||||
m_toolMgr->GetView()->SetVisible( &m_viewAxis, false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::AlignGrid( const VECTOR2I& aPoint ) const
|
||||
{
|
||||
return computeNearest( aPoint, GetGrid() );
|
||||
return computeNearest( aPoint, GetGrid(), GetOrigin() );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::AlignGrid( const VECTOR2I& aPoint, const VECTOR2D& aGrid ) const
|
||||
VECTOR2I GRID_HELPER::AlignGrid( const VECTOR2I& aPoint, const VECTOR2D& aGrid,
|
||||
const VECTOR2D& aOffset ) const
|
||||
{
|
||||
return computeNearest( aPoint, aGrid );
|
||||
return computeNearest( aPoint, aGrid, aOffset );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::computeNearest( const VECTOR2I& aPoint, const VECTOR2I& aGrid ) const
|
||||
VECTOR2I GRID_HELPER::computeNearest( const VECTOR2I& aPoint, const VECTOR2I& aGrid,
|
||||
const VECTOR2I& aOffset ) const
|
||||
{
|
||||
return VECTOR2I( KiROUND( static_cast<double>( aPoint.x ) / aGrid.x ) * aGrid.x,
|
||||
KiROUND( static_cast<double>( aPoint.y ) / aGrid.y ) * aGrid.y );
|
||||
return VECTOR2I( KiROUND( (double) ( aPoint.x - aOffset.x ) / aGrid.x ) * aGrid.x + aOffset.x,
|
||||
KiROUND( (double) ( aPoint.y - aOffset.y ) / aGrid.y ) * aGrid.y + aOffset.y );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint ) const
|
||||
{
|
||||
return Align( aPoint, GetGrid() );
|
||||
return Align( aPoint, GetGrid(), GetOrigin() );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint, const VECTOR2D& aGrid ) const
|
||||
VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint, const VECTOR2D& aGrid,
|
||||
const VECTOR2D& aOffset ) const
|
||||
{
|
||||
if( !canUseGrid() )
|
||||
return aPoint;
|
||||
|
||||
VECTOR2I nearest = AlignGrid( aPoint, aGrid );
|
||||
VECTOR2I nearest = AlignGrid( aPoint, aGrid, aOffset );
|
||||
|
||||
if( !m_auxAxis )
|
||||
return nearest;
|
||||
@@ -227,7 +471,8 @@ VECTOR2I GRID_HELPER::Align( const VECTOR2I& aPoint, const VECTOR2D& aGrid ) con
|
||||
|
||||
bool GRID_HELPER::canUseGrid() const
|
||||
{
|
||||
return m_enableGrid && m_toolMgr->GetView()->GetGAL()->GetGridSnapping();
|
||||
return m_enableGrid && ( m_toolMgr ? m_toolMgr->GetView()->GetGAL()->GetGridSnapping()
|
||||
: m_manualGridSnapping );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@ void POLYGON_POINT_EDIT_BEHAVIOR::BuildForPolyOutline( EDIT_POINTS& aPo
|
||||
{
|
||||
const int cornersCount = aOutline.TotalVertices();
|
||||
|
||||
if( cornersCount == 0 )
|
||||
return;
|
||||
|
||||
for( auto iterator = aOutline.CIterateWithHoles(); iterator; iterator++ )
|
||||
{
|
||||
aPoints.AddPoint( *iterator );
|
||||
|
||||
@@ -59,6 +59,8 @@ const wxChar* const traceUiProfile = wxT( "KICAD_UI_PROFILE" );
|
||||
const wxChar* const traceGit = wxT( "KICAD_GIT" );
|
||||
const wxChar* const traceEagleIo = wxT( "KICAD_EAGLE_IO" );
|
||||
const wxChar* const traceDesignBlocks = wxT( "KICAD_DESIGN_BLOCK" );
|
||||
const wxChar* const traceLibFieldTable = wxT( "KICAD_LIB_FIELD_TABLE" );
|
||||
const wxChar* const traceSnap = wxT( "KICAD_SNAP" );
|
||||
|
||||
|
||||
wxString dump( const wxArrayString& aArray )
|
||||
|
||||
+79
-56
@@ -362,18 +362,26 @@ bool FIELD_VALIDATOR::Validate( wxWindow* aParent )
|
||||
}
|
||||
|
||||
|
||||
bool FIELD_VALIDATOR::DoValidate( const wxString& aValue, wxWindow* aParent )
|
||||
wxString GetFieldValidationErrorMessage( int aFieldId, const wxString& aValue )
|
||||
{
|
||||
wxString msg;
|
||||
FIELD_VALIDATOR validator( aFieldId );
|
||||
wxString msg;
|
||||
|
||||
if( HasFlag( wxFILTER_EMPTY ) && aValue.empty() )
|
||||
msg.Printf( _( "The value of the field cannot be empty." ) );
|
||||
if( validator.HasFlag( wxFILTER_EMPTY ) && aValue.empty() )
|
||||
{
|
||||
switch( aFieldId )
|
||||
{
|
||||
case SHEETNAME_V: msg = _( "A sheet must have a name." ); break;
|
||||
case SHEETFILENAME_V: msg = _( "A sheet must have a file specified." ); break;
|
||||
default: msg = _( "The value of the field cannot be empty." ); break;
|
||||
}
|
||||
}
|
||||
|
||||
if( HasFlag( wxFILTER_EXCLUDE_CHAR_LIST ) && ContainsExcludedCharacters( aValue ) )
|
||||
if( msg.empty() && validator.HasFlag( wxFILTER_EXCLUDE_CHAR_LIST ) )
|
||||
{
|
||||
wxArrayString badCharsFound;
|
||||
|
||||
for( const wxUniCharRef& excludeChar : GetCharExcludes() )
|
||||
for( const wxUniCharRef& excludeChar : validator.GetCharExcludes() )
|
||||
{
|
||||
if( aValue.Find( excludeChar ) != wxNOT_FOUND )
|
||||
{
|
||||
@@ -390,68 +398,83 @@ bool FIELD_VALIDATOR::DoValidate( const wxString& aValue, wxWindow* aParent )
|
||||
}
|
||||
}
|
||||
|
||||
wxString badChars;
|
||||
|
||||
for( size_t i = 0; i < badCharsFound.GetCount(); i++ )
|
||||
if( !badCharsFound.IsEmpty() )
|
||||
{
|
||||
if( !badChars.IsEmpty() )
|
||||
wxString badChars;
|
||||
|
||||
for( size_t i = 0; i < badCharsFound.GetCount(); i++ )
|
||||
{
|
||||
if( badCharsFound.GetCount() == 2 )
|
||||
if( !badChars.IsEmpty() )
|
||||
{
|
||||
badChars += _( " or " );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( i < badCharsFound.GetCount() - 2 )
|
||||
badChars += _( ", or " );
|
||||
if( badCharsFound.GetCount() == 2 )
|
||||
{
|
||||
badChars += _( " or " );
|
||||
}
|
||||
else
|
||||
badChars += wxT( ", " );
|
||||
{
|
||||
if( i < badCharsFound.GetCount() - 2 )
|
||||
badChars += _( ", or " );
|
||||
else
|
||||
badChars += wxT( ", " );
|
||||
}
|
||||
}
|
||||
|
||||
badChars += badCharsFound.Item( i );
|
||||
}
|
||||
|
||||
badChars += badCharsFound.Item( i );
|
||||
switch( aFieldId )
|
||||
{
|
||||
case REFERENCE_FIELD:
|
||||
msg.Printf( _( "The reference designator cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case VALUE_FIELD:
|
||||
msg.Printf( _( "The value field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case FOOTPRINT_FIELD:
|
||||
msg.Printf( _( "The footprint field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case DATASHEET_FIELD:
|
||||
msg.Printf( _( "The datasheet field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case SHEETNAME_V:
|
||||
msg.Printf( _( "The sheet name cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case SHEETFILENAME_V:
|
||||
msg.Printf( _( "The sheet filename cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
default:
|
||||
msg.Printf( _( "The field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
switch( m_fieldId )
|
||||
if( msg.empty() )
|
||||
{
|
||||
if( aFieldId == REFERENCE_FIELD && aValue.Contains( wxT( "${" ) ) )
|
||||
{
|
||||
case REFERENCE_FIELD:
|
||||
msg.Printf( _( "The reference designator cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case VALUE_FIELD:
|
||||
msg.Printf( _( "The value field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case FOOTPRINT_FIELD:
|
||||
msg.Printf( _( "The footprint field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case DATASHEET_FIELD:
|
||||
msg.Printf( _( "The datasheet field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case SHEETNAME_V:
|
||||
msg.Printf( _( "The sheet name cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
case SHEETFILENAME_V:
|
||||
msg.Printf( _( "The sheet filename cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
|
||||
default:
|
||||
msg.Printf( _( "The field cannot contain %s character(s)." ), badChars );
|
||||
break;
|
||||
};
|
||||
}
|
||||
else if( m_fieldId == REFERENCE_FIELD && aValue.Contains( wxT( "${" ) ) )
|
||||
{
|
||||
msg.Printf( _( "The reference designator cannot contain text variable references" ) );
|
||||
}
|
||||
else if( m_fieldId == REFERENCE_FIELD && UTIL::GetRefDesPrefix( aValue ).IsEmpty() )
|
||||
{
|
||||
msg.Printf( _( "References must start with a letter." ) );
|
||||
msg.Printf( _( "The reference designator cannot contain text variable references" ) );
|
||||
}
|
||||
else if( aFieldId == REFERENCE_FIELD && UTIL::GetRefDesPrefix( aValue ).IsEmpty() )
|
||||
{
|
||||
msg.Printf( _( "References must start with a letter." ) );
|
||||
}
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
bool FIELD_VALIDATOR::DoValidate( const wxString& aValue, wxWindow* aParent )
|
||||
{
|
||||
wxString msg = GetFieldValidationErrorMessage( m_fieldId, aValue );
|
||||
|
||||
if( !msg.empty() )
|
||||
{
|
||||
if( m_validatorWindow )
|
||||
|
||||
@@ -214,6 +214,22 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
|
||||
int y = mouseRel.y;
|
||||
VECTOR2D mousePos( x, y );
|
||||
|
||||
// Clear keyboard cursor position flag when actual mouse motion is detected
|
||||
// (i.e., not from cursor warping and position has changed)
|
||||
if( !m_cursorWarped && m_settings.m_lastKeyboardCursorPositionValid )
|
||||
{
|
||||
VECTOR2I screenPos( x, y );
|
||||
VECTOR2I keyboardScreenPos = m_view->ToScreen( m_settings.m_lastKeyboardCursorPosition );
|
||||
|
||||
// If mouse has moved to a different position than the keyboard cursor position,
|
||||
// clear the keyboard position flag to allow mouse control
|
||||
if( screenPos != keyboardScreenPos )
|
||||
{
|
||||
m_settings.m_lastKeyboardCursorPositionValid = false;
|
||||
m_settings.m_lastKeyboardCursorPosition = { 0.0, 0.0 };
|
||||
}
|
||||
}
|
||||
|
||||
// Automatic focus switching between SCH and PCB windows on canvas mouse motion
|
||||
if( m_settings.m_focusFollowSchPcb )
|
||||
{
|
||||
|
||||
@@ -326,7 +326,9 @@ void COLOR_SWATCH::GetNewSwatchColor()
|
||||
|
||||
void COLOR_SWATCH::OnDarkModeToggle()
|
||||
{
|
||||
m_checkerboardBg = m_parent->GetBackgroundColour();
|
||||
wxWindow* parent = GetParent();
|
||||
m_checkerboardBg = parent ? parent->GetBackgroundColour() : wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
|
||||
|
||||
m_swatch->SetBitmap( makeBitmap() );
|
||||
if( m_swatch )
|
||||
m_swatch->SetBitmap( makeBitmap() );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
#include <widgets/grid_striped_renderer.h>
|
||||
|
||||
void STRIPED_CELL_RENDERER::Draw(wxGrid& grid, wxGridCellAttr& attr, wxDC& dc,
|
||||
const wxRect& rect, int row, int col, bool isSelected)
|
||||
{
|
||||
// First draw the striped background for empty cells
|
||||
wxString cellValue = grid.GetCellValue(row, col);
|
||||
if (cellValue.IsEmpty())
|
||||
{
|
||||
DrawStripedBackground(dc, rect, isSelected);
|
||||
}
|
||||
|
||||
// Then draw the text content using the parent class
|
||||
wxGridCellStringRenderer::Draw(grid, attr, dc, rect, row, col, isSelected);
|
||||
}
|
||||
|
||||
void STRIPED_CELL_RENDERER::drawStripedBackground(wxDC& dc, const wxRect& rect, bool isSelected) const
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
// For selected cells, use the selection color
|
||||
dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)));
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.DrawRectangle(rect);
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw horizontal stripes
|
||||
const int stripeHeight = 3;
|
||||
wxColour color1 = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
|
||||
wxColour color2(240, 240, 240); // Light gray
|
||||
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
|
||||
bool useColor1 = true;
|
||||
for (int y = rect.GetTop(); y < rect.GetBottom(); y += stripeHeight)
|
||||
{
|
||||
wxColour currentColor = useColor1 ? color1 : color2;
|
||||
dc.SetBrush(wxBrush(currentColor));
|
||||
|
||||
int stripeBottom = wxMin(y + stripeHeight, rect.GetBottom());
|
||||
dc.DrawRectangle(rect.GetLeft(), y, rect.GetWidth(), stripeBottom - y);
|
||||
|
||||
useColor1 = !useColor1;
|
||||
}
|
||||
}
|
||||
@@ -443,7 +443,8 @@ public:
|
||||
TEXT_BUTTON_FILE_BROWSER( wxWindow* aParent, DIALOG_SHIM* aParentDlg, WX_GRID* aGrid,
|
||||
wxString* aCurrentDir, const wxString& aFileFilter = wxEmptyString,
|
||||
bool aNormalize = false,
|
||||
const wxString& aNormalizeBasePath = wxEmptyString ) :
|
||||
const wxString& aNormalizeBasePath = wxEmptyString,
|
||||
std::function<wxString( const wxString& )> aEmbedCallback = nullptr ) :
|
||||
wxComboCtrl( aParent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 0, 0 ),
|
||||
wxTE_PROCESS_ENTER | wxBORDER_NONE ),
|
||||
m_dlg( aParentDlg ),
|
||||
@@ -451,7 +452,8 @@ public:
|
||||
m_currentDir( aCurrentDir ),
|
||||
m_normalize( aNormalize ),
|
||||
m_normalizeBasePath( aNormalizeBasePath ),
|
||||
m_fileFilter( aFileFilter )
|
||||
m_fileFilter( aFileFilter ),
|
||||
m_embedCallback( std::move( aEmbedCallback ) )
|
||||
{
|
||||
SetButtonBitmaps( KiBitmapBundle( BITMAPS::small_folder ) );
|
||||
|
||||
@@ -463,7 +465,8 @@ public:
|
||||
wxString* aCurrentDir,
|
||||
std::function<wxString( WX_GRID* grid, int row )> aFileFilterFn,
|
||||
bool aNormalize = false,
|
||||
const wxString& aNormalizeBasePath = wxEmptyString ) :
|
||||
const wxString& aNormalizeBasePath = wxEmptyString,
|
||||
std::function<wxString( const wxString& )> aEmbedCallback = nullptr ) :
|
||||
wxComboCtrl( aParent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 0, 0 ),
|
||||
wxTE_PROCESS_ENTER | wxBORDER_NONE ),
|
||||
m_dlg( aParentDlg ),
|
||||
@@ -471,7 +474,8 @@ public:
|
||||
m_currentDir( aCurrentDir ),
|
||||
m_normalize( aNormalize ),
|
||||
m_normalizeBasePath( aNormalizeBasePath ),
|
||||
m_fileFilterFn( std::move( aFileFilterFn ) )
|
||||
m_fileFilterFn( std::move( aFileFilterFn ) ),
|
||||
m_embedCallback( std::move( aEmbedCallback ) )
|
||||
{
|
||||
SetButtonBitmaps( KiBitmapBundle( BITMAPS::small_folder ) );
|
||||
|
||||
@@ -502,16 +506,30 @@ protected:
|
||||
|
||||
if( !m_fileFilter.IsEmpty() )
|
||||
{
|
||||
FILEDLG_OPEN_EMBED_FILE customize( false );
|
||||
wxFileDialog dlg( m_dlg, _( "Select a File" ), fn.GetPath(), fn.GetFullName(),
|
||||
m_fileFilter, wxFD_FILE_MUST_EXIST | wxFD_OPEN );
|
||||
|
||||
if( m_embedCallback )
|
||||
dlg.SetCustomizeHook( customize );
|
||||
|
||||
if( dlg.ShowModal() == wxID_OK )
|
||||
{
|
||||
wxString filePath = dlg.GetPath();
|
||||
wxString lastPath = dlg.GetDirectory();
|
||||
wxString relPath = wxEmptyString;
|
||||
|
||||
if( m_normalize )
|
||||
if( m_embedCallback && customize.GetEmbed() )
|
||||
{
|
||||
relPath = m_embedCallback( filePath );
|
||||
|
||||
if( relPath.IsEmpty() )
|
||||
{
|
||||
m_dlg->CleanupAfterModalSubDialog();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( m_normalize )
|
||||
{
|
||||
relPath = NormalizePath( filePath, &Pgm().GetLocalEnvVariables(),
|
||||
m_normalizeBasePath );
|
||||
@@ -573,6 +591,7 @@ protected:
|
||||
|
||||
wxString m_fileFilter;
|
||||
std::function<wxString( WX_GRID* aGrid, int aRow )> m_fileFilterFn;
|
||||
std::function<wxString( const wxString& )> m_embedCallback;
|
||||
};
|
||||
|
||||
|
||||
@@ -583,12 +602,13 @@ void GRID_CELL_PATH_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
|
||||
{
|
||||
m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_grid, m_currentDir,
|
||||
m_fileFilterFn, m_normalize,
|
||||
m_normalizeBasePath );
|
||||
m_normalizeBasePath, m_embedCallback );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_control = new TEXT_BUTTON_FILE_BROWSER( aParent, m_dlg, m_grid, m_currentDir,
|
||||
m_fileFilter, m_normalize, m_normalizeBasePath );
|
||||
m_fileFilter, m_normalize, m_normalizeBasePath,
|
||||
m_embedCallback );
|
||||
}
|
||||
|
||||
WX_GRID::CellEditorSetMargins( Combo() );
|
||||
|
||||
@@ -122,17 +122,14 @@ PROPERTIES_PANEL::PROPERTIES_PANEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame )
|
||||
m_grid->CenterSplitter();
|
||||
|
||||
Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( PROPERTIES_PANEL::onCharHook ), nullptr, this );
|
||||
Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanged ),
|
||||
nullptr, this );
|
||||
Connect( wxEVT_PG_CHANGING, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanging ),
|
||||
nullptr, this );
|
||||
Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanged ), nullptr, this );
|
||||
Connect( wxEVT_PG_CHANGING, wxPropertyGridEventHandler( PROPERTIES_PANEL::valueChanging ), nullptr, this );
|
||||
Connect( wxEVT_SHOW, wxShowEventHandler( PROPERTIES_PANEL::onShow ), nullptr, this );
|
||||
|
||||
Bind( wxEVT_PG_COL_END_DRAG,
|
||||
[&]( wxPropertyGridEvent& )
|
||||
{
|
||||
m_splitter_key_proportion =
|
||||
static_cast<float>( m_grid->GetSplitterPosition() ) / m_grid->GetSize().x;
|
||||
m_splitter_key_proportion = static_cast<float>( m_grid->GetSplitterPosition() ) / m_grid->GetSize().x;
|
||||
} );
|
||||
|
||||
Bind( wxEVT_SIZE,
|
||||
@@ -225,33 +222,27 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
|
||||
wxCHECK( !types.empty(), /* void */ ); // already guarded above, but Coverity doesn't know that
|
||||
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
std::set<PROPERTY_BASE*> commonProps;
|
||||
const PROPERTY_LIST& allProperties = propMgr.GetProperties( *types.begin() );
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
std::set<PROPERTY_BASE*> commonProps;
|
||||
const std::vector<PROPERTY_BASE*>& allProperties = propMgr.GetProperties( *types.begin() );
|
||||
|
||||
copy( allProperties.begin(), allProperties.end(),
|
||||
inserter( commonProps, commonProps.begin() ) );
|
||||
copy( allProperties.begin(), allProperties.end(), inserter( commonProps, commonProps.begin() ) );
|
||||
|
||||
PROPERTY_DISPLAY_ORDER displayOrder = propMgr.GetDisplayOrder( *types.begin() );
|
||||
|
||||
std::vector<wxString> groupDisplayOrder = propMgr.GetGroupDisplayOrder( *types.begin() );
|
||||
std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
|
||||
std::map<PROPERTY_BASE*, int> displayOrder = propMgr.GetDisplayOrder( *types.begin() );
|
||||
std::vector<wxString> groupDisplayOrder = propMgr.GetGroupDisplayOrder( *types.begin() );
|
||||
std::set<wxString> groups( groupDisplayOrder.begin(), groupDisplayOrder.end() );
|
||||
|
||||
std::set<PROPERTY_BASE*> availableProps;
|
||||
|
||||
// Get all possible properties
|
||||
for( const TYPE_ID& type : types )
|
||||
{
|
||||
const PROPERTY_LIST& itemProps = propMgr.GetProperties( type );
|
||||
const std::vector<PROPERTY_BASE*>& itemProps = propMgr.GetProperties( type );
|
||||
const std::map<PROPERTY_BASE*, int>& itemDisplayOrder = propMgr.GetDisplayOrder( type );
|
||||
|
||||
const PROPERTY_DISPLAY_ORDER& itemDisplayOrder = propMgr.GetDisplayOrder( type );
|
||||
copy( itemDisplayOrder.begin(), itemDisplayOrder.end(), inserter( displayOrder, displayOrder.begin() ) );
|
||||
|
||||
copy( itemDisplayOrder.begin(), itemDisplayOrder.end(),
|
||||
inserter( displayOrder, displayOrder.begin() ) );
|
||||
|
||||
const std::vector<wxString>& itemGroups = propMgr.GetGroupDisplayOrder( type );
|
||||
|
||||
for( const wxString& group : itemGroups )
|
||||
for( const wxString& group : propMgr.GetGroupDisplayOrder( type ) )
|
||||
{
|
||||
if( !groups.count( group ) )
|
||||
{
|
||||
@@ -305,9 +296,14 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
if( !property )
|
||||
continue;
|
||||
|
||||
wxVariant commonVal;
|
||||
wxVariant commonVal;
|
||||
wxPGChoices choices;
|
||||
|
||||
extractValueAndWritability( aSelection, property, commonVal, writeable, choices );
|
||||
|
||||
if( choices.GetCount() > 0 )
|
||||
pgProp->SetChoices( choices );
|
||||
|
||||
extractValueAndWritability( aSelection, property, commonVal, writeable );
|
||||
pgProp->SetValue( commonVal );
|
||||
pgProp->Enable( writeable );
|
||||
|
||||
@@ -326,13 +322,17 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
|
||||
for( PROPERTY_BASE* property : availableProps )
|
||||
{
|
||||
wxPGProperty* pgProp = createPGProperty( property );
|
||||
wxVariant commonVal;
|
||||
wxVariant commonVal;
|
||||
wxPGChoices choices;
|
||||
|
||||
if( !extractValueAndWritability( aSelection, property, commonVal, writeable ) )
|
||||
if( !extractValueAndWritability( aSelection, property, commonVal, writeable, choices ) )
|
||||
continue;
|
||||
|
||||
if( pgProp )
|
||||
{
|
||||
if( choices.GetCount() )
|
||||
pgProp->SetChoices( choices );
|
||||
|
||||
pgProp->SetValue( commonVal );
|
||||
pgProp->Enable( writeable );
|
||||
m_displayed.push_back( property );
|
||||
@@ -403,13 +403,12 @@ bool PROPERTIES_PANEL::getItemValue( EDA_ITEM* aItem, PROPERTY_BASE* aProperty,
|
||||
}
|
||||
|
||||
|
||||
bool PROPERTIES_PANEL::extractValueAndWritability( const SELECTION& aSelection,
|
||||
PROPERTY_BASE* aProperty,
|
||||
wxVariant& aValue, bool& aWritable )
|
||||
bool PROPERTIES_PANEL::extractValueAndWritability( const SELECTION& aSelection, PROPERTY_BASE* aProperty,
|
||||
wxVariant& aValue, bool& aWritable, wxPGChoices& aChoices )
|
||||
{
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
bool different = false;
|
||||
wxVariant commonVal;
|
||||
bool first = true;
|
||||
|
||||
aWritable = true;
|
||||
|
||||
@@ -421,6 +420,22 @@ bool PROPERTIES_PANEL::extractValueAndWritability( const SELECTION& aSelection,
|
||||
if( aProperty->IsHiddenFromPropertiesManager() )
|
||||
return false;
|
||||
|
||||
wxPGChoices choices = aProperty->GetChoices( item );
|
||||
|
||||
if( first )
|
||||
{
|
||||
aChoices = choices;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxArrayString labels = choices.GetLabels();
|
||||
wxArrayInt values = choices.GetValuesForStrings( labels );
|
||||
|
||||
if( labels != aChoices.GetLabels() || values != aChoices.GetValuesForStrings( labels ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
// If read-only for any of the selection, read-only for the whole selection.
|
||||
if( !propMgr.IsWriteableFor( TYPE_HASH( *item ), aProperty, item ) )
|
||||
aWritable = false;
|
||||
@@ -494,10 +509,15 @@ void PROPERTIES_PANEL::onCharHook( wxKeyEvent& aEvent )
|
||||
}
|
||||
}
|
||||
|
||||
if( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER )
|
||||
if( aEvent.GetKeyCode() == WXK_RETURN || aEvent.GetKeyCode() == WXK_NUMPAD_ENTER
|
||||
|| aEvent.GetKeyCode() == WXK_DOWN || aEvent.GetKeyCode() == WXK_UP )
|
||||
{
|
||||
m_grid->CommitChangesFromEditor();
|
||||
/* don't skip this one; if we're not the last property we'll also go to the next row */
|
||||
|
||||
CallAfter( [this]()
|
||||
{
|
||||
m_grid->SelectProperty( m_grid->GetSelectedProperty(), true );
|
||||
} );
|
||||
}
|
||||
|
||||
aEvent.Skip();
|
||||
|
||||
@@ -102,7 +102,7 @@ protected:
|
||||
* @return true if the property is available for all the items in the selection
|
||||
*/
|
||||
bool extractValueAndWritability( const SELECTION& aSelection, PROPERTY_BASE* aProperty,
|
||||
wxVariant& aValue, bool& aWritable );
|
||||
wxVariant& aValue, bool& aWritable, wxPGChoices& aChoices );
|
||||
|
||||
public:
|
||||
int m_SuppressGridChangeEvents;
|
||||
|
||||
@@ -230,7 +230,11 @@ void UNIT_BINDER::onComboBox( wxCommandEvent& aEvent )
|
||||
const long long int conv =
|
||||
EDA_UNIT_UTILS::UI::ValueFromString( *m_iuScale, m_units, value, m_dataType );
|
||||
|
||||
SetValue( conv );
|
||||
CallAfter(
|
||||
[this, conv]
|
||||
{
|
||||
SetValue( conv );
|
||||
} );
|
||||
|
||||
aEvent.Skip();
|
||||
}
|
||||
|
||||
@@ -124,6 +124,8 @@ set( EESCHEMA_DLGS
|
||||
dialogs/dialog_label_properties_base.cpp
|
||||
dialogs/dialog_lib_edit_pin_table.cpp
|
||||
dialogs/dialog_lib_edit_pin_table_base.cpp
|
||||
dialogs/dialog_lib_fields_base.cpp
|
||||
dialogs/dialog_lib_fields.cpp
|
||||
dialogs/dialog_lib_new_symbol.cpp
|
||||
dialogs/dialog_lib_new_symbol_base.cpp
|
||||
dialogs/dialog_lib_symbol_properties.cpp
|
||||
@@ -369,6 +371,7 @@ set( EESCHEMA_SRCS
|
||||
generate_alias_info.cpp
|
||||
gfx_import_utils.cpp
|
||||
junction_helpers.cpp
|
||||
lib_fields_data_model.cpp
|
||||
lib_symbol.cpp
|
||||
libarch.cpp
|
||||
menubar.cpp
|
||||
|
||||
@@ -253,7 +253,7 @@ HANDLER_RESULT<ItemRequestStatus> API_HANDLER_SCH::handleCreateUpdateItemsIntern
|
||||
if( aCreate )
|
||||
{
|
||||
item->Serialize( newItem );
|
||||
commit->Add( item.release() );
|
||||
commit->Add( item.release(), screen );
|
||||
|
||||
if( !m_activeClients.count( aClientName ) )
|
||||
pushCurrentCommit( aClientName, _( "Added items via API" ) );
|
||||
@@ -266,7 +266,7 @@ HANDLER_RESULT<ItemRequestStatus> API_HANDLER_SCH::handleCreateUpdateItemsIntern
|
||||
{
|
||||
schItem->SwapData( static_cast<SCH_ITEM*>( item.get() ) );
|
||||
schItem->Serialize( newItem );
|
||||
commit->Modify( schItem );
|
||||
commit->Modify( schItem, screen );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+105
-76
@@ -441,13 +441,13 @@ CONNECTION_SUBGRAPH::GetNetclassesForDriver( SCH_ITEM* aItem ) const
|
||||
// Get netclasses on attached rule areas
|
||||
for( SCH_RULE_AREA* ruleArea : ruleAreaCache )
|
||||
{
|
||||
const std::vector<std::pair<wxString, SCH_ITEM*>> ruleNetclasses =
|
||||
ruleArea->GetResolvedNetclasses();
|
||||
const std::vector<std::pair<wxString, SCH_ITEM*>> ruleAreaNetclasses =
|
||||
ruleArea->GetResolvedNetclasses( &m_sheet );
|
||||
|
||||
if( ruleNetclasses.size() > 0 )
|
||||
if( ruleAreaNetclasses.size() > 0 )
|
||||
{
|
||||
foundNetclasses.insert( foundNetclasses.end(), ruleNetclasses.begin(),
|
||||
ruleNetclasses.end() );
|
||||
foundNetclasses.insert( foundNetclasses.end(), ruleAreaNetclasses.begin(),
|
||||
ruleAreaNetclasses.end() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -563,12 +563,22 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
|
||||
if( !aDriver )
|
||||
return PRIORITY::NONE;
|
||||
|
||||
auto libSymbolRef =
|
||||
[]( const SCH_SYMBOL* symbol ) -> wxString
|
||||
{
|
||||
if( const std::unique_ptr<LIB_SYMBOL>& part = symbol->GetLibSymbolRef() )
|
||||
return part->GetReferenceField().GetText();
|
||||
|
||||
return wxEmptyString;
|
||||
};
|
||||
|
||||
switch( aDriver->Type() )
|
||||
{
|
||||
case SCH_SHEET_PIN_T: return PRIORITY::SHEET_PIN;
|
||||
case SCH_HIER_LABEL_T: return PRIORITY::HIER_LABEL;
|
||||
case SCH_LABEL_T: return PRIORITY::LOCAL_LABEL;
|
||||
case SCH_GLOBAL_LABEL_T: return PRIORITY::GLOBAL;
|
||||
|
||||
case SCH_PIN_T:
|
||||
{
|
||||
SCH_PIN* sch_pin = static_cast<SCH_PIN*>( aDriver );
|
||||
@@ -576,14 +586,14 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
|
||||
|
||||
if( sch_pin->IsGlobalPower() )
|
||||
return PRIORITY::POWER_PIN;
|
||||
else if( !sym || sym->GetExcludedFromBoard()
|
||||
|| sym->GetLibSymbolRef()->GetReferenceField().GetText().StartsWith( '#' ) )
|
||||
else if( !sym || sym->GetExcludedFromBoard() || libSymbolRef( sym ).StartsWith( '#' ) )
|
||||
return PRIORITY::NONE;
|
||||
else
|
||||
return PRIORITY::PIN;
|
||||
}
|
||||
|
||||
default: return PRIORITY::NONE;
|
||||
default:
|
||||
return PRIORITY::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,13 +601,13 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
|
||||
void CONNECTION_GRAPH::Merge( CONNECTION_GRAPH& aGraph )
|
||||
{
|
||||
std::copy( aGraph.m_items.begin(), aGraph.m_items.end(),
|
||||
std::back_inserter( m_items ) );
|
||||
std::back_inserter( m_items ) );
|
||||
|
||||
for( SCH_ITEM* item : aGraph.m_items )
|
||||
item->SetConnectionGraph( this );
|
||||
|
||||
std::copy( aGraph.m_subgraphs.begin(), aGraph.m_subgraphs.end(),
|
||||
std::back_inserter( m_subgraphs ) );
|
||||
std::back_inserter( m_subgraphs ) );
|
||||
|
||||
for( CONNECTION_SUBGRAPH* sg : aGraph.m_subgraphs )
|
||||
{
|
||||
@@ -607,13 +617,11 @@ void CONNECTION_GRAPH::Merge( CONNECTION_GRAPH& aGraph )
|
||||
sg->m_graph = this;
|
||||
}
|
||||
|
||||
std::copy( aGraph.m_driver_subgraphs.begin(),
|
||||
aGraph.m_driver_subgraphs.end(),
|
||||
std::back_inserter( m_driver_subgraphs ) );
|
||||
std::copy( aGraph.m_driver_subgraphs.begin(), aGraph.m_driver_subgraphs.end(),
|
||||
std::back_inserter( m_driver_subgraphs ) );
|
||||
|
||||
std::copy( aGraph.m_global_power_pins.begin(),
|
||||
aGraph.m_global_power_pins.end(),
|
||||
std::back_inserter( m_global_power_pins ) );
|
||||
std::copy( aGraph.m_global_power_pins.begin(), aGraph.m_global_power_pins.end(),
|
||||
std::back_inserter( m_global_power_pins ) );
|
||||
|
||||
for( auto& [key, value] : aGraph.m_net_name_to_subgraphs_map )
|
||||
m_net_name_to_subgraphs_map.insert_or_assign( key, value );
|
||||
@@ -1141,21 +1149,22 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
aSheet.Last()->GetFileName(), aItemList.size() );
|
||||
std::map<VECTOR2I, std::vector<SCH_ITEM*>> connection_map;
|
||||
|
||||
auto updatePin = [&]( SCH_PIN* aPin, SCH_CONNECTION* aConn )
|
||||
{
|
||||
aConn->SetType( CONNECTION_TYPE::NET );
|
||||
auto updatePin =
|
||||
[&]( SCH_PIN* aPin, SCH_CONNECTION* aConn )
|
||||
{
|
||||
aConn->SetType( CONNECTION_TYPE::NET );
|
||||
|
||||
// because calling the first time is not thread-safe
|
||||
wxString name = aPin->GetDefaultNetName( aSheet );
|
||||
aPin->ClearConnectedItems( aSheet );
|
||||
// because calling the first time is not thread-safe
|
||||
wxString name = aPin->GetDefaultNetName( aSheet );
|
||||
aPin->ClearConnectedItems( aSheet );
|
||||
|
||||
// power symbol pins need to be post-processed later
|
||||
if( aPin->IsGlobalPower() )
|
||||
{
|
||||
aConn->SetName( name );
|
||||
m_global_power_pins.emplace_back( std::make_pair( aSheet, aPin ) );
|
||||
}
|
||||
};
|
||||
// power symbol pins need to be post-processed later
|
||||
if( aPin->IsGlobalPower() )
|
||||
{
|
||||
aConn->SetName( name );
|
||||
m_global_power_pins.emplace_back( std::make_pair( aSheet, aPin ) );
|
||||
}
|
||||
};
|
||||
|
||||
for( SCH_ITEM* item : aItemList )
|
||||
{
|
||||
@@ -1227,17 +1236,41 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
|
||||
for( const VECTOR2I& point : points )
|
||||
connection_map[ point ].push_back( item );
|
||||
|
||||
/// Special case for labels that overlap wires
|
||||
/// While this is an ERC error as there is not an explicit junction,
|
||||
/// we want to enforce connectivity for all items under the label position.
|
||||
if( dynamic_cast<SCH_LABEL_BASE*>( item ) )
|
||||
{
|
||||
VECTOR2I point = item->GetPosition();
|
||||
SCH_SCREEN* screen = aSheet.LastScreen();
|
||||
auto items = screen->Items().Overlapping( point );
|
||||
std::vector<SCH_ITEM*> overlapping_items;
|
||||
|
||||
std::copy_if( items.begin(), items.end(), std::back_inserter( overlapping_items ),
|
||||
[&]( SCH_ITEM* test_item )
|
||||
{
|
||||
return test_item->Type() == SCH_LINE_T
|
||||
&& test_item->HitTest( point, -1 );
|
||||
} );
|
||||
|
||||
// We need at least two connnectable lines that are not the label here
|
||||
// Otherwise, the label will be normally assigned to one or the other
|
||||
if( overlapping_items.size() < 2 ) continue;
|
||||
|
||||
for( SCH_ITEM* test_item : overlapping_items )
|
||||
connection_map[point].push_back( test_item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( const auto& it : connection_map )
|
||||
for( auto& [point, connection_vec] : connection_map )
|
||||
{
|
||||
std::vector<SCH_ITEM*> connection_vec = it.second;
|
||||
std::sort( connection_vec.begin(), connection_vec.end() );
|
||||
alg::remove_duplicates( connection_vec );
|
||||
|
||||
// Pre-scan to see if we have a bus at this location
|
||||
SCH_LINE* busLine = aSheet.LastScreen()->GetBus( it.first );
|
||||
SCH_LINE* busLine = aSheet.LastScreen()->GetBus( point );
|
||||
|
||||
std::mutex update_mutex;
|
||||
|
||||
@@ -1264,7 +1297,6 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bus-to-bus entries are treated just like bus wires
|
||||
else if( connected_item->Type() == SCH_BUS_BUS_ENTRY_T )
|
||||
{
|
||||
@@ -1274,7 +1306,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
{
|
||||
auto bus_entry = static_cast<SCH_BUS_BUS_ENTRY*>( connected_item );
|
||||
|
||||
if( it.first == bus_entry->GetPosition() )
|
||||
if( point == bus_entry->GetPosition() )
|
||||
bus_entry->m_connected_bus_items[0] = busLine;
|
||||
else
|
||||
bus_entry->m_connected_bus_items[1] = busLine;
|
||||
@@ -1285,7 +1317,6 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Change junctions to be on bus junction layer if they are touching a bus
|
||||
else if( connected_item->Type() == SCH_JUNCTION_T )
|
||||
{
|
||||
@@ -1321,9 +1352,9 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
bus_connection_ok = !busLine || connected_item->GetLayer() == LAYER_BUS;
|
||||
}
|
||||
|
||||
if( connected_item->ConnectionPropagatesTo( test_item ) &&
|
||||
test_item->ConnectionPropagatesTo( connected_item ) &&
|
||||
bus_connection_ok )
|
||||
if( connected_item->ConnectionPropagatesTo( test_item )
|
||||
&& test_item->ConnectionPropagatesTo( connected_item )
|
||||
&& bus_connection_ok )
|
||||
{
|
||||
connected_item->AddConnectionTo( aSheet, test_item );
|
||||
}
|
||||
@@ -1339,7 +1370,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
|
||||
if( !bus_entry->m_connected_bus_item )
|
||||
{
|
||||
SCH_SCREEN* screen = aSheet.LastScreen();
|
||||
SCH_LINE* bus = screen->GetBus( it.first );
|
||||
SCH_LINE* bus = screen->GetBus( point );
|
||||
|
||||
if( bus )
|
||||
bus_entry->m_connected_bus_item = bus;
|
||||
@@ -1378,11 +1409,8 @@ void CONNECTION_GRAPH::buildItemSubGraphs()
|
||||
// Build subgraphs from items (on a per-sheet basis)
|
||||
for( SCH_ITEM* item : m_items )
|
||||
{
|
||||
for( const auto& it : item->m_connection_map )
|
||||
for( const auto& [sheet, connection] : item->m_connection_map )
|
||||
{
|
||||
const SCH_SHEET_PATH& sheet = it.first;
|
||||
SCH_CONNECTION* connection = it.second;
|
||||
|
||||
if( connection->SubgraphCode() == 0 )
|
||||
{
|
||||
CONNECTION_SUBGRAPH* subgraph = new CONNECTION_SUBGRAPH( this );
|
||||
@@ -1448,7 +1476,6 @@ void CONNECTION_GRAPH::buildItemSubGraphs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1467,44 +1494,45 @@ void CONNECTION_GRAPH::resolveAllDrivers()
|
||||
|
||||
std::vector<std::future<size_t>> returns( dirty_graphs.size() );
|
||||
|
||||
auto update_lambda = []( CONNECTION_SUBGRAPH* subgraph ) -> size_t
|
||||
{
|
||||
if( !subgraph->m_dirty )
|
||||
return 0;
|
||||
|
||||
// Special processing for some items
|
||||
for( SCH_ITEM* item : subgraph->m_items )
|
||||
{
|
||||
switch( item->Type() )
|
||||
auto update_lambda =
|
||||
[]( CONNECTION_SUBGRAPH* subgraph ) -> size_t
|
||||
{
|
||||
case SCH_NO_CONNECT_T:
|
||||
subgraph->m_no_connect = item;
|
||||
break;
|
||||
if( !subgraph->m_dirty )
|
||||
return 0;
|
||||
|
||||
case SCH_BUS_WIRE_ENTRY_T:
|
||||
subgraph->m_bus_entry = item;
|
||||
break;
|
||||
// Special processing for some items
|
||||
for( SCH_ITEM* item : subgraph->m_items )
|
||||
{
|
||||
switch( item->Type() )
|
||||
{
|
||||
case SCH_NO_CONNECT_T:
|
||||
subgraph->m_no_connect = item;
|
||||
break;
|
||||
|
||||
case SCH_PIN_T:
|
||||
{
|
||||
auto pin = static_cast<SCH_PIN*>( item );
|
||||
case SCH_BUS_WIRE_ENTRY_T:
|
||||
subgraph->m_bus_entry = item;
|
||||
break;
|
||||
|
||||
if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
|
||||
subgraph->m_no_connect = item;
|
||||
case SCH_PIN_T:
|
||||
{
|
||||
auto pin = static_cast<SCH_PIN*>( item );
|
||||
|
||||
break;
|
||||
}
|
||||
if( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC )
|
||||
subgraph->m_no_connect = item;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
subgraph->ResolveDrivers( true );
|
||||
subgraph->m_dirty = false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
||||
subgraph->ResolveDrivers( true );
|
||||
subgraph->m_dirty = false;
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
@@ -2304,8 +2332,9 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
[&]( CONNECTION_SUBGRAPH* subgraph ) -> size_t
|
||||
{
|
||||
// Make sure weakly-driven single-pin nets get the unconnected_ prefix
|
||||
if( !subgraph->m_strong_driver && subgraph->m_drivers.size() == 1 &&
|
||||
subgraph->m_driver->Type() == SCH_PIN_T )
|
||||
if( !subgraph->m_strong_driver
|
||||
&& subgraph->m_drivers.size() == 1
|
||||
&& subgraph->m_driver->Type() == SCH_PIN_T )
|
||||
{
|
||||
SCH_PIN* pin = static_cast<SCH_PIN*>( subgraph->m_driver );
|
||||
wxString name = pin->GetDefaultNetName( subgraph->m_sheet, true );
|
||||
|
||||
@@ -590,7 +590,16 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
|
||||
{
|
||||
SCH_SYMBOL* symbol = it->first;
|
||||
|
||||
wxCHECK2( symbol && it->second.m_LibId.IsValid(), continue );
|
||||
wxCHECK2( symbol, ++it; continue );
|
||||
|
||||
if( !it->second.m_LibId.IsValid() )
|
||||
{
|
||||
msg = getSymbolReferences( *symbol, it->second.m_LibId );
|
||||
msg << wxT( ": " ) << _( "*** symbol lib id not valid ***" );
|
||||
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
|
||||
it = symbols.erase( it );
|
||||
continue;
|
||||
}
|
||||
|
||||
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( it->second.m_LibId );
|
||||
|
||||
@@ -647,10 +656,13 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
|
||||
// Remember initial link before changing for diags purpose
|
||||
wxString initialLibLinkName = UnescapeString( symbol->GetLibId().Format() );
|
||||
|
||||
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( symbol_change_info.m_LibId );
|
||||
|
||||
wxCHECK2( libSymbol, continue );
|
||||
|
||||
if( symbol_change_info.m_LibId != symbol->GetLibId() )
|
||||
symbol->SetLibId( symbol_change_info.m_LibId );
|
||||
|
||||
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( symbol_change_info.m_LibId );
|
||||
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
|
||||
SCH_SCREEN* screen = symbol_change_info.m_Instances[0].LastScreen();
|
||||
|
||||
|
||||
@@ -195,6 +195,28 @@ void DIALOG_ERC::UpdateAnnotationWarning()
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_ERC::OnCharHook( wxKeyEvent& aEvt )
|
||||
{
|
||||
if( int hotkey = aEvt.GetKeyCode() )
|
||||
{
|
||||
if( aEvt.ControlDown() )
|
||||
hotkey |= MD_CTRL;
|
||||
if( aEvt.ShiftDown() )
|
||||
hotkey |= MD_SHIFT;
|
||||
if( aEvt.AltDown() )
|
||||
hotkey |= MD_ALT;
|
||||
|
||||
if( hotkey == ACTIONS::excludeMarker.GetHotKey() )
|
||||
{
|
||||
ExcludeMarker();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DIALOG_SHIM::OnCharHook( aEvt );
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_ERC::updateUI()
|
||||
{
|
||||
// If ERC checks ever get slow enough we'll want a progress indicator...
|
||||
@@ -325,6 +347,7 @@ void DIALOG_ERC::OnDeleteAllClick( wxCommandEvent& event )
|
||||
}
|
||||
|
||||
deleteAllMarkers( includeExclusions );
|
||||
m_ercRun = false;
|
||||
|
||||
// redraw the schematic
|
||||
redrawDrawPanel();
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _DIALOG_ERC_H_
|
||||
#define _DIALOG_ERC_H_
|
||||
#pragma once
|
||||
|
||||
#include <wx/htmllbox.h>
|
||||
|
||||
@@ -70,6 +69,7 @@ public:
|
||||
|
||||
private:
|
||||
// from DIALOG_ERC_BASE:
|
||||
void OnCharHook( wxKeyEvent& aEvt ) override;
|
||||
void OnCloseErcDialog( wxCloseEvent& event ) override;
|
||||
void OnRunERCClick( wxCommandEvent& event ) override;
|
||||
void OnDeleteOneClick( wxCommandEvent& event ) override;
|
||||
@@ -116,8 +116,3 @@ private:
|
||||
|
||||
int m_severities;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// _DIALOG_ERC_H_
|
||||
|
||||
@@ -53,10 +53,63 @@
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/filedlg.h>
|
||||
#include <wx/msgdlg.h>
|
||||
#include <wx/process.h>
|
||||
#include <wx/regex.h>
|
||||
#include <wx/txtstrm.h>
|
||||
#include <wx/utils.h>
|
||||
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
std::vector<wxString> SplitCommandLine( const wxString& aCommand )
|
||||
{
|
||||
std::vector<wxString> args;
|
||||
wxString current;
|
||||
bool inSingle = false;
|
||||
bool inDouble = false;
|
||||
bool argStarted = false;
|
||||
|
||||
for( wxUniChar c : aCommand )
|
||||
{
|
||||
if( c == '"' && !inSingle )
|
||||
{
|
||||
inDouble = !inDouble;
|
||||
argStarted = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( c == '\'' && !inDouble )
|
||||
{
|
||||
inSingle = !inSingle;
|
||||
argStarted = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ( c == ' ' || c == '\t' || c == '\n' || c == '\r' ) && !inSingle && !inDouble )
|
||||
{
|
||||
if( argStarted || !current.IsEmpty() )
|
||||
{
|
||||
args.emplace_back( current );
|
||||
current.clear();
|
||||
argStarted = false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
current.Append( c );
|
||||
argStarted = true;
|
||||
}
|
||||
|
||||
if( argStarted || !current.IsEmpty() )
|
||||
args.emplace_back( current );
|
||||
|
||||
return args;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
#define CUSTOMPANEL_COUNTMAX 8 // Max number of netlist plugins
|
||||
@@ -232,16 +285,16 @@ DIALOG_EXPORT_NETLIST::DIALOG_EXPORT_NETLIST( SCH_EDIT_FRAME* aEditFrame, wxWind
|
||||
page->m_LeftBoxSizer->Add( label, 0, wxBOTTOM, 10 );
|
||||
m_PanelNetType[PANELALLEGRO] = page;
|
||||
|
||||
page = new EXPORT_NETLIST_PAGE( m_NoteBook, wxT( "PADS" ), NET_TYPE_PADS, false );
|
||||
label = new wxStaticText( page, wxID_ANY, _( "Export netlist in PADS format" ) );
|
||||
page->m_LeftBoxSizer->Add( label, 0, wxBOTTOM, 10 );
|
||||
m_PanelNetType[PANELPADS] = page;
|
||||
|
||||
page = new EXPORT_NETLIST_PAGE( m_NoteBook, wxT( "CadStar" ), NET_TYPE_CADSTAR, false );
|
||||
label = new wxStaticText( page, wxID_ANY, _( "Export netlist in CadStar format" ) );
|
||||
page->m_LeftBoxSizer->Add( label, 0, wxBOTTOM, 10 );
|
||||
m_PanelNetType[PANELCADSTAR] = page;
|
||||
|
||||
page = new EXPORT_NETLIST_PAGE( m_NoteBook, wxT( "PADS" ), NET_TYPE_PADS, false );
|
||||
label = new wxStaticText( page, wxID_ANY, _( "Export netlist in PADS format" ) );
|
||||
page->m_LeftBoxSizer->Add( label, 0, wxBOTTOM, 10 );
|
||||
m_PanelNetType[PANELPADS] = page;
|
||||
|
||||
InstallPageSpice();
|
||||
InstallPageSpiceModel();
|
||||
|
||||
@@ -616,68 +669,119 @@ bool DIALOG_EXPORT_NETLIST::TransferDataFromWindow()
|
||||
|
||||
if( !commandLine.IsEmpty() )
|
||||
{
|
||||
wxProcess* process = new wxProcess( GetEventHandler(), wxID_ANY );
|
||||
process->Redirect();
|
||||
wxExecute( commandLine, wxEXEC_ASYNC, process );
|
||||
std::vector<wxString> argsStrings = SplitCommandLine( commandLine );
|
||||
|
||||
reporter.ReportHead( commandLine, RPT_SEVERITY_ACTION );
|
||||
process->Activate();
|
||||
|
||||
std::this_thread::sleep_for( std::chrono::seconds( 1 ) ); // give the process time to start and output any data or errors
|
||||
|
||||
if( process->IsInputAvailable() )
|
||||
if( !argsStrings.empty() )
|
||||
{
|
||||
wxInputStream* in = process->GetInputStream();
|
||||
wxTextInputStream textstream( *in );
|
||||
std::vector<const wxChar*> argv;
|
||||
argv.reserve( argsStrings.size() + 1 );
|
||||
|
||||
while( in->CanRead() )
|
||||
for( wxString& arg : argsStrings )
|
||||
argv.emplace_back( arg.wc_str() );
|
||||
|
||||
argv.emplace_back( nullptr );
|
||||
|
||||
wxExecuteEnv env;
|
||||
wxGetEnvMap( &env.env );
|
||||
|
||||
const ENV_VAR_MAP& envVars = Pgm().GetLocalEnvVariables();
|
||||
|
||||
for( const auto& [key, value] : envVars )
|
||||
{
|
||||
wxString line = textstream.ReadLine();
|
||||
|
||||
if( !line.IsEmpty() )
|
||||
reporter.Report( line, RPT_SEVERITY_INFO );
|
||||
if( !value.GetValue().IsEmpty() )
|
||||
env.env[key] = value.GetValue();
|
||||
}
|
||||
}
|
||||
|
||||
if( process->IsErrorAvailable() )
|
||||
{
|
||||
wxInputStream* err = process->GetErrorStream();
|
||||
wxTextInputStream textstream( *err );
|
||||
wxFileName netlistFile( fullpath );
|
||||
|
||||
while( err->CanRead() )
|
||||
if( !netlistFile.IsAbsolute() )
|
||||
netlistFile.MakeAbsolute( Prj().GetProjectPath() );
|
||||
else
|
||||
netlistFile.MakeAbsolute();
|
||||
|
||||
wxString cwd = netlistFile.GetPath();
|
||||
|
||||
if( cwd.IsEmpty() )
|
||||
cwd = Prj().GetProjectPath();
|
||||
|
||||
env.cwd = cwd;
|
||||
|
||||
wxProcess* process = new wxProcess( GetEventHandler(), wxID_ANY );
|
||||
process->Redirect();
|
||||
|
||||
long pid = wxExecute( argv.data(), wxEXEC_ASYNC, process, &env );
|
||||
|
||||
reporter.ReportHead( commandLine, RPT_SEVERITY_ACTION );
|
||||
|
||||
if( pid <= 0 )
|
||||
{
|
||||
wxString line = textstream.ReadLine();
|
||||
reporter.Report( _( "external simulator not found" ), RPT_SEVERITY_ERROR );
|
||||
reporter.Report( _( "Note: command line is usually: "
|
||||
"<tt><path to SPICE binary> \"%I\"</tt>" ),
|
||||
RPT_SEVERITY_INFO );
|
||||
delete process;
|
||||
}
|
||||
else
|
||||
{
|
||||
process->Activate();
|
||||
|
||||
if( !line.IsEmpty() )
|
||||
std::this_thread::sleep_for( std::chrono::seconds( 1 ) ); // give the process time to start and output any data or errors
|
||||
|
||||
if( process->IsInputAvailable() )
|
||||
{
|
||||
if( line.EndsWith( wxS( "failed with error 2!" ) ) ) // ENOENT
|
||||
wxInputStream* in = process->GetInputStream();
|
||||
wxTextInputStream textstream( *in );
|
||||
|
||||
while( in->CanRead() )
|
||||
{
|
||||
reporter.Report( _( "external simulator not found" ), RPT_SEVERITY_ERROR );
|
||||
reporter.Report( _( "Note: command line is usually: "
|
||||
"<tt><path to SPICE binary> \"%I\"</tt>" ),
|
||||
RPT_SEVERITY_INFO );
|
||||
}
|
||||
else if( line.EndsWith( wxS( "failed with error 8!" ) ) ) // ENOEXEC
|
||||
{
|
||||
reporter.Report( _( "external simulator has the wrong format or "
|
||||
"architecture" ), RPT_SEVERITY_ERROR );
|
||||
}
|
||||
else if( line.EndsWith( "failed with error 13!" ) ) // EACCES
|
||||
{
|
||||
reporter.Report( _( "permission denied" ), RPT_SEVERITY_ERROR );
|
||||
}
|
||||
else
|
||||
{
|
||||
reporter.Report( line, RPT_SEVERITY_ERROR );
|
||||
wxString line = textstream.ReadLine();
|
||||
|
||||
if( !line.IsEmpty() )
|
||||
reporter.Report( line, RPT_SEVERITY_INFO );
|
||||
}
|
||||
}
|
||||
|
||||
if( process->IsErrorAvailable() )
|
||||
{
|
||||
wxInputStream* err = process->GetErrorStream();
|
||||
wxTextInputStream textstream( *err );
|
||||
|
||||
while( err->CanRead() )
|
||||
{
|
||||
wxString line = textstream.ReadLine();
|
||||
|
||||
if( !line.IsEmpty() )
|
||||
{
|
||||
if( line.EndsWith( wxS( "failed with error 2!" ) ) ) // ENOENT
|
||||
{
|
||||
reporter.Report( _( "external simulator not found" ), RPT_SEVERITY_ERROR );
|
||||
reporter.Report( _( "Note: command line is usually: "
|
||||
"<tt><path to SPICE binary> \"%I\"</tt>" ),
|
||||
RPT_SEVERITY_INFO );
|
||||
}
|
||||
else if( line.EndsWith( wxS( "failed with error 8!" ) ) ) // ENOEXEC
|
||||
{
|
||||
reporter.Report( _( "external simulator has the wrong format or "
|
||||
"architecture" ), RPT_SEVERITY_ERROR );
|
||||
}
|
||||
else if( line.EndsWith( "failed with error 13!" ) ) // EACCES
|
||||
{
|
||||
reporter.Report( _( "permission denied" ), RPT_SEVERITY_ERROR );
|
||||
}
|
||||
else
|
||||
{
|
||||
reporter.Report( line, RPT_SEVERITY_ERROR );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
process->CloseOutput();
|
||||
process->Detach();
|
||||
|
||||
// Do not delete process, it will delete itself when it terminates
|
||||
}
|
||||
}
|
||||
|
||||
process->CloseOutput();
|
||||
process->Detach();
|
||||
|
||||
// Do not delete process, it will delete itself when it terminates
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -463,12 +463,7 @@ bool DIALOG_FIELD_PROPERTIES::TransferDataToWindow()
|
||||
const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( m_field->GetParentSymbol() );
|
||||
|
||||
for( int ii = 1; ii <= symbol->GetUnitCount(); ii++ )
|
||||
{
|
||||
if( symbol->HasUnitDisplayName( ii ) )
|
||||
m_unitChoice->Append( symbol->GetUnitDisplayName( ii ) );
|
||||
else
|
||||
m_unitChoice->Append( symbol->SubReference( ii, false ) );
|
||||
}
|
||||
m_unitChoice->Append( symbol->GetUnitDisplayName( ii, false ) );
|
||||
|
||||
if( symbol->GetUnit() <= ( int )m_unitChoice->GetCount() )
|
||||
m_unitChoice->SetSelection( symbol->GetUnit() - 1 );
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <kiway.h>
|
||||
#include <macros.h>
|
||||
|
||||
#include <kiplatform/io.h>
|
||||
#include "symbol_lib_table.h"
|
||||
|
||||
|
||||
@@ -102,7 +103,8 @@ bool DIALOG_GLOBAL_SYM_LIB_TABLE_CONFIG::TransferDataFromWindow()
|
||||
// Create the config path if it doesn't already exist.
|
||||
wxFileName symTableFileName = SYMBOL_LIB_TABLE::GetGlobalTableFileName();
|
||||
|
||||
if( !symTableFileName.DirExists() && !symTableFileName.Mkdir( 0x777, wxPATH_MKDIR_FULL ) )
|
||||
if( !wxFileName::DirExists( symTableFileName.GetPath() )
|
||||
&& !wxFileName::Mkdir( symTableFileName.GetPath(), 0x777, wxPATH_MKDIR_FULL ) )
|
||||
{
|
||||
DisplayError( this, wxString::Format( _( "Cannot create global library table '%s'." ),
|
||||
symTableFileName.GetPath() ) );
|
||||
@@ -118,6 +120,9 @@ bool DIALOG_GLOBAL_SYM_LIB_TABLE_CONFIG::TransferDataFromWindow()
|
||||
fn.GetFullPath(), symTableFileName.GetFullPath() ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure the copied file is writable
|
||||
KIPLATFORM::IO::MakeWriteable( symTableFileName.GetFullPath() );
|
||||
}
|
||||
|
||||
// Load the successfully copied symbol library table file. This should not fail since the
|
||||
|
||||
@@ -683,6 +683,7 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataFromWindow()
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
{
|
||||
SCH_GLOBALLABEL* label = new SCH_GLOBALLABEL( *static_cast<SCH_GLOBALLABEL*>( m_currentLabel ) );
|
||||
const_cast<KIID&>( label->m_Uuid ) = KIID(); // Gives a new UUID to the copy
|
||||
label->SetText( text );
|
||||
m_labelList->push_back( std::unique_ptr<SCH_LABEL_BASE>( label ) );
|
||||
break;
|
||||
@@ -690,6 +691,7 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataFromWindow()
|
||||
case SCH_HIER_LABEL_T:
|
||||
{
|
||||
SCH_HIERLABEL* label = new SCH_HIERLABEL( *static_cast<SCH_HIERLABEL*>( m_currentLabel ) );
|
||||
const_cast<KIID&>( label->m_Uuid ) = KIID();
|
||||
label->SetText( text );
|
||||
m_labelList->push_back( std::unique_ptr<SCH_LABEL_BASE>( label ) );
|
||||
break;
|
||||
@@ -697,6 +699,7 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataFromWindow()
|
||||
case SCH_LABEL_T:
|
||||
{
|
||||
SCH_LABEL* label = new SCH_LABEL( *static_cast<SCH_LABEL*>( m_currentLabel ) );
|
||||
const_cast<KIID&>( label->m_Uuid ) = KIID();
|
||||
label->SetText( text );
|
||||
m_labelList->push_back( std::unique_ptr<SCH_LABEL_BASE>( label ) );
|
||||
break;
|
||||
@@ -956,7 +959,7 @@ void DIALOG_LABEL_PROPERTIES::onMultiLabelCheck( wxCommandEvent& event )
|
||||
wxString multiText = m_valueMultiLine->GetValue();
|
||||
m_valueCombo->SetValue( multiText.BeforeFirst( '\n' ) );
|
||||
m_activeTextEntry = m_valueCombo;
|
||||
SetInitialFocus( m_valueCombo );
|
||||
SetInitialFocus( m_valueCombo->GetTextCtrl() );
|
||||
}
|
||||
}
|
||||
else if( m_currentLabel->Type() == SCH_HIER_LABEL_T )
|
||||
|
||||
@@ -827,7 +827,7 @@ DIALOG_LIB_EDIT_PIN_TABLE::DIALOG_LIB_EDIT_PIN_TABLE( SYMBOL_EDIT_FRAME* parent,
|
||||
m_unitFilter->Append( UNITS_ALL );
|
||||
|
||||
for( int ii = 0; ii < aSymbol->GetUnitCount(); ++ii )
|
||||
m_unitFilter->Append( aSymbol->GetUnitReference( ii + 1 ) );
|
||||
m_unitFilter->Append( LIB_SYMBOL::LetterSubReference( ii + 1, 'A' ) );
|
||||
|
||||
m_unitFilter->SetSelection( -1 );
|
||||
}
|
||||
@@ -963,6 +963,7 @@ void DIALOG_LIB_EDIT_PIN_TABLE::OnAddRow( wxCommandEvent& event )
|
||||
newPin->SetType( last->GetType() );
|
||||
newPin->SetShape( last->GetShape() );
|
||||
newPin->SetUnit( last->GetUnit() );
|
||||
newPin->SetBodyStyle( last->GetBodyStyle() );
|
||||
|
||||
VECTOR2I pos = last->GetPosition();
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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 DIALOG_LIB_FIELDS_H
|
||||
#define DIALOG_LIB_FIELDS_H
|
||||
|
||||
#include <dialog_lib_fields_base.h>
|
||||
#include <sch_reference_list.h>
|
||||
#include <widgets/grid_text_button_helpers.h>
|
||||
|
||||
class SYMBOL_EDIT_FRAME;
|
||||
class LIB_FIELDS_EDITOR_GRID_DATA_MODEL;
|
||||
class LIB_SYMBOL;
|
||||
|
||||
class DIALOG_LIB_FIELDS : public DIALOG_LIB_FIELDS_BASE
|
||||
{
|
||||
public:
|
||||
DIALOG_LIB_FIELDS( SYMBOL_EDIT_FRAME* parent, wxString libId, const wxArrayString& aSymbolNames );
|
||||
~DIALOG_LIB_FIELDS() override;
|
||||
|
||||
void OnInit();
|
||||
|
||||
protected:
|
||||
void OnClose( wxCloseEvent& event ) override;
|
||||
void OnColumnItemToggled( wxDataViewEvent& event ) override;
|
||||
void OnFieldsCtrlSelectionChanged( wxDataViewEvent& event ) override;
|
||||
void OnSizeFieldList( wxSizeEvent& event ) override;
|
||||
void OnAddField( wxCommandEvent& event ) override;
|
||||
void OnRenameField( wxCommandEvent& event ) override;
|
||||
void OnRemoveField( wxCommandEvent& event ) override;
|
||||
void OnFilterMouseMoved( wxMouseEvent& event ) override;
|
||||
void OnFilterText( wxCommandEvent& event ) override;
|
||||
void OnRegroupSymbols( wxCommandEvent& event ) override;
|
||||
void OnTableValueChanged( wxGridEvent& event ) override;
|
||||
void OnTableCellClick( wxGridEvent& event ) override;
|
||||
void OnTableItemContextMenu( wxGridEvent& event ) override;
|
||||
void OnTableColSize( wxGridSizeEvent& event ) override;
|
||||
void OnCancel( wxCommandEvent& event ) override;
|
||||
void OnOk( wxCommandEvent& event ) override;
|
||||
void OnApply( wxCommandEvent& event ) override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
private:
|
||||
void UpdateFieldList();
|
||||
void AddField( const wxString& aFieldName, const wxString& aLabelValue, bool show, bool groupBy, bool addedByUser = false, bool aIsCheckbox = false );
|
||||
void RemoveField( const wxString& fieldName );
|
||||
void RenameField( const wxString& oldName, const wxString& newName );
|
||||
void RegroupSymbols();
|
||||
|
||||
void OnColSort( wxGridEvent& aEvent );
|
||||
void OnColMove( wxGridEvent& aEvent );
|
||||
void OnColLabelChange( wxDataViewEvent& aEvent );
|
||||
void SetupColumnProperties( int aCol );
|
||||
void SetupAllColumnProperties();
|
||||
|
||||
void loadSymbols( const wxArrayString& aSymbolNames );
|
||||
|
||||
wxString m_libId;
|
||||
SYMBOL_EDIT_FRAME* m_parent;
|
||||
|
||||
int m_fieldNameColWidth;
|
||||
int m_labelColWidth;
|
||||
int m_showColWidth;
|
||||
int m_groupByColWidth;
|
||||
|
||||
LIB_FIELDS_EDITOR_GRID_DATA_MODEL* m_dataModel;
|
||||
std::vector<LIB_SYMBOL*> m_symbolsList;
|
||||
};
|
||||
|
||||
|
||||
#endif // DIALOG_LIB_FIELDS_H
|
||||
@@ -0,0 +1,203 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "widgets/std_bitmap_button.h"
|
||||
#include "widgets/wx_grid.h"
|
||||
|
||||
#include "dialog_lib_fields_base.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DIALOG_LIB_FIELDS_BASE::DIALOG_LIB_FIELDS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
|
||||
{
|
||||
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
|
||||
|
||||
wxBoxSizer* bMainSizer;
|
||||
bMainSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxBoxSizer* bEditSizer;
|
||||
bEditSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_splitterMainWindow = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH|wxSP_LIVE_UPDATE|wxSP_NO_XP_THEME );
|
||||
m_splitterMainWindow->SetMinimumPaneSize( 200 );
|
||||
|
||||
m_leftPanel = new wxPanel( m_splitterMainWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxBoxSizer* bLeftSizer;
|
||||
bLeftSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_fieldsCtrl = new wxDataViewListCtrl( m_leftPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_fieldsCtrl->SetMinSize( wxSize( -1,250 ) );
|
||||
|
||||
bLeftSizer->Add( m_fieldsCtrl, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
|
||||
wxBoxSizer* bFieldsButtons;
|
||||
bFieldsButtons = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_addFieldButton = new STD_BITMAP_BUTTON( m_leftPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
bFieldsButtons->Add( m_addFieldButton, 0, wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
m_renameFieldButton = new STD_BITMAP_BUTTON( m_leftPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
bFieldsButtons->Add( m_renameFieldButton, 0, wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
|
||||
bFieldsButtons->Add( 15, 0, 0, wxEXPAND, 5 );
|
||||
|
||||
m_removeFieldButton = new STD_BITMAP_BUTTON( m_leftPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
bFieldsButtons->Add( m_removeFieldButton, 0, wxBOTTOM|wxLEFT, 5 );
|
||||
|
||||
|
||||
bLeftSizer->Add( bFieldsButtons, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_leftPanel->SetSizer( bLeftSizer );
|
||||
m_leftPanel->Layout();
|
||||
bLeftSizer->Fit( m_leftPanel );
|
||||
m_rightPanel = new wxPanel( m_splitterMainWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxBoxSizer* bRightSizer;
|
||||
bRightSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxBoxSizer* bControls;
|
||||
bControls = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_filter = new wxSearchCtrl( m_rightPanel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
#ifndef __WXMAC__
|
||||
m_filter->ShowSearchButton( true );
|
||||
#endif
|
||||
m_filter->ShowCancelButton( true );
|
||||
m_filter->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
|
||||
m_filter->SetMinSize( wxSize( 140,-1 ) );
|
||||
|
||||
bControls->Add( m_filter, 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
|
||||
|
||||
m_staticline31 = new wxStaticLine( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL );
|
||||
bControls->Add( m_staticline31, 0, wxEXPAND | wxALL, 3 );
|
||||
|
||||
m_bRefresh = new STD_BITMAP_BUTTON( m_rightPanel, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
|
||||
m_bRefresh->SetMinSize( wxSize( 30,30 ) );
|
||||
|
||||
bControls->Add( m_bRefresh, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
|
||||
|
||||
|
||||
bRightSizer->Add( bControls, 0, wxEXPAND|wxLEFT|wxTOP, 5 );
|
||||
|
||||
m_grid = new WX_GRID( m_rightPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
|
||||
// Grid
|
||||
m_grid->CreateGrid( 5, 5 );
|
||||
m_grid->EnableEditing( true );
|
||||
m_grid->EnableGridLines( true );
|
||||
m_grid->EnableDragGridSize( false );
|
||||
m_grid->SetMargins( 0, 0 );
|
||||
|
||||
// Columns
|
||||
m_grid->EnableDragColMove( true );
|
||||
m_grid->EnableDragColSize( true );
|
||||
m_grid->SetColLabelSize( 24 );
|
||||
m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
|
||||
// Rows
|
||||
m_grid->EnableDragRowSize( false );
|
||||
m_grid->SetRowLabelSize( 0 );
|
||||
m_grid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
|
||||
|
||||
// Label Appearance
|
||||
|
||||
// Cell Defaults
|
||||
m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_CENTER );
|
||||
m_grid->SetMinSize( wxSize( 400,200 ) );
|
||||
|
||||
bRightSizer->Add( m_grid, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
|
||||
|
||||
|
||||
m_rightPanel->SetSizer( bRightSizer );
|
||||
m_rightPanel->Layout();
|
||||
bRightSizer->Fit( m_rightPanel );
|
||||
m_splitterMainWindow->SplitVertically( m_leftPanel, m_rightPanel, -1 );
|
||||
bEditSizer->Add( m_splitterMainWindow, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
|
||||
|
||||
|
||||
bMainSizer->Add( bEditSizer, 1, wxEXPAND, 5 );
|
||||
|
||||
wxBoxSizer* bButtonsSizer;
|
||||
bButtonsSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
|
||||
bButtonsSizer->Add( 0, 0, 9, wxEXPAND, 5 );
|
||||
|
||||
m_sdbSizer = new wxStdDialogButtonSizer();
|
||||
m_sdbSizerOK = new wxButton( this, wxID_OK );
|
||||
m_sdbSizer->AddButton( m_sdbSizerOK );
|
||||
m_sdbSizerApply = new wxButton( this, wxID_APPLY );
|
||||
m_sdbSizer->AddButton( m_sdbSizerApply );
|
||||
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
|
||||
m_sdbSizer->AddButton( m_sdbSizerCancel );
|
||||
m_sdbSizer->Realize();
|
||||
|
||||
bButtonsSizer->Add( m_sdbSizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
|
||||
|
||||
|
||||
bMainSizer->Add( bButtonsSizer, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bMainSizer );
|
||||
this->Layout();
|
||||
bMainSizer->Fit( this );
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
|
||||
// Connect Events
|
||||
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_FIELDS_BASE::OnClose ) );
|
||||
m_fieldsCtrl->Connect( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED, wxDataViewEventHandler( DIALOG_LIB_FIELDS_BASE::OnColumnItemToggled ), NULL, this );
|
||||
m_fieldsCtrl->Connect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_LIB_FIELDS_BASE::OnFieldsCtrlSelectionChanged ), NULL, this );
|
||||
m_fieldsCtrl->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_LIB_FIELDS_BASE::OnSizeFieldList ), NULL, this );
|
||||
m_addFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnAddField ), NULL, this );
|
||||
m_renameFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRenameField ), NULL, this );
|
||||
m_removeFieldButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRemoveField ), NULL, this );
|
||||
m_filter->Connect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_LIB_FIELDS_BASE::OnFilterMouseMoved ), NULL, this );
|
||||
m_filter->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnFilterText ), NULL, this );
|
||||
m_bRefresh->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRegroupSymbols ), NULL, this );
|
||||
m_grid->Connect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableValueChanged ), NULL, this );
|
||||
m_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCellClick ), NULL, this );
|
||||
m_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCellClick ), NULL, this );
|
||||
m_grid->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableItemContextMenu ), NULL, this );
|
||||
m_grid->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCmdCellClick ), NULL, this );
|
||||
m_grid->Connect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCmdCellClick ), NULL, this );
|
||||
m_grid->Connect( wxEVT_GRID_COL_SIZE, wxGridSizeEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableColSize ), NULL, this );
|
||||
m_grid->Connect( wxEVT_GRID_EDITOR_SHOWN, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnEditorShown ), NULL, this );
|
||||
m_grid->Connect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableSelectCell ), NULL, this );
|
||||
m_sdbSizerApply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnApply ), NULL, this );
|
||||
m_sdbSizerCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnCancel ), NULL, this );
|
||||
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnOk ), NULL, this );
|
||||
}
|
||||
|
||||
DIALOG_LIB_FIELDS_BASE::~DIALOG_LIB_FIELDS_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_LIB_FIELDS_BASE::OnClose ) );
|
||||
m_fieldsCtrl->Disconnect( wxEVT_COMMAND_DATAVIEW_ITEM_VALUE_CHANGED, wxDataViewEventHandler( DIALOG_LIB_FIELDS_BASE::OnColumnItemToggled ), NULL, this );
|
||||
m_fieldsCtrl->Disconnect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_LIB_FIELDS_BASE::OnFieldsCtrlSelectionChanged ), NULL, this );
|
||||
m_fieldsCtrl->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_LIB_FIELDS_BASE::OnSizeFieldList ), NULL, this );
|
||||
m_addFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnAddField ), NULL, this );
|
||||
m_renameFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRenameField ), NULL, this );
|
||||
m_removeFieldButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRemoveField ), NULL, this );
|
||||
m_filter->Disconnect( wxEVT_MOTION, wxMouseEventHandler( DIALOG_LIB_FIELDS_BASE::OnFilterMouseMoved ), NULL, this );
|
||||
m_filter->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnFilterText ), NULL, this );
|
||||
m_bRefresh->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnRegroupSymbols ), NULL, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_CELL_CHANGED, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableValueChanged ), NULL, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCellClick ), NULL, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCellClick ), NULL, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableItemContextMenu ), NULL, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCmdCellClick ), NULL, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableCmdCellClick ), NULL, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_COL_SIZE, wxGridSizeEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableColSize ), NULL, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_EDITOR_SHOWN, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnEditorShown ), NULL, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_SELECT_CELL, wxGridEventHandler( DIALOG_LIB_FIELDS_BASE::OnTableSelectCell ), NULL, this );
|
||||
m_sdbSizerApply->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnApply ), NULL, this );
|
||||
m_sdbSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnCancel ), NULL, this );
|
||||
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_FIELDS_BASE::OnOk ), NULL, this );
|
||||
|
||||
}
|
||||
@@ -0,0 +1,898 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<wxFormBuilder_Project>
|
||||
<FileVersion major="1" minor="18"/>
|
||||
<object class="Project" expanded="true">
|
||||
<property name="code_generation">C++</property>
|
||||
<property name="cpp_class_decoration"></property>
|
||||
<property name="cpp_disconnect_events">1</property>
|
||||
<property name="cpp_event_generation">connect</property>
|
||||
<property name="cpp_help_provider">none</property>
|
||||
<property name="cpp_namespace"></property>
|
||||
<property name="cpp_precompiled_header"></property>
|
||||
<property name="cpp_use_array_enum">0</property>
|
||||
<property name="cpp_use_enum">0</property>
|
||||
<property name="embedded_files_path">res</property>
|
||||
<property name="encoding">UTF-8</property>
|
||||
<property name="file">dialog_lib_fields_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="lua_skip_events">1</property>
|
||||
<property name="lua_ui_table">UI</property>
|
||||
<property name="name">dialog_lib_fields_base</property>
|
||||
<property name="path">.</property>
|
||||
<property name="php_disconnect_events">0</property>
|
||||
<property name="php_disconnect_mode">source_name</property>
|
||||
<property name="php_skip_events">1</property>
|
||||
<property name="python_disconnect_events">0</property>
|
||||
<property name="python_disconnect_mode">source_name</property>
|
||||
<property name="python_image_path_wrapper_function_name"></property>
|
||||
<property name="python_indent_with_spaces"></property>
|
||||
<property name="python_skip_events">1</property>
|
||||
<property name="relative_path">1</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<property name="use_native_eol">0</property>
|
||||
<object class="Dialog" expanded="true">
|
||||
<property name="aui_managed">0</property>
|
||||
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
|
||||
<property name="bg"></property>
|
||||
<property name="center">wxBOTH</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="event_handler">impl_virtual</property>
|
||||
<property name="extra_style"></property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size">-1,-1</property>
|
||||
<property name="name">DIALOG_LIB_FIELDS_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size">-1,-1</property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER</property>
|
||||
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
|
||||
<property name="title">Library Fields Editor</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="two_step_creation">0</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnClose">OnClose</event>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<property name="minimum_size">-1,-1</property>
|
||||
<property name="name">bMainSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bEditSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxSplitterWindow" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</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="drag_accept_files">0</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="min_pane_size">200</property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size">-1,-1</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_splitterMainWindow</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="sashgravity">0.0</property>
|
||||
<property name="sashpos">-1</property>
|
||||
<property name="sashsize">-1</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="splitmode">wxSPLIT_VERTICAL</property>
|
||||
<property name="style">wxSP_3DSASH|wxSP_LIVE_UPDATE|wxSP_NO_XP_THEME</property>
|
||||
<property name="subclass"></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>
|
||||
<object class="splitteritem" expanded="true">
|
||||
<object class="wxPanel" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</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="drag_accept_files">0</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="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_leftPanel</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="subclass"></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">wxTAB_TRAVERSAL</property>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bLeftSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxDataViewListCtrl" expanded="false">
|
||||
<property name="bg"></property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size">-1,250</property>
|
||||
<property name="name">m_fieldsCtrl</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnDataViewListCtrlItemValueChanged">OnColumnItemToggled</event>
|
||||
<event name="OnDataViewListCtrlSelectionChanged">OnFieldsCtrlSelectionChanged</event>
|
||||
<event name="OnSize">OnSizeFieldList</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bFieldsButtons</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBitmapButton" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</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="drag_accept_files">0</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_addFieldButton</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">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; 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">OnAddField</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBitmapButton" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</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="drag_accept_files">0</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">Rename Field...</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_renameFieldButton</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">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; 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">OnRenameField</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="spacer" expanded="true">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">15</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxLEFT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBitmapButton" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</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="drag_accept_files">0</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">Remove Field...</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_removeFieldButton</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">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; 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">OnRemoveField</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="splitteritem" expanded="true">
|
||||
<object class="wxPanel" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</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="drag_accept_files">0</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="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_rightPanel</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="subclass"></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">wxTAB_TRAVERSAL</property>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bRightSizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND|wxLEFT|wxTOP</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bControls</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxSearchCtrl" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="cancel_button">1</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="drag_accept_files">0</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font">,90,400,-1,70,0</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="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size">140,-1</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_filter</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="search_button">1</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="OnMotion">OnFilterMouseMoved</event>
|
||||
<event name="OnText">OnFilterText</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">3</property>
|
||||
<property name="flag">wxEXPAND | wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticLine" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</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="drag_accept_files">0</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="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticline31</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">wxLI_VERTICAL</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>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBitmapButton" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</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="drag_accept_files">0</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">Refresh Grouping</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">30,30</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_bRefresh</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">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; 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">OnRegroupSymbols</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxGrid" expanded="false">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer">0</property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position">0</property>
|
||||
<property name="aui_row">0</property>
|
||||
<property name="autosize_cols">0</property>
|
||||
<property name="autosize_rows">0</property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="cell_bg"></property>
|
||||
<property name="cell_font"></property>
|
||||
<property name="cell_horiz_alignment">wxALIGN_LEFT</property>
|
||||
<property name="cell_text"></property>
|
||||
<property name="cell_vert_alignment">wxALIGN_CENTER</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
|
||||
<property name="col_label_size">24</property>
|
||||
<property name="col_label_values"></property>
|
||||
<property name="col_label_vert_alignment">wxALIGN_CENTER</property>
|
||||
<property name="cols">5</property>
|
||||
<property name="column_sizes"></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="drag_accept_files">0</property>
|
||||
<property name="drag_col_move">1</property>
|
||||
<property name="drag_col_size">1</property>
|
||||
<property name="drag_grid_size">0</property>
|
||||
<property name="drag_row_size">0</property>
|
||||
<property name="editing">1</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="grid_line_color"></property>
|
||||
<property name="grid_lines">1</property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label_bg"></property>
|
||||
<property name="label_font"></property>
|
||||
<property name="label_text"></property>
|
||||
<property name="margin_height">0</property>
|
||||
<property name="margin_width">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">400,200</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_grid</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="row_label_horiz_alignment">wxALIGN_CENTER</property>
|
||||
<property name="row_label_size">0</property>
|
||||
<property name="row_label_values"></property>
|
||||
<property name="row_label_vert_alignment">wxALIGN_CENTER</property>
|
||||
<property name="row_sizes"></property>
|
||||
<property name="rows">5</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="subclass">WX_GRID; widgets/wx_grid.h; 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>
|
||||
<event name="OnGridCellChange">OnTableValueChanged</event>
|
||||
<event name="OnGridCellLeftClick">OnTableCellClick</event>
|
||||
<event name="OnGridCellLeftDClick">OnTableCellClick</event>
|
||||
<event name="OnGridCellRightClick">OnTableItemContextMenu</event>
|
||||
<event name="OnGridCmdCellLeftClick">OnTableCmdCellClick</event>
|
||||
<event name="OnGridCmdCellLeftDClick">OnTableCmdCellClick</event>
|
||||
<event name="OnGridColSize">OnTableColSize</event>
|
||||
<event name="OnGridEditorShown">OnEditorShown</event>
|
||||
<event name="OnGridSelectCell">OnTableSelectCell</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="true">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="true">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bButtonsSizer</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">9</property>
|
||||
<object class="spacer" expanded="false">
|
||||
<property name="height">0</property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="width">0</property>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="false">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStdDialogButtonSizer" expanded="false">
|
||||
<property name="Apply">1</property>
|
||||
<property name="Cancel">1</property>
|
||||
<property name="ContextHelp">0</property>
|
||||
<property name="Help">0</property>
|
||||
<property name="No">0</property>
|
||||
<property name="OK">1</property>
|
||||
<property name="Save">0</property>
|
||||
<property name="Yes">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_sdbSizer</property>
|
||||
<property name="permission">protected</property>
|
||||
<event name="OnApplyButtonClick">OnApply</event>
|
||||
<event name="OnCancelButtonClick">OnCancel</event>
|
||||
<event name="OnOKButtonClick">OnOk</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</wxFormBuilder_Project>
|
||||
@@ -0,0 +1,92 @@
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6a-dirty)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
class STD_BITMAP_BUTTON;
|
||||
class WX_GRID;
|
||||
|
||||
#include "dialog_shim.h"
|
||||
#include <wx/dataview.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/srchctrl.h>
|
||||
#include <wx/statline.h>
|
||||
#include <wx/grid.h>
|
||||
#include <wx/splitter.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class DIALOG_LIB_FIELDS_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class DIALOG_LIB_FIELDS_BASE : public DIALOG_SHIM
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxSplitterWindow* m_splitterMainWindow;
|
||||
wxPanel* m_leftPanel;
|
||||
wxDataViewListCtrl* m_fieldsCtrl;
|
||||
STD_BITMAP_BUTTON* m_addFieldButton;
|
||||
STD_BITMAP_BUTTON* m_renameFieldButton;
|
||||
STD_BITMAP_BUTTON* m_removeFieldButton;
|
||||
wxPanel* m_rightPanel;
|
||||
wxSearchCtrl* m_filter;
|
||||
wxStaticLine* m_staticline31;
|
||||
STD_BITMAP_BUTTON* m_bRefresh;
|
||||
WX_GRID* m_grid;
|
||||
wxStdDialogButtonSizer* m_sdbSizer;
|
||||
wxButton* m_sdbSizerOK;
|
||||
wxButton* m_sdbSizerApply;
|
||||
wxButton* m_sdbSizerCancel;
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
|
||||
virtual void OnColumnItemToggled( wxDataViewEvent& event ) { event.Skip(); }
|
||||
virtual void OnFieldsCtrlSelectionChanged( wxDataViewEvent& event ) { event.Skip(); }
|
||||
virtual void OnSizeFieldList( wxSizeEvent& event ) { event.Skip(); }
|
||||
virtual void OnAddField( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnRenameField( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnRemoveField( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnFilterMouseMoved( wxMouseEvent& event ) { event.Skip(); }
|
||||
virtual void OnFilterText( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnRegroupSymbols( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnTableValueChanged( wxGridEvent& event ) { event.Skip(); }
|
||||
virtual void OnTableCellClick( wxGridEvent& event ) { event.Skip(); }
|
||||
virtual void OnTableItemContextMenu( wxGridEvent& event ) { event.Skip(); }
|
||||
virtual void OnTableCmdCellClick( wxGridEvent& event ) { event.Skip(); }
|
||||
virtual void OnTableColSize( wxGridSizeEvent& event ) { event.Skip(); }
|
||||
virtual void OnEditorShown( wxGridEvent& event ) { event.Skip(); }
|
||||
virtual void OnTableSelectCell( wxGridEvent& event ) { event.Skip(); }
|
||||
virtual void OnApply( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnCancel( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnOk( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_LIB_FIELDS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Library Fields Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER );
|
||||
|
||||
~DIALOG_LIB_FIELDS_BASE();
|
||||
|
||||
};
|
||||
|
||||
@@ -84,6 +84,7 @@ DIALOG_LIB_SYMBOL_PROPERTIES::DIALOG_LIB_SYMBOL_PROPERTIES( SYMBOL_EDIT_FRAME* a
|
||||
} ) );
|
||||
m_grid->SetSelectionMode( wxGrid::wxGridSelectRows );
|
||||
|
||||
|
||||
// Show/hide columns according to the user's preference
|
||||
SYMBOL_EDITOR_SETTINGS* cfg = m_Parent->GetSettings();
|
||||
m_grid->ShowHideColumns( cfg->m_EditSymbolVisibleColumns );
|
||||
@@ -110,8 +111,11 @@ DIALOG_LIB_SYMBOL_PROPERTIES::DIALOG_LIB_SYMBOL_PROPERTIES( SYMBOL_EDIT_FRAME* a
|
||||
|
||||
// wxFormBuilder doesn't include this event...
|
||||
m_grid->Connect( wxEVT_GRID_CELL_CHANGING,
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging ),
|
||||
nullptr, this );
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging ), nullptr, this );
|
||||
m_grid->Connect( wxEVT_GRID_CELL_CHANGED,
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanged ), nullptr, this );
|
||||
m_grid->GetGridWindow()->Bind( wxEVT_MOTION, &DIALOG_LIB_SYMBOL_PROPERTIES::OnGridMotion, this );
|
||||
|
||||
|
||||
// Forward the delete button to the tricks
|
||||
m_deleteFilterButton->Bind( wxEVT_BUTTON,
|
||||
@@ -161,8 +165,10 @@ DIALOG_LIB_SYMBOL_PROPERTIES::~DIALOG_LIB_SYMBOL_PROPERTIES()
|
||||
m_grid->DestroyTable( m_fields );
|
||||
|
||||
m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING,
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging ),
|
||||
nullptr, this );
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging ), nullptr, this );
|
||||
m_grid->Disconnect( wxEVT_GRID_CELL_CHANGED,
|
||||
wxGridEventHandler( DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanged ), nullptr, this );
|
||||
m_grid->GetGridWindow()->Unbind( wxEVT_MOTION, &DIALOG_LIB_SYMBOL_PROPERTIES::OnGridMotion, this );
|
||||
|
||||
// Delete the GRID_TRICKS.
|
||||
m_grid->PopEventHandler( true );
|
||||
@@ -174,9 +180,58 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow()
|
||||
if( !wxDialog::TransferDataToWindow() )
|
||||
return false;
|
||||
|
||||
// Push a copy of each field into m_updateFields
|
||||
// Ensure the fields vector is empty before (re)loading. Constructor no longer
|
||||
// pre-populates fields to avoid double insertion of mandatory fields.
|
||||
if( m_fields->size() > 0 )
|
||||
{
|
||||
// Clear existing entries; we recreate inheritance metadata via push_back()
|
||||
// Note: We cannot simply reuse existing entries because alias inheritance
|
||||
// state may have changed if the parent was edited prior to dialog open.
|
||||
m_fields->clear();
|
||||
}
|
||||
|
||||
// Load current symbol fields (mandatory first, then user fields)
|
||||
m_libEntry->CopyFields( *m_fields );
|
||||
|
||||
// Handle alias (derived) symbol inherited fields. We only inherit non-mandatory fields
|
||||
// and mark any matching names as inherited rather than duplicating them.
|
||||
if( m_libEntry->IsAlias() )
|
||||
{
|
||||
if( std::shared_ptr<LIB_SYMBOL> parent = m_libEntry->GetParent().lock() )
|
||||
{
|
||||
std::vector<SCH_FIELD*> parentFields;
|
||||
parent->GetFields( parentFields );
|
||||
|
||||
for( SCH_FIELD* pf : parentFields )
|
||||
{
|
||||
if( pf->IsMandatory() )
|
||||
continue; // Never inherit mandatory fields
|
||||
|
||||
bool found = false;
|
||||
|
||||
for( size_t jj = 0; jj < m_fields->size(); ++jj )
|
||||
{
|
||||
SCH_FIELD& f = m_fields->at( jj );
|
||||
|
||||
if( f.IsMandatory() )
|
||||
continue; // Skip mandatory in child list for inheritance match
|
||||
|
||||
if( f.GetCanonicalName() == pf->GetCanonicalName() )
|
||||
{
|
||||
m_fields->SetFieldInherited( jj, *pf );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
m_fields->AddInheritedField( *pf );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fields already loaded above; avoid re-copying to prevent duplication.
|
||||
|
||||
std::set<wxString> defined;
|
||||
|
||||
for( SCH_FIELD& field : *m_fields )
|
||||
@@ -275,7 +330,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataToWindow()
|
||||
|
||||
m_inheritanceSelectCombo->Append( symbolNames );
|
||||
|
||||
if( LIB_SYMBOL_SPTR rootSymbol = m_libEntry->GetParent().lock() )
|
||||
if( std::shared_ptr<LIB_SYMBOL> rootSymbol = m_libEntry->GetParent().lock() )
|
||||
{
|
||||
wxString parentName = UnescapeString( rootSymbol->GetName() );
|
||||
int selection = m_inheritanceSelectCombo->FindString( parentName );
|
||||
@@ -416,37 +471,40 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||
m_Parent->SaveCopyInUndoList( _( "Edit Symbol Properties" ), m_libEntry );
|
||||
}
|
||||
|
||||
// The Y axis for components in lib is from bottom to top while the screen axis is top
|
||||
// to bottom: we must change the y coord sign when writing back to the library
|
||||
for( int ii = 0; ii < (int) m_fields->size(); ++ii )
|
||||
{
|
||||
VECTOR2I pos = m_fields->at( ii ).GetPosition();
|
||||
pos.y = -pos.y;
|
||||
m_fields->at( ii ).SetPosition( pos );
|
||||
m_fields->at( ii ).SetId( ii );
|
||||
}
|
||||
std::vector<SCH_FIELD> fieldsToSave;
|
||||
|
||||
for( int ii = m_fields->GetNumberRows() - 1; ii >= 0; ii-- )
|
||||
{
|
||||
SCH_FIELD& field = m_fields->at( ii );
|
||||
|
||||
if( field.IsMandatory() )
|
||||
continue;
|
||||
// The Y axis for components in lib is from bottom to top while the screen axis is top
|
||||
// to bottom: we must change the y coord sign when writing back to the library
|
||||
VECTOR2I pos = field.GetPosition();
|
||||
pos.y = -pos.y;
|
||||
field.SetPosition( pos );
|
||||
|
||||
const wxString& fieldName = field.GetCanonicalName();
|
||||
// if( !field.IsMandatory() )
|
||||
field.SetId( ii );
|
||||
|
||||
wxString fieldName = field.GetCanonicalName();
|
||||
|
||||
if( m_fields->IsInherited( ii ) && field == m_fields->ParentField( ii ) )
|
||||
continue; // Skip inherited fields
|
||||
|
||||
if( field.GetText().IsEmpty() )
|
||||
{
|
||||
if( fieldName.IsEmpty() || m_addedTemplateFields.contains( fieldName ) )
|
||||
m_fields->erase( m_fields->begin() + ii );
|
||||
continue; // Skip empty fields that are not mandatory or template fields
|
||||
}
|
||||
else if( fieldName.IsEmpty() )
|
||||
{
|
||||
field.SetName( _( "untitled" ) );
|
||||
field.SetName( _( "untitled" ) ); // Set a default name for unnamed fields
|
||||
}
|
||||
|
||||
fieldsToSave.push_back( field );
|
||||
}
|
||||
|
||||
m_libEntry->SetFields( *m_fields );
|
||||
m_libEntry->SetFields( fieldsToSave );
|
||||
|
||||
// Update the parent for inherited symbols
|
||||
if( m_libEntry->IsAlias() )
|
||||
@@ -517,6 +575,27 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridMotion( wxMouseEvent& aEvent )
|
||||
{
|
||||
aEvent.Skip();
|
||||
|
||||
wxPoint pos = aEvent.GetPosition();
|
||||
wxPoint unscolled_pos = m_grid->CalcUnscrolledPosition( pos );
|
||||
int row = m_grid->YToRow( unscolled_pos.y );
|
||||
int col = m_grid->XToCol( unscolled_pos.x );
|
||||
|
||||
if( row == wxNOT_FOUND || col == wxNOT_FOUND || !m_fields->IsInherited( row ) )
|
||||
{
|
||||
m_grid->SetToolTip( "" );
|
||||
return;
|
||||
}
|
||||
|
||||
m_grid->SetToolTip(
|
||||
wxString::Format( _( "This field is inherited from '%s'." ),
|
||||
m_fields->ParentField( row ).GetName() ) );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
|
||||
{
|
||||
wxGridCellEditor* editor = m_grid->GetCellEditor( event.GetRow(), event.GetCol() );
|
||||
@@ -555,6 +634,13 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanging( wxGridEvent& event )
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_LIB_SYMBOL_PROPERTIES::OnGridCellChanged( wxGridEvent& event )
|
||||
{
|
||||
m_grid->ForceRefresh();
|
||||
OnModify();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_LIB_SYMBOL_PROPERTIES::OnSymbolNameText( wxCommandEvent& event )
|
||||
{
|
||||
if( m_OptionPower->IsChecked() )
|
||||
|
||||
@@ -68,6 +68,8 @@ private:
|
||||
void OnEditFootprintFilter( wxCommandEvent& event ) override;
|
||||
void OnSizeGrid( wxSizeEvent& event ) override;
|
||||
void OnGridCellChanging( wxGridEvent& event );
|
||||
void OnGridCellChanged( wxGridEvent& event );
|
||||
void OnGridMotion( wxMouseEvent& event );
|
||||
void OnEditSpiceModel( wxCommandEvent& event ) override;
|
||||
void OnUpdateUI( wxUpdateUIEvent& event ) override;
|
||||
void OnCancelButtonClick( wxCommandEvent& event ) override;
|
||||
|
||||
@@ -1003,6 +1003,7 @@ void DIALOG_SIM_COMMAND::OnFilterText( wxCommandEvent& aEvent )
|
||||
|
||||
void DIALOG_SIM_COMMAND::OnFilterMouseMoved( wxMouseEvent& aEvent )
|
||||
{
|
||||
#if defined( __WXOSX__ ) || wxCHECK_VERSION( 3, 3, 0 ) // Doesn't work properly on other ports
|
||||
wxPoint pos = aEvent.GetPosition();
|
||||
wxRect ctrlRect = m_inputSignalsFilter->GetScreenRect();
|
||||
int buttonWidth = ctrlRect.GetHeight(); // Presume buttons are square
|
||||
@@ -1014,6 +1015,7 @@ void DIALOG_SIM_COMMAND::OnFilterMouseMoved( wxMouseEvent& aEvent )
|
||||
SetCursor( wxCURSOR_ARROW );
|
||||
else
|
||||
SetCursor( wxCURSOR_IBEAM );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -88,7 +88,8 @@ DIALOG_SIM_MODEL<T>::DIALOG_SIM_MODEL( wxWindow* aParent, EDA_BASE_FRAME* aFrame
|
||||
m_filesStack.push_back( symbol->Schematic()->GetEmbeddedFiles() );
|
||||
}
|
||||
|
||||
m_filesStack.push_back( aSymbol.GetEmbeddedFiles() );
|
||||
if( EMBEDDED_FILES* symbolEmbeddedFiles = aSymbol.GetEmbeddedFiles() )
|
||||
m_filesStack.push_back( symbolEmbeddedFiles );
|
||||
|
||||
m_libraryModelsMgr.SetFilesStack( m_filesStack );
|
||||
m_builtinModelsMgr.SetFilesStack( m_filesStack );
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user