Compare commits

..

633 Commits

Author SHA1 Message Date
Wayne Stambaugh cc82296118 Tag stable version 9.0.7. 2026-01-01 12:54:29 -05:00
Alex Shvartzkop bce055fa21 Update translations 2026-01-01 20:31:21 +03:00
Sárkány Lőrinc 45471ecfc9 Translated using Weblate (Hungarian)
Currently translated at 51.6% (5219 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2026-01-01 15:49:57 +01:00
Marco Ciampa ca8633b3db Translated using Weblate (Italian)
Currently translated at 99.4% (10043 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2026-01-01 15:49:57 +01:00
2tama3 fbb70da3c0 Translated using Weblate (Japanese)
Currently translated at 100.0% (10103 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2026-01-01 15:49:57 +01:00
Marco Ciampa 8f8c937db5 Translated using Weblate (Italian)
Currently translated at 99.3% (10037 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2026-01-01 15:49:56 +01:00
Sárkány Lőrinc b62a67ceba Translated using Weblate (Hungarian)
Currently translated at 51.6% (5217 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2026-01-01 15:49:56 +01:00
2tama3 c0c25fb1d7 Translated using Weblate (Japanese)
Currently translated at 100.0% (10103 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2026-01-01 15:49:56 +01:00
Sárkány Lőrinc 2b3d3bc41b Translated using Weblate (Hungarian)
Currently translated at 51.4% (5200 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2026-01-01 15:49:56 +01:00
Sárkány Lőrinc 60d64c8c1b Translated using Weblate (Hungarian)
Currently translated at 51.3% (5192 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2026-01-01 15:49:56 +01:00
Sárkány Lőrinc b5a54e8822 Translated using Weblate (Hungarian)
Currently translated at 51.1% (5172 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2026-01-01 15:49:56 +01:00
Sárkány Lőrinc 962aadb859 Translated using Weblate (Hungarian)
Currently translated at 51.1% (5170 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2026-01-01 15:49:56 +01:00
Sárkány Lőrinc e2a5b8ee74 Translated using Weblate (Hungarian)
Currently translated at 49.3% (4988 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2026-01-01 15:49:56 +01:00
2tama3 a3f7e5339b Translated using Weblate (Japanese)
Currently translated at 100.0% (10103 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2026-01-01 15:49:56 +01:00
Henrik Kauhanen c5964c59ce Translated using Weblate (Swedish)
Currently translated at 99.9% (10097 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2026-01-01 15:49:55 +01:00
Sárkány Lőrinc dcff6e0547 Translated using Weblate (Hungarian)
Currently translated at 48.0% (4852 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2026-01-01 15:49:55 +01:00
Wayne Stambaugh 9f6e81e9cc Tag stable version 9.0.7 release candidate 2. 2025-12-23 15:40:18 -05:00
Alex Shvartzkop 17c867e92f Update translations 2025-12-23 05:02:55 +03:00
Sárkány Lőrinc 938dec0d6e Translated using Weblate (Hungarian)
Currently translated at 47.8% (4835 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-23 03:02:04 +01:00
CloverGit 0107ac0532 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10090 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-23 03:02:04 +01:00
soldado-do-wolfenstein d4910a66dc Translated using Weblate (Portuguese (Brazil))
Currently translated at 97.6% (9867 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/pt_BR/
2025-12-23 03:02:04 +01:00
Sárkány Lőrinc 89ebfa63c9 Translated using Weblate (Hungarian)
Currently translated at 47.7% (4825 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-23 03:02:04 +01:00
Sárkány Lőrinc 451642fa62 Translated using Weblate (Hungarian)
Currently translated at 46.6% (4713 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-23 03:02:04 +01:00
CharlieYu 8f52e2b685 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.9% (10093 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-23 03:02:03 +01:00
Temuri Doghonadze 3597d76c40 Translated using Weblate (Georgian)
Currently translated at 32.8% (3319 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-12-23 03:02:03 +01:00
Sárkány Lőrinc 6c092d78a3 Translated using Weblate (Hungarian)
Currently translated at 45.4% (4594 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-23 03:02:03 +01:00
Marco Ciampa 95bbcc40d4 Translated using Weblate (Italian)
Currently translated at 99.3% (10036 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-23 03:02:03 +01:00
Sárkány Lőrinc 2ebe4cc9e2 Translated using Weblate (Hungarian)
Currently translated at 45.4% (4590 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-23 03:02:03 +01:00
Sárkány Lőrinc 2f52c4901a Translated using Weblate (Hungarian)
Currently translated at 45.3% (4579 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-23 03:02:03 +01:00
Sárkány Lőrinc 689fb262c5 Translated using Weblate (Hungarian)
Currently translated at 45.2% (4568 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-23 03:02:03 +01:00
Sárkány Lőrinc 16b0ec206a Translated using Weblate (Hungarian)
Currently translated at 44.8% (4529 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-23 03:02:03 +01:00
Pferd O. 890735dbe1 Translated using Weblate (German)
Currently translated at 100.0% (10103 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-12-23 03:02:03 +01:00
Jon Evans 3cfb633ea4 Avoid crash when project tree files disappear
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22568
2025-12-22 15:55:25 -05:00
Alex Shvartzkop 92274f1a5d Fix assert failure when opening simulator frame
Fixes KICAD-XS2
2025-12-20 19:01:08 +03:00
Alex Shvartzkop 7d03b6bb8c Fix assert failures when opening non-ASCII files in gerbview.
Fixes KICAD-KEV
2025-12-20 03:19:28 +03:00
Alex Shvartzkop 9ae5759e24 Specctra DSN: fix assert failures when exporting footprint arcs.
Fixes KICAD-PG4
2025-12-20 02:04:48 +03:00
Alex Shvartzkop 11467a7f4b Specctra DSN export: add last rectangle edge. 2025-12-20 02:04:48 +03:00
Wayne Stambaugh f8f051275f Fix Windows build error. 2025-12-19 16:46:04 -05:00
Wayne Stambaugh a167322440 Do not assume sheet path is valid when getting sheet page number.
Fixes KICAD-C4Q
2025-12-19 15:41:34 -05:00
Jeff Young 2b1747f80f Careful of unspecified start reference.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22552

(cherry picked from commit 1aed1d5f2f)
2025-12-19 13:21:02 +00:00
jean-pierre charras 26b350b51a symbol editor: import SVG: fix incorrect import of degenerated splines
Degenerated splines are in fact segments. So they are imported as 2 points polylines.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22556

(cherry picked from commit 1b17b57be0)
2025-12-19 15:47:06 +03:00
Jeff Young 64821c793f Don't test clearance or shorting for same-net items; only holes.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22532

(cherry picked from commit 57c9866094)
2025-12-16 14:11:10 +00:00
Alex Shvartzkop 50ddfefbbb Fix potential crash when multichannel tool can't find any rule areas.
fbp dialog changes:
- Don't add the first grid row,
- Resize the grid with the dialog window,
- Improve min sizes.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22535
2025-12-16 16:27:56 +03:00
jean-pierre charras 49ee909d68 DIALOG_LABEL_PROPERTIES: ensure multiple placed labels have a unique ID
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22529

(cherry picked from commit e20671ea73)
2025-12-15 10:03:09 +01:00
Wayne Stambaugh 85ebd7c371 Tag stable version 9.0.7 release candidate 1. 2025-12-14 09:30:40 -05:00
jean-pierre charras 12d1f5bdd9 SVG_PLOTTER: fix incorrect bitmaps position is some cases
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22326

Cherry picked by hand.
2025-12-14 14:10:18 +01:00
Alex Shvartzkop 5071295d34 Update translations 2025-12-13 20:08:29 +03:00
CloverGit 5885b364a3 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.7% (10082 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-13 18:07:50 +01:00
Sárkány Lőrinc 1a04549321 Translated using Weblate (Hungarian)
Currently translated at 44.1% (4464 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-13 18:07:50 +01:00
Sárkány Lőrinc b9819bc8ae Translated using Weblate (Hungarian)
Currently translated at 44.1% (4460 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-13 18:07:50 +01:00
2tama3 7cd534c614 Translated using Weblate (Japanese)
Currently translated at 100.0% (10103 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-12-13 18:07:50 +01:00
Pferd O. f652fbcfcf Translated using Weblate (German)
Currently translated at 99.9% (10098 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-12-13 18:07:50 +01:00
Максим Горпиніч 6085182574 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (10103 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/uk/
2025-12-13 18:07:50 +01:00
Henrik Kauhanen 3aa22cd4e4 Translated using Weblate (Swedish)
Currently translated at 99.9% (10095 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-12-13 18:07:49 +01:00
Marco Ciampa 7e33fc18d3 Translated using Weblate (Italian)
Currently translated at 99.3% (10034 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-13 18:07:49 +01:00
dsa-t 0503b22617 Translated using Weblate (Russian)
Currently translated at 100.0% (10103 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ru/
2025-12-13 18:07:49 +01:00
2tama3 e2562aae5d Translated using Weblate (Japanese)
Currently translated at 100.0% (10103 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-12-13 18:07:49 +01:00
Henrik Kauhanen b1b28786af Translated using Weblate (Swedish)
Currently translated at 99.9% (10094 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-12-13 18:07:49 +01:00
Sárkány Lőrinc 355afb9845 Translated using Weblate (Hungarian)
Currently translated at 44.1% (4459 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-13 18:07:49 +01:00
Vic 14d2ebc607 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 98.1% (9913 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hant/
2025-12-13 18:07:49 +01:00
Максим Горпиніч c48ace68a0 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (10103 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/uk/
2025-12-13 18:07:48 +01:00
Ivan Chuba c82caa6dc1 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (10103 of 10103 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/uk/
2025-12-13 18:07:48 +01:00
Alex Shvartzkop 50309f0033 Revert "Lock harfbuzz to 11.2.0 to avoid 11.3.3+ regressions/features."
This reverts commit 481e78a29f.
2025-12-13 02:28:10 +03:00
Alex Shvartzkop a588a63778 Remove hb_ft_font_set_funcs call in outline fonts.
It doesn't appear to do anything useful since we already use the ft vtable,
and calling hb_ft_font_set_funcs breaks x_advance values in harfbuzz 11.3.0+

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22524
2025-12-13 02:27:12 +03:00
Alex Shvartzkop 481e78a29f Lock harfbuzz to 11.2.0 to avoid 11.3.3+ regressions/features.
pos.x_advance is just too small for bold Bahnschrift font when using harfbuzz 11.3.3+

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22524
2025-12-12 22:28:38 +03:00
Alex Shvartzkop 5e4633545b Clear tool manager model to avoid crash when closing PCB editor. 2025-12-12 21:29:15 +03:00
Mark Roszko 447be71b65 Fix new msvc build warnings about enums
(cherry picked from commit 0e46f99fdf)
2025-12-12 21:17:37 +03:00
Mike Williams a54ac23bbb snapping: don't snap to invisible footprint anchors 2025-12-12 07:59:23 -05:00
Mike Williams a017fb265f footprint anchors: only show them for footprints on visible layers 2025-12-12 07:59:23 -05:00
Mike Williams 65e486499e view switcher: default to advance selection
This make ctrl-tab/shift-tab work like other OS and KiCad switcher
paradigms.
2025-12-12 07:59:23 -05:00
Mark Roszko ef2f445b14 Don't EscapeHTML on the netname that is stored internally
(cherry picked from commit 602eeb01e3)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-12-12 12:50:28 +00:00
dsa-t 866d92e1f6 Altium PCB import: don't overwrite m_layermap.
m_layermap contains copper layers from stackup info at this point.
We don't want to clear it, especially that most copper layers don't
appear in the layer mapping dialog.


(cherry picked from commit 744406cda0)

Co-authored-by: Alex Shvartzkop <dudesuchamazing@gmail.com>
2025-12-11 21:45:41 +03:00
Seth Hillbrand 3003c0c509 Clear construction manager with grid helper
Construction manager and snap manager keep raw pointers to board items,
so we need to clear them when switching canvases
2025-12-10 08:31:19 -08:00
Alex Shvartzkop 9b3e14546e Update translations 2025-12-10 10:04:59 +03:00
CloverGit 1a3bded55e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10083 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:28 +01:00
Sárkány Lőrinc bf9d6e2689 Translated using Weblate (Hungarian)
Currently translated at 44.1% (4454 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-10 07:59:28 +01:00
Sárkány Lőrinc 24529ef5df Translated using Weblate (Hungarian)
Currently translated at 43.9% (4441 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-10 07:59:28 +01:00
Marco Ciampa 4bf59e4b0f Translated using Weblate (Italian)
Currently translated at 99.3% (10033 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:28 +01:00
Seth Hillbrand 2c35d43069 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 97.9% (9890 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hant/
2025-12-10 07:59:28 +01:00
Sárkány Lőrinc a3a00a4932 Translated using Weblate (Hungarian)
Currently translated at 43.7% (4415 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-10 07:59:27 +01:00
Sárkány Lőrinc 2fd4406f04 Translated using Weblate (Hungarian)
Currently translated at 43.4% (4386 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-10 07:59:27 +01:00
Temuri Doghonadze d4c262cc40 Translated using Weblate (Georgian)
Currently translated at 32.8% (3318 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-12-10 07:59:27 +01:00
Sárkány Lőrinc 1767edfd87 Translated using Weblate (Hungarian)
Currently translated at 42.7% (4318 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-10 07:59:27 +01:00
CloverGit 704bfa5391 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.9% (10087 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:27 +01:00
Sárkány Lőrinc ed8a699670 Translated using Weblate (Hungarian)
Currently translated at 42.3% (4274 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-10 07:59:27 +01:00
Temuri Doghonadze 49ca0e5452 Translated using Weblate (Georgian)
Currently translated at 32.7% (3307 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-12-10 07:59:27 +01:00
Sárkány Lőrinc 844a1b5eb9 Translated using Weblate (Hungarian)
Currently translated at 41.1% (4154 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-10 07:59:27 +01:00
CloverGit ff6c1852b4 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10084 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:27 +01:00
Temuri Doghonadze 6d6355c67d Translated using Weblate (Georgian)
Currently translated at 32.5% (3285 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-12-10 07:59:26 +01:00
Sárkány Lőrinc 3321da2a5d Translated using Weblate (Hungarian)
Currently translated at 40.3% (4073 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-12-10 07:59:26 +01:00
Marco Ciampa 74963bd16c Translated using Weblate (Italian)
Currently translated at 99.3% (10032 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:26 +01:00
Temuri Doghonadze 03c67a8033 Translated using Weblate (Georgian)
Currently translated at 32.1% (3250 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-12-10 07:59:26 +01:00
Temuri Doghonadze 778d8846d6 Translated using Weblate (Georgian)
Currently translated at 30.9% (3125 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-12-10 07:59:26 +01:00
Marco Ciampa b5a763fe69 Translated using Weblate (Italian)
Currently translated at 99.3% (10030 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:26 +01:00
CloverGit af16d38b46 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10081 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:26 +01:00
Marco Ciampa d089ecbc02 Translated using Weblate (Italian)
Currently translated at 99.2% (10026 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:26 +01:00
Temuri Doghonadze 06b6b51ed8 Translated using Weblate (Georgian)
Currently translated at 29.7% (3002 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-12-10 07:59:26 +01:00
CloverGit cbaeb2235e Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10079 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:25 +01:00
ZbeeGin 833b5fc6e2 Translated using Weblate (Polish)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/pl/
2025-12-10 07:59:25 +01:00
Krzysztof Kawa 22efda6367 Translated using Weblate (Polish)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/pl/
2025-12-10 07:59:24 +01:00
Marco Ciampa 964947bc4f Translated using Weblate (Italian)
Currently translated at 99.2% (10017 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:24 +01:00
Temuri Doghonadze f032186e43 Translated using Weblate (Georgian)
Currently translated at 28.7% (2904 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-12-10 07:59:24 +01:00
Jan Straka 91f6033982 Translated using Weblate (Czech)
Currently translated at 77.9% (7872 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/cs/
2025-12-10 07:59:24 +01:00
CloverGit fa1bb05cfa Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10079 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:24 +01:00
Temuri Doghonadze 9ac570c622 Translated using Weblate (Georgian)
Currently translated at 28.2% (2856 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-12-10 07:59:24 +01:00
CloverGit 1e795bee18 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10079 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:24 +01:00
Marco Ciampa e9a1792d45 Translated using Weblate (Italian)
Currently translated at 99.1% (10013 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:23 +01:00
CloverGit c2593c3547 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10079 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:23 +01:00
2tama3 c59c1701bb Translated using Weblate (Japanese)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-12-10 07:59:23 +01:00
CloverGit 534acc718d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10079 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:23 +01:00
Marco Ciampa 7f6557e76a Translated using Weblate (Italian)
Currently translated at 99.1% (10013 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:23 +01:00
Henrik Kauhanen b6f21ea2ae Translated using Weblate (Swedish)
Currently translated at 99.9% (10091 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-12-10 07:59:23 +01:00
Marco Ciampa e906e5e98c Translated using Weblate (Italian)
Currently translated at 99.0% (10002 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:23 +01:00
CloverGit c5a02c908f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10079 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:22 +01:00
Marco Ciampa 9edf3e4005 Translated using Weblate (Italian)
Currently translated at 99.0% (10001 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:22 +01:00
Pferd O. 55a8a075e6 Translated using Weblate (German)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-12-10 07:59:22 +01:00
김랑기 1f95d9bc1c Translated using Weblate (Korean)
Currently translated at 99.7% (10075 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ko/
2025-12-10 07:59:22 +01:00
Marco Ciampa 97971957ce Translated using Weblate (Italian)
Currently translated at 98.7% (9972 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:22 +01:00
김랑기 662f4c1e89 Translated using Weblate (Korean)
Currently translated at 99.3% (10033 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ko/
2025-12-10 07:59:22 +01:00
Temuri Doghonadze 49a03c7c01 Translated using Weblate (Georgian)
Currently translated at 28.0% (2836 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-12-10 07:59:22 +01:00
김랑기 ed6319fae0 Translated using Weblate (Korean)
Currently translated at 99.1% (10016 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ko/
2025-12-10 07:59:22 +01:00
2tama3 10f5d88b7a Translated using Weblate (Japanese)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-12-10 07:59:21 +01:00
Ivan Chuba 8937681052 Translated using Weblate (Estonian)
Currently translated at 3.5% (357 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/et/
2025-12-10 07:59:21 +01:00
Pferd O. a0030b4dd3 Translated using Weblate (German)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-12-10 07:59:20 +01:00
Vic 1fb6254d62 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 97.9% (9890 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hant/
2025-12-10 07:59:19 +01:00
CloverGit 6f0bafa7a0 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10080 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-12-10 07:59:19 +01:00
Максим Горпиніч c7e7d3aac8 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/uk/
2025-12-10 07:59:19 +01:00
2tama3 312dd06216 Translated using Weblate (Japanese)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-12-10 07:59:19 +01:00
Marco Ciampa 803ce01795 Translated using Weblate (Italian)
Currently translated at 98.7% (9969 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-12-10 07:59:18 +01:00
Pferd O. d9cc8ee071 Translated using Weblate (German)
Currently translated at 99.9% (10096 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-12-10 07:59:18 +01:00
Jeff Young 27df4775d0 Kill any running tools before switching the footprint. 2025-12-09 23:51:48 +00:00
Jeff Young 3071bbd201 Don't short-cicuit Remove() or RemoveAll().
Also, make sure PCB_GRID_HELPER installs itself
as a board listener.  (Otherwise its
OnBoardItemRemoved() handler will never get
called.)

(cherry picked from commit 88e87bab3e)
2025-12-09 18:00:37 +00:00
Jeff Young 6296360047 Clear snap items when their parent footprint are removed from board.
(cherry picked from commit 75deaaa467)
2025-12-09 18:00:37 +00:00
Seth Hillbrand a23c267fb3 Avoid calling grid helper when changing tool
When changing tools, the canvas may reference objects that are invalid,
so avoid using the grid helper here.  We don't need the cursor pos at
this point anyway

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21929
2025-12-08 15:31:39 -08:00
Jeff Young 85f483c36b Fix accidentally broken text mirroring direction.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22479

(cherry picked from commit 39cf28d5fd)
2025-12-08 17:20:10 +00:00
Jeff Young e99964d652 Fix indenting. 2025-12-08 16:38:42 +00:00
Jeff Young a68a69893c Regenerate changes list when checkboxes change.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22467

(cherry picked from commit 51494f3853)
2025-12-08 16:38:42 +00:00
Jeff Young 3f528f89ef Force output of pad offset when other layers of padstack differ.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22464

(cherry picked from commit 8133e53fbf)
2025-12-08 16:38:42 +00:00
Mark Roszko 1a69f21462 Reduce tiny fp errors that can be introduced when updating footprints
Moving by the cursor position (double) and then back to the integer coordinate position sometimes added tiny tiny tiny shifts in the coordinate.


(cherry picked from commit dad49d5dba)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-12-06 20:41:32 +00:00
Mark Roszko 47363766c7 Fix rule areas not accounting for inner layer expansion in drc parity check
Also fix up the pad stack check to account for external layer presence more properly
2025-12-06 14:12:14 -05:00
Mark Roszko 1d694eba5d Allow footprints to have additional layers on their pads in boards instead of flagging constant library mismatches
Board layer count settings increase the number of layers on PTH pads when the board is loaded.
This causes false library mismatch DRCs with little explanation of something that is automatic and logical behavior.
2025-12-06 11:26:14 -05:00
Wayne Stambaugh dbeaeae919 Reset tools before loading new footprint in footprint chooser.
This may not actually fix this issue.  It is probably safer to reset all
tools before changing the footprint view just in case an unexpected event
occurs that causes a tool to attempt to access an object no longer valid
in the view.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21929
2025-12-05 08:12:19 -05:00
Seth Hillbrand 4f97ce15cc Fix broken cherry-pick 2025-12-03 15:43:36 -08:00
Seth Hillbrand d27552a282 Ensure closed polygons for filling
PDF output needs closed polygons to fill objects, so ensure that we
properly close before filling

(cherry picked from commit ae80e30467)
2025-12-03 11:32:11 -08:00
Wayne Stambaugh 0be18638f8 Use correct signature of VIA::Width() to prevent crash.
- Update VIA::GetWidth() to raise an assertion and always return a valid albeit
  most likely incorrect width.

- Fix interactive via placement tool to call the correct VIA::GetWidth() which
  prevents the crash/assertion.  This uses the layer of the shape where the via
  is being placed.

Fixes KICAD-ZY6
2025-12-01 15:35:38 -05:00
Jeff Young a697be4fbf Resolve text variables when resolving netclasses.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22413

(cherry picked from commit 36c603b6f0)
2025-12-01 17:35:49 +00:00
Mark Roszko ac6dcbe9ae Update vcpkg for wx test 2025-12-01 01:16:01 +00:00
Jeff Young d16f784412 Don't leave the dirty flag set after clearing properties.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22428
2025-11-30 14:38:01 +00:00
Jeff Young b12b88fd40 Don't try to open-code a SHAPE_POLY_SET::BooleanSubtract().
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17317

(cherry picked from commit 308134d025)
2025-11-30 14:38:01 +00:00
Bernhard Kirchen bd2152bb3d add DRC exclusion comment to JSON report
closes #22330.

(cherry picked from commit 80e148fb68)
2025-11-30 14:38:01 +00:00
Jeff Young 677750b64e Remove previous hack for dealing with ligatures.
It appears to be no longer needed, and messes some
things up.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22402

(cherry picked from commit 4bfed3f174)
2025-11-30 14:38:01 +00:00
Jeff Young d6ddeff443 Fix initial focus in Label Properties dialog.
(cherry picked from commit 84213dff2a)
2025-11-30 14:38:01 +00:00
Jeff Young 06e1e4c62c Drawing tools must police their own handling of paste.
Doing otherwise disables paste even when
the tool is idle.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22373

(cherry picked from commit b7c561b232)
2025-11-30 14:38:01 +00:00
Alex Shvartzkop aa6fb159b5 Warn about Controlled folder access on Windows
Controlled folder access blocks access to Documents folder which we use.
2025-11-29 19:38:17 +03:00
Mark Roszko 3ed9fbe423 Edit doxygen.yml
(cherry picked from commit bc73ecbddf)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-11-27 00:11:04 +00:00
Alex Shvartzkop 8b93d56c14 Hyperlynx export: swap arc start/end.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22178
2025-11-25 12:48:27 +03:00
Alex Shvartzkop 138f8af8ab Support Autodesk Fusion urn format for Eagle import.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22394
2025-11-25 09:55:30 +03:00
Mark Roszko 00b6f25031 Fix calculator min size and minor dead code nix
(cherry picked from commit e222aaeefd)

82bbecc9 pcb_calculator: remove dead code in PCB_CALCULATOR_FRAME::OnUpdateUi
d1de79b8 fixes https://gitlab.com/kicad/code/kicad/-/issues/22385

Co-authored-by: Jan Dorniak <jaskij@gmail.com>
2025-11-23 17:05:42 +00:00
Mark Roszko fdb333ca8b Add missing include 2025-11-22 18:54:21 +00:00
Mark Roszko 014a4d040c Handle Python multi-phase initialization support in swig-4.4.0
Signed-off-by: Mark Roszko <mark.roszko@gmail.com>


(cherry picked from commit c5a2b86379)

Co-authored-by: Raman Varabets <gitlab-20240601-da2ef10c@cyborgize.sg>
2025-11-22 18:15:30 +00:00
Jon Evans 5818b52a38 API: Ensure new footprints have unique child UUIDs
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21340
2025-11-22 11:28:37 -05:00
Jon Evans ea5ae7cc5d API: Fix serialization of footprint rule overrides; add missing allow_soldermask_bridges attribute
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21674
2025-11-22 09:59:03 -05:00
Jon Evans f230800365 Use active layer when pasting text from clipboard
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22370
2025-11-22 09:25:15 -05:00
Jon Evans 51ba93c680 Fix loading of shape offset and delta for complex padstacks
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21691
2025-11-22 09:21:23 -05:00
Alex Shvartzkop bddc4e5f89 gerbview: significantly improve performance when zip archive has extra ASCII files. 2025-11-22 15:27:24 +03:00
Jon Evans bdd98e801f API: Add schematic pin attributes to pads
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22360
2025-11-20 23:29:43 -05:00
Mark Roszko a7c69264ad Fix vcpkg baseline hash 2025-11-20 21:04:54 -05:00
Mark Roszko 9c16efcb83 Bump vcpkg baseline 2025-11-20 20:53:55 -05:00
Mark Roszko 89155c488f Bump kicad-vcpkg for a wxwidgets fix (aui icon drawing speed) 2025-11-20 20:53:11 -05:00
Jon Evans 949be9a63a API: Preserve linked symbol properties in footprints
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21655
2025-11-20 19:57:27 -05:00
Alex Shvartzkop 0685039e0a EasyEDA/JLCEDA Pro V3: fix pin name/number import. 2025-11-21 02:05:09 +03:00
Alex Shvartzkop 5ab0ab2bdb EasyEDA Pro schematic import: improve text sizing. 2025-11-21 00:50:14 +03:00
Alex Shvartzkop 95f895b4a9 EasyEDA Pro schematic import: change Arial to default font
JLCEDA Pro V3 export to format version V1 specifies Arial
explicitly instead of null for default font,
and system's Arial usually doesn't have the Chinese charset.
2025-11-21 00:49:15 +03:00
Alex Shvartzkop 34a7f64821 EasyEDA Pro: allow picking "Global Net Name" from symbol.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/19734
2025-11-21 00:19:28 +03:00
Alex Shvartzkop 95f1630bce Revert "Ignore visibility and style attrs in instance data."
This reverts commit 17158f21da.
2025-11-20 23:36:57 +03:00
jean-pierre charras 85494592d6 ZONE::GetMsgPanelInfo(): fix info displayed for rule areas
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22352

(cherry picked from commit 284348f032)
2025-11-20 17:28:06 +01:00
jean-pierre charras 4a5c64a036 Fix plot pad issue with solder paste layer when using a percentage for clearance.
For chamfered rectangle pads, when using a percentage to define a clearance for
solder paste shape from copper pad shape with different X and Y sizes, the
plotted solder paste shape was incorrect.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22306

(cherry picked from commit fa0fc59d82)
2025-11-20 14:34:26 +01:00
dsa-t 39e69ffdad Work around a bug in JLCEDA V1 format export where SMD pads specify zero-sized hole.
(cherry picked from commit 3e8a2fb7ea)

Co-authored-by: Alex Shvartzkop <dudesuchamazing@gmail.com>
2025-11-20 14:31:12 +03:00
Jeff Young 48d8c8d0b2 Hand cherry-pick of ea147ae68b. 2025-11-14 18:15:52 +00:00
Jeff Young 06f48b6c88 Refresh library tree when saving an editable copy.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22247

(cherry picked from commit 885bb34f66)
2025-11-13 12:35:18 +00:00
Magnus Lundmark 96868b2737 Add row or column to a table now respects formatting
(cherry picked from commit a6840a1370)
2025-11-10 14:10:44 +00:00
JamesJCode 4e4a2d1fa1 Implement hierarchical component classes
This ensures that hierarchical sheets inside a rule are with a
component class attached pass that component class down the
schematic hierarchy.

(cherry picked from commit 710a239c67)
2025-11-09 20:51:08 +00:00
Wayne Stambaugh 3c4f582352 Fix image rotation direction in schematic editor.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22254

(cherry picked from commit 2e278c10f8)
2025-11-06 16:36:13 -05:00
akhilles 7a513cb61a IPC-2581: Fix SlotCavity to use drill hole dimensions
The addSlotCavity function was using GetEffectiveShape() which returns
the copper pad geometry, not the drill hole geometry. This caused
slotted through-holes to export with incorrect dimensions in the ROUT
layer, resulting in zero annular ring when parsed by IPC-2581 compliant
tools.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22145
2025-11-06 14:04:25 -05:00
dsa-t 29863a3da1 Fix EasyEDA Pro v2.2 compatibility.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22239


(cherry picked from commit be8025b331)

Co-authored-by: Alex Shvartzkop <dudesuchamazing@gmail.com>
2025-11-06 11:15:23 +03:00
Jeff Young f059596736 Fix regression with resolving text variables in symbol fields table.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/19978
2025-11-04 17:52:03 +00:00
Jeff Young 19c0bb27f5 Adding/removing items to/from footprint taints the geometry caches.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22203
2025-11-04 17:41:42 +00:00
Alex Shvartzkop 7852afc219 router: try to resolve track drag collision first before showing "Track violates DRC". 2025-11-04 02:28:07 +03:00
Alex Shvartzkop 32b15a6d8d Support wx 3.2 in Eagle sch parser.
(cherry picked from commit 79a926f533)
2025-11-03 02:10:44 +03:00
Alex Shvartzkop 5eb95e9976 Support reading EAGLE sch files starting with "<eagle" instead of correct xml header.
(cherry picked from commit 7ff43c501e)
2025-11-03 02:10:44 +03:00
Alex Shvartzkop 378b7ef2cb Eagle import: improve rot field parsing. 2025-11-03 02:10:44 +03:00
Alex Shvartzkop 1770ce0557 Update translations 2025-11-02 05:47:46 +03:00
Максим Горпиніч 31ce874136 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (10096 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/uk/
2025-11-02 03:45:45 +01:00
Marco Ciampa c4d3d0e0e2 Translated using Weblate (Italian)
Currently translated at 98.6% (9964 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-11-02 03:45:45 +01:00
CloverGit 050df10ad4 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10081 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-11-02 03:45:45 +01:00
Marco Ciampa 2c8d12f9eb Translated using Weblate (Italian)
Currently translated at 98.6% (9962 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-11-02 03:45:45 +01:00
CloverGit acc70d85c3 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10079 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-11-02 03:45:45 +01:00
Tatu Bogdan 995e313f3a Translated using Weblate (Romanian)
Currently translated at 24.2% (2449 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ro/
2025-11-02 03:45:45 +01:00
2tama3 c5b6ebaa1a Translated using Weblate (Japanese)
Currently translated at 100.0% (10096 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-11-02 03:45:45 +01:00
Pferd O 9ce8200750 Translated using Weblate (German)
Currently translated at 100.0% (10096 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-11-02 03:45:45 +01:00
Eli Hughes 5bc2f6aa2b adding some docuemntation for the http test server as well as a requirements.txt and pyproject.toml for running w/ uv
(cherry picked from commit 8fa6656e39)
2025-11-01 10:24:11 +00:00
Jeff Young db2f1a3040 Don't beep on the event that got us here.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22158

(cherry picked from commit 8c2b5977ec)
2025-10-30 15:35:01 +00:00
Jeff Young 3a77e1377a Resolve text variables in descriptions and keywords.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22146

(cherry picked from commit 5e41d63bd0)
2025-10-30 15:35:01 +00:00
Jeff Young 7a9d9fb5f6 Hand cherry-pick of 82b1bcecca. 2025-10-30 15:35:01 +00:00
Jeff Young d4c25be6c0 Make sure graphic items pass selection filter. 2025-10-30 15:35:01 +00:00
Jeff Young 11d08ae2c8 Make sure graphic segments pass selection filter. 2025-10-30 15:35:01 +00:00
Jeff Young da8be848e1 Multiple bug fixes in handling of inheritance chains.
Lots of code assumed a single inheritance, while in
fact the parent could also be derived.

Also removed a couple of cover types on std:shared_ptr
and std::weak_ptr as it's important to know the API
contract you're dealing with.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22003

(cherry picked from commit 857c408b25)
2025-10-30 15:35:01 +00:00
Jeff Young c3226645c5 Hand cherry-pick parts of f1e4d75118. 2025-10-30 15:35:01 +00:00
Jeff Young 144cdd98ce Replace comment; change format name.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21982

(cherry picked from commit d8b4fde1c8)
2025-10-30 15:35:01 +00:00
Philippe Maire 9aa9a618be Fix position file alignment when the values or footprint contain UTF-8 characters. https://gitlab.com/kicad/code/kicad/-/issues/21982
(cherry picked from commit 1be157d212)
2025-10-30 15:35:01 +00:00
Jeff Young 2cc574ed14 Adjust text offset after SCH_/LIB_ merger.
(It was upside down as it originated
from the flipped coordinate system.)

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21802

(cherry picked from commit 507ec29cc0)
2025-10-30 15:35:01 +00:00
Jeff Young 08267916e8 Give auto-created fields names.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21928

(cherry picked from commit 4c91cba7c8)
2025-10-30 15:35:01 +00:00
Jeff Young 3476553bb2 Cleanup CLI argument specifications.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21950

(cherry picked from commit 9468f304c7)
2025-10-30 15:35:01 +00:00
Jeff Young c7fd6a14d6 Formatting. 2025-10-30 15:35:01 +00:00
Jeff Young 8c1e3704e7 Cherry-pick of 54200d073a. 2025-10-30 15:35:01 +00:00
Jeff Young 9eef6cf857 Be wary of items being pulled out from under PointEditor.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21966

(cherry picked from commit 54200d073a)
2025-10-30 15:35:01 +00:00
Jeff Young 2b662b4ccc Don't abort same-net items in the filter.
We still need to check for hole collisions.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21941

(cherry picked from commit d03b5f44ab)
2025-10-30 15:35:01 +00:00
Jeff Young 8a78d83087 Hand cherry-pick 77d6a1d490 2025-10-30 15:35:01 +00:00
Jeff Young c05fe36a0a Hand cherry-pick hole clearance fixes for #21941. 2025-10-30 15:35:01 +00:00
Jeff Young 2cf7288b1b Hand cherry-pick of b6cc9df1f4. 2025-10-30 15:35:01 +00:00
jean-pierre charras 77686f50af Fix BOARD::ConvertBrdLayerToPolygonalContours() broken for PCB_TABLE
ConvertBrdLayerToPolygonalContours() convert basic graphic items to their
polygonal shapes to allow plotting them in DXF export and vrml export.
For PCB_TABLE, the conversion of PCB_TABLE basic graphic items (textx, segments)
was not made.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21934

(cherry picked from commit 118410eb1b)
2025-10-30 13:57:45 +01:00
Wayne Stambaugh f84f0b913d Begin version 9.0.7 development. 2025-10-30 08:43:20 -04:00
Wayne Stambaugh 8a3464bdf1 Tag stable version 9.0.6. 2025-10-30 08:41:59 -04:00
Alex Shvartzkop 51646e6605 Update translations 2025-10-30 04:51:46 +03:00
Vic e962686afb Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 97.9% (9891 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hant/
2025-10-30 02:50:56 +01:00
2tama3 9211d60d7b Translated using Weblate (Japanese)
Currently translated at 100.0% (10096 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-10-30 02:50:56 +01:00
Marco Ciampa 632c03a874 Translated using Weblate (Italian)
Currently translated at 98.6% (9958 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/it/
2025-10-30 02:50:56 +01:00
Vic 24d2eded07 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 97.9% (9891 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hant/
2025-10-30 02:50:56 +01:00
தமிழ்நேரம் d3a5bf20db Translated using Weblate (Tamil)
Currently translated at 99.9% (10094 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ta/
2025-10-30 02:50:56 +01:00
Pferd O 099e0d1312 Translated using Weblate (German)
Currently translated at 99.9% (10093 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-30 02:50:56 +01:00
Frank Sonnenberg 3c1bc31456 Translated using Weblate (German)
Currently translated at 99.9% (10093 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-30 02:50:56 +01:00
Vic 2fffc9780b Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 97.8% (9874 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hant/
2025-10-30 02:50:56 +01:00
தமிழ்நேரம் 68bfa2001e Translated using Weblate (Tamil)
Currently translated at 99.8% (10078 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ta/
2025-10-30 02:50:56 +01:00
Sárkány Lőrinc ebdf4c7719 Translated using Weblate (Hungarian)
Currently translated at 39.7% (4012 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-10-30 02:50:55 +01:00
Toni Laiho f944b662b6 Translated using Weblate (Finnish)
Currently translated at 97.6% (9854 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/fi/
2025-10-30 02:50:55 +01:00
Frank Sonnenberg 3ac9bace21 Translated using Weblate (German)
Currently translated at 99.9% (10093 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-30 02:50:55 +01:00
Vic 98141d0143 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 97.7% (9871 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hant/
2025-10-30 02:50:55 +01:00
தமிழ்நேரம் d90d86775b Translated using Weblate (Tamil)
Currently translated at 99.7% (10067 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ta/
2025-10-30 02:50:55 +01:00
dsa-t 578d0a5a4a Translated using Weblate (Russian)
Currently translated at 100.0% (10096 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ru/
2025-10-30 02:50:55 +01:00
2tama3 53075ee9f3 Translated using Weblate (Japanese)
Currently translated at 100.0% (10096 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-10-30 02:50:55 +01:00
Frank Sonnenberg 7f19d051ed Translated using Weblate (German)
Currently translated at 99.9% (10094 of 10096 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-30 02:50:55 +01:00
Seth Hillbrand 364cf0808f Ensure snaps override grid points 2025-10-29 15:22:52 -07:00
Seth Hillbrand d3cce1e35c Remove H/V/45 limits in router completely
Lots of complaints, little benefit

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22147

(cherry picked from commit ab0e0abe67)
2025-10-28 17:00:55 -07:00
jean-pierre charras 1b20a932ad Fix Unroute Selected when footprint is select and filter selection pad OFF
Fixes https://gitlab.com/kicad/code/kicad/-/issues/22138

(cherry picked from commit 8ba749bf49)
2025-10-28 18:40:01 +01:00
Jeff Young 3b0dac9491 Fix typo. 2025-10-27 15:35:39 +00:00
Wayne Stambaugh 4433da15b1 Tag stable version 9.0.6 release candidate 2. 2025-10-22 18:40:21 -04:00
Alex Shvartzkop e4af447855 Update translations 2025-10-23 00:59:39 +03:00
தமிழ்நேரம் ecd4326533 Translated using Weblate (Tamil)
Currently translated at 99.5% (10050 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ta/
2025-10-23 00:57:45 +03:00
Sárkány Lőrinc 73854bc9f1 Translated using Weblate (Hungarian)
Currently translated at 39.7% (4009 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-10-23 00:57:30 +03:00
CloverGit 544c035298 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10082 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-10-23 00:57:18 +03:00
aris-kimi c8da489b1f Translated using Weblate (Greek)
Currently translated at 85.6% (8649 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/el/
2025-10-23 00:57:18 +03:00
2tama3 da6f97b24f Translated using Weblate (Japanese)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-10-23 00:57:08 +03:00
Tokita, Hiroshi 464d248b8c Translated using Weblate (Japanese)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-10-23 00:57:08 +03:00
CloverGit b790b46c76 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.8% (10081 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-10-23 00:56:54 +03:00
Frank Sonnenberg b4a5422e54 Translated using Weblate (German)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-23 00:56:43 +03:00
Mark Hämmerling 565d54a184 Translated using Weblate (German)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-23 00:56:43 +03:00
Pferd O ebcf96dcd6 Translated using Weblate (German)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-23 00:56:43 +03:00
Pferd O e067a8ddc8 Translated using Weblate (German)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-23 00:56:43 +03:00
Temuri Doghonadze 4d8feb94bd Translated using Weblate (Georgian)
Currently translated at 27.6% (2790 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-10-23 00:56:27 +03:00
Seth Hillbrand 2374e5e542 Propagate lib_fields changes
Partial cherry-pick of 702f774a1f and
fef84a2c6a
2025-10-22 13:10:04 -07:00
Seth Hillbrand a3e4a001bb Fix HV45 toggle during move
Action handled externally, so trigger internal updates on flag

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22025
2025-10-21 16:44:12 -07:00
Seth Hillbrand edc25f8ba0 Fix axis locking when keypresses are specific
If you immediately pressed left/right it would not unlock unless there
was a mouse movement between
2025-10-21 16:25:49 -07:00
Seth Hillbrand 10a03972d4 Re-enable axis locking on cursor key
This is an accidental feature previously but now make it explicit.
Pressing left or right keys will lock the movement to the horizontal
axis until you press the opposite key.  Same for up/down

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21981
2025-10-21 15:30:26 -07:00
Wayne Stambaugh 5a3c210b7c Revert "Tag stable version 9.0.6 release candidate 2."
This reverts commit 239eb5a1ff.
2025-10-21 16:48:53 -04:00
Wayne Stambaugh 239eb5a1ff Tag stable version 9.0.6 release candidate 2. 2025-10-21 16:39:16 -04:00
Seth Hillbrand c1a1bbc96b Strongly prefer snap points over snap lines
When moving toward an intersection of snap lines that is also a snap
point, when the grid is off, the snap will always be closer to one snap
line or the other before the snap point.  This is problematic for
snapping to a center point, e.g.

Instead, if you are within the snap range of a snap point, that should
be your preference.  Zooming in will allow snapping to the snap physical
point on a line and avoiding the snap point snapping

Fixes https://gitlab.com/kicad/code/kicad/-/issues/22045
2025-10-21 12:07:27 -07:00
Seth Hillbrand c16076a5c3 Remove Local Power from v9 2025-10-21 12:04:57 -07:00
Seth Hillbrand 77ab6c29bf Ensure ERC Exclusions are maintained
After we load/resolve the exclusions, we want to ensure that the
resolved ones are re-recorded into the project file so that it always
remains consistent with the state of the system.  This way, if pcbnew
closes first and re-saves the project, our exclusions are not lost until
the schematic closes

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21410

(cherry picked from commit 5442e5050e)
2025-10-21 06:27:40 -07:00
Seth Hillbrand 9366902052 Clear the keyboard movement flag on mouse move
We detect mouse movement by checking if the screen position is not the
keyboard position and if not, we clear the
m_lastKeyboardCursorPositionValid that is used for detemining keyboard
movement in snaps

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21981

(cherry picked from commit 120c788ef0)
2025-10-20 16:34:11 -07:00
Jeff Young 86b687bdaf Minimal cherry-pick of ba73ce78e6. 2025-10-20 14:08:30 +01:00
Wayne Stambaugh 1da4895619 Sync shared symbol instance field values in symbol fields table dialog.
Change data store key from wxString to KIID_PATH to make it easier to look
up shared symbol instances by KIID.
2025-10-16 17:56:18 -04:00
Seth Hillbrand fbf9a45a00 Fix MSVC compile 2025-10-15 17:27:45 -07:00
Seth Hillbrand c6c2d6468d Keep movement snaps aligned with start
Prevents jumping elements when we start to move

(cherry picked from commit d4265ebff8)
2025-10-15 16:51:40 -07:00
Seth Hillbrand b349140112 Snap construction lines to grid if enabled
Nearest grid line intersection is a snap point on construction lines

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21984

(cherry picked from commit ce305990e8)
2025-10-15 16:49:00 -07:00
Seth Hillbrand 5dafadb12c Prioritize anchor snapping over snapline/grid
We have a number of potential snap points and we would prefer to snap to
identified snap points on objects in the view over ethereal points
created by intersections

(cherry picked from commit ce49e9d69c)
2025-10-15 15:25:55 -07:00
Seth Hillbrand da1f71684c Use full path to match symbols in table/BOM
In the symbol fields table, we can't rely on the UUID being unique
across sheets.  So, we need to keep the full path as our key to unique
symbols

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21998

N.B. This is similar to but not a direct cherry pick from 8cf33049be
since the branches have diverged
2025-10-15 15:14:50 -07:00
Seth Hillbrand 563a2d20b7 SCH_ITEMs will not always have a schematic pointer
Especially if we are updating a symbol, the pointer is removed, so we
need to be able to handle this case

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21995
2025-10-15 10:01:39 -07:00
Seth Hillbrand f31450018d Add missing acknowlegement for ur-3dmodels library
(cherry picked from commit fcc25071b7)
2025-10-15 06:57:00 -07:00
Seth Hillbrand c329ba2b4c Add link to original GitHub 3D repo
(cherry picked from commit 61f33a2fef)
2025-10-15 06:57:00 -07:00
Seth Hillbrand fe42b1fd6b Fix link to Maui's GitHub
(cherry picked from commit 9067338e37)
2025-10-15 06:57:00 -07:00
Jon Evans 66628a3501 API: Do not attempt to unpack invalid layers
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21743
2025-10-14 17:55:30 -04:00
Tomasz Wlostowski e21ebbff76 router: improved multidrag segment side/corner determination
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21972
2025-10-14 19:16:42 +03:00
Seth Hillbrand 7df0a80eed Don't write invalid countour data in ODB++
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21974

(cherry picked from commit df76a54db1)
2025-10-13 16:20:11 -07:00
Jeff Young 790dee114b Use the fully-qualified name in the library too.
(Otherwise when we save another symbol with
a different fully-qualified name, but same
elem.text, we'll delete the first instance
which we still have cached.)

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21947
2025-10-12 20:30:33 +01:00
Seth Hillbrand 3f17abba60 Properly handle choices mapped
If the choice is an integer, we need to be able to handle it directly
because we can't get the wxAny to a wxString if the underlying type
doesn't map

(cherry picked from commit 42a76dd4bd)
2025-10-11 22:55:46 -07:00
Wayne Stambaugh dbca140d17 Tag stable version 9.0.6 release candidate 1. 2025-10-11 13:02:53 -04:00
Alex Shvartzkop d563588b28 Update translations 2025-10-11 04:08:44 +03:00
2tama3 4503abdf80 Translated using Weblate (Japanese)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-10-11 03:08:00 +02:00
Sárkány Lőrinc d670be0007 Translated using Weblate (Hungarian)
Currently translated at 39.6% (4007 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-10-11 03:08:00 +02:00
Pferd O f55873fc3d Translated using Weblate (German)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-11 03:08:00 +02:00
Temuri Doghonadze 330437ee8d Translated using Weblate (Georgian)
Currently translated at 26.4% (2669 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-10-11 03:08:00 +02:00
Sárkány Lőrinc 61648be38a Translated using Weblate (Hungarian)
Currently translated at 39.5% (3998 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-10-11 03:08:00 +02:00
Frank Sonnenberg 58584cb227 Translated using Weblate (German)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-11 03:08:00 +02:00
Pferd O 4cab605fb6 Translated using Weblate (German)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-11 03:07:59 +02:00
Henrik Kauhanen 57f6d1c015 Translated using Weblate (Swedish)
Currently translated at 99.7% (10070 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-10-11 03:07:59 +02:00
Seth Hillbrand 57df0435bf Fix double-delete crash
9.0 uses boost to auto-manage the lifetime
2025-10-10 17:23:53 -07:00
Seth Hillbrand 46312674c6 Re-work of 5514396c for v9
All links are processed in the same order

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21913
2025-10-10 17:12:00 -07:00
Quentin Freimanis 32781c3992 altium pcbs: import pad to die length
(cherry picked from commit ad07c85cea)
2025-10-10 15:35:59 -07:00
Seth Hillbrand 48b3408f9a Fix alignment QA
We actually offset by 25, so the check was wrong
2025-10-10 15:19:24 -07:00
Seth Hillbrand e892783109 Move HV45 to suggestions when moving
Snap lines shown when snapped
2025-10-10 14:44:00 -07:00
Seth Hillbrand 5865431759 Refactor grid_helper to allow testing
Make view and tool manager optional so that we can implement QA on the
actual snapping

(cherry picked from commit 29eee9f126)
2025-10-10 13:39:02 -07:00
Seth Hillbrand d75d0ef686 Allow multi-row deleting in 3d models
Removes all selected rows when hitting the trash can

Fixes https://gitlab.com/kicad/code/kicad/issues/21894

(cherry picked from commit 7ebf5f084b)
2025-10-10 10:01:15 -07:00
Seth Hillbrand baf4843a45 Avoid minor overlaps
Some geometry creates 1-2nm overlaps.  These are not actually overlaps
because our collinear test can't correctly determine their
directionality, so we limit the overlap to at least 25 units (arbitrary)
to skip these chunks

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21946

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21930

(cherry picked from commit 063430e488)
2025-10-09 17:57:44 -07:00
Alex Shvartzkop 57309d4a62 Update translations 2025-10-08 13:56:58 +03:00
ZbeeGin a9ad99f513 Translated using Weblate (Polish)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/pl/
2025-10-08 12:56:21 +02:00
Temuri Doghonadze 5a459ce982 Translated using Weblate (Georgian)
Currently translated at 25.4% (2572 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-10-08 12:56:21 +02:00
2tama3 32626dfa1d Translated using Weblate (Japanese)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-10-08 12:56:21 +02:00
Temuri Doghonadze 3406f20a5c Translated using Weblate (Georgian)
Currently translated at 25.4% (2571 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-10-08 12:56:20 +02:00
2tama3 2fedbaac2e Translated using Weblate (Japanese)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-10-08 12:56:20 +02:00
Pferd O b3f7e2e827 Translated using Weblate (German)
Currently translated at 99.8% (10083 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-08 12:56:20 +02:00
Frank Sonnenberg 6430bd6c61 Translated using Weblate (German)
Currently translated at 99.8% (10083 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-08 12:56:20 +02:00
Michal Kundrát cb51d324b7 Translated using Weblate (Czech)
Currently translated at 77.9% (7871 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/cs/
2025-10-08 12:56:20 +02:00
Максим Горпиніч 1eb9accb1e Translated using Weblate (Ukrainian)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/uk/
2025-10-08 12:56:20 +02:00
dsa-t fb8716f16a Translated using Weblate (Russian)
Currently translated at 100.0% (10097 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ru/
2025-10-08 12:56:19 +02:00
Temuri Doghonadze 1bdeebf13d Translated using Weblate (Georgian)
Currently translated at 19.2% (1943 of 10097 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-10-08 12:56:19 +02:00
Jeff Young 3688a9ca61 Support translation of property grid enums.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21859

Fixes https://gitlab.com/kicad/code/kicad/-/issues/13636

(cherry picked from commit 44f932e9ec)
2025-10-07 13:49:14 +01:00
Jeff Young 94370cc6d8 Support translation in tool context menus that are long-lived.
(The specialized ones are OK as they're created
for each use.)

Also, enum maps must be untranslated.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21859

(cherry picked from commit 2fe7219474)
2025-10-07 13:46:54 +01:00
Jeff Young 186839b245 Nullptr safety.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21840

(cherry picked from commit e00bb21afd)
2025-10-07 13:44:26 +01:00
Jeff Young c70653c9dc Nullptr safety.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21841

(cherry picked from commit 0edae828df)
2025-10-07 13:38:25 +01:00
Jeff Young ed59993fc3 Fix build error. 2025-10-07 13:32:09 +01:00
Jeff Young fec37a0f79 Make sure exclusion hotkey works when dialog has focus.
(Potentially only required on MSW.  Not required
on MacOS, unknown on GTK.)

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21761

(cherry picked from commit 7003c0639e)
2025-10-07 13:28:41 +01:00
Jeff Young 7a4ab8971c Auto-convert numeric values in fields when referencing them in expressions.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21723

(cherry picked from commit 2c102a62e0)
2025-10-07 13:24:21 +01:00
Jeff Young 76cff2e7aa Fix build error. 2025-10-07 13:23:14 +01:00
Jeff Young e95aab5df6 Implement netclass compare for sorting.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21345

(cherry picked from commit 3bb1aafdf3)
2025-10-07 12:41:33 +01:00
Seth Hillbrand 0b1fee9f7f Properly account for keyboard movement
We need to snap the position to the grid at the start of movement with
the keyboard because it will snap to the movement point of the item when
we are moving, so the difference between mouse position and grid
position will end up being some fractional value that appears random

Fixes https://gitlab.com/kicad/code/kicad/issues/21682

(cherry picked from commit 4a090ca353)
2025-10-05 21:35:53 -07:00
Seth Hillbrand 8a5c51d37f Properly name Altium subsheets
Instead of using Altium extensions, we need to use KiCad extensions
otherwise, we'll never load them

Fixes https://gitlab.com/kicad/code/kicad/issues/21173
2025-10-05 14:03:15 -07:00
Seth Hillbrand d288dce1d0 Fix Altium subsheet names 2025-10-05 13:57:57 -07:00
Seth Hillbrand 89b92fe3f5 One follow-on to fix additional windows paths
We need to set the format earlier and handle internal filenames

Fixes https://gitlab.com/kicad/code/kicad/issues/20161
2025-10-05 13:53:57 -07:00
Seth Hillbrand cb7385bf0c Update Altium subfolder import
Altium projects save relative sub folder paths in the windows path
format.  To import these correctly, we need to turn off the escape
character handling in wx's config file processing otherwise
SUBFOLDER\PROJECT.SchDoc ends up looking like SUBFOLDERROJECT.SchDoc

Fixes https://gitlab.com/kicad/code/kicad/issues/20161

(cherry picked from commit 4ae76d56c6)
2025-10-05 13:29:29 -07:00
Seth Hillbrand ec6af273bb One more fix for compiling 2025-10-05 06:58:59 -07:00
Seth Hillbrand 0dd4d0e46c Fix cherry-pick error 2025-10-05 06:57:43 -07:00
Seth Hillbrand 2d0c5dc8bd Only constrain points based on settings
There was a false fall-through that caught all points for polygons.
Now, constraint is applied only based on the user keys and settings

Fixes https://gitlab.com/kicad/code/kicad/issues/21897
2025-10-05 06:53:41 -07:00
Alex Shvartzkop 95418742e9 Fix build error. 2025-10-05 16:09:59 +03:00
Seth Hillbrand 53d0d60f33 Force clearing rtree when rebuilding
Avoid leaving stale triangle references

Fixes https://gitlab.com/kicad/code/kicad/issues/21896

(cherry picked from commit b4f396bb2d)
2025-10-05 16:09:59 +03:00
Alex Shvartzkop bf1dbde3c3 Update translations 2025-10-05 16:04:44 +03:00
Temuri Doghonadze 2b1b1b4fcb Translated using Weblate (Georgian)
Currently translated at 17.7% (1786 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-10-05 15:03:47 +02:00
Sárkány Lőrinc a1066bac65 Translated using Weblate (Hungarian)
Currently translated at 39.4% (3972 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-10-05 15:03:47 +02:00
Temuri Doghonadze a30498a572 Translated using Weblate (Georgian)
Currently translated at 15.0% (1520 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ka/
2025-10-05 15:03:47 +02:00
YÜKSEL AÇIKGÖZ 5403990121 Translated using Weblate (Turkish)
Currently translated at 99.4% (10029 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/tr/
2025-10-05 15:03:47 +02:00
2tama3 2deacd59ef Translated using Weblate (Japanese)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-10-05 15:03:46 +02:00
William Lin 7d67775f45 Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 97.9% (9870 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hant/
2025-10-05 15:03:46 +02:00
Henrik Kauhanen c5ef10cf2c Translated using Weblate (Swedish)
Currently translated at 99.8% (10062 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-10-05 15:03:46 +02:00
Frank Sonnenberg 04d0719269 Translated using Weblate (German)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-10-05 15:03:46 +02:00
Seth Hillbrand f143ce563f Protect polygon build
If we don't have corners, then we cannot add any points or lines

(cherry picked from commit f33fd675d2)
2025-10-05 05:58:14 -07:00
Seth Hillbrand 5792a02825 Adjust the project name when importing
Ensures that the proper project is referenced after saving imported
project

Fixes https://gitlab.com/kicad/code/kicad/issues/13986

(cherry picked from commit d0f1920ab6)
2025-10-05 04:58:46 -07:00
Seth Hillbrand 0dc0061d30 When using git, show all files
Git tracks the status of files in the repository, so we shouldn't hide
the non-root schematics

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21583

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21583

(cherry picked from commit d5e03741b7)
2025-10-05 04:54:13 -07:00
Seth Hillbrand 2116e272b5 Maintain units even when opening standalone
The unit data is maintained in the instances so we need a temporary
instance setting if we do not have the parent sheet

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19361

(cherry picked from commit 39ed3c538f)
2025-10-05 04:53:37 -07:00
Seth Hillbrand 25c14ae7cb Ensure new symbols obey the observed sheet number
Internal numerology will not make sense when annotating, so use the
observed sheet number and let the algo ensure that numbers are not
duplicated

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21637

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19138

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16632

(cherry picked from commit 4fcc2ac7e2)
2025-10-05 04:53:16 -07:00
Seth Hillbrand 3a8fc4dd82 Fully separate command and parameters
Ensures proper execution on all platforms

Fixes https://gitlab.com/kicad/code/kicad/issues/14261

(cherry picked from commit 25e9464d2c)
2025-10-05 04:51:17 -07:00
Seth Hillbrand 5558dce259 Handle custom fields from netlist
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21648

(cherry picked from commit 2677cae840)
2025-10-05 04:50:53 -07:00
Seth Hillbrand 8fe891a475 Prevent H/V locking when dragging
This avoids the track position locking into arbitrary 90° points.

Fixes https://gitlab.com/kicad/code/kicad/issues/21892

(cherry picked from commit a5090c908d)
2025-10-05 04:50:36 -07:00
Seth Hillbrand 501b63028b Prevent crash in changing units
SCH_ITEM unit is set as a wxString

Fixes https://gitlab.com/kicad/code/kicad/issues/21891

(cherry picked from commit 5b0db05ad2)
2025-10-05 04:50:36 -07:00
Seth Hillbrand b7d7403e6f Dedupe ODB++ symbol names
If we have duplicate symbol names (can happen from plugins), suffix a
number

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21803

(cherry picked from commit 8cfac03444)
2025-10-05 04:50:36 -07:00
Seth Hillbrand c0648c4728 We need to clamp the index to max - 1
What did we think this was?  Pascal?

Fixes https://gitlab.com/kicad/code/kicad/issues/21750

(cherry picked from commit 9c0727f28e)
2025-10-05 04:50:36 -07:00
Seth Hillbrand a33003cf62 Clean up third axis
Ensure that there are better displays and detects potential power
signals

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21645

(cherry picked from commit c00e818688)
2025-10-05 04:33:02 -07:00
Seth Hillbrand 1d577cf917 Lazy load git credentials when needed
Prevents querying SecretStore on boot

Fixes https://gitlab.com/kicad/code/kicad/issues/20176

(cherry picked from commit 4ed56d87a4)
2025-10-05 04:32:21 -07:00
Seth Hillbrand d189c6ddbf Enforce spice-valid netnames when parsing
Avoids prematurely trimming netnames containing numbers

Fixes https://gitlab.com/kicad/code/kicad/issues/18598

(cherry picked from commit d6d476e39e)
2025-10-05 04:31:10 -07:00
Seth Hillbrand f781ec82c9 Avoid OtherSideView in 2581B
This was introduced in 2581C, so if we are exporting 2581B, emit the
silk elements as board-level instead of tied to a footprint

Fixes https://gitlab.com/kicad/code/kicad/issues/16286

(cherry picked from commit 1dceb5825d)
2025-10-05 04:15:25 -07:00
Seth Hillbrand 3a33a5b506 Ensure table directories are created
Use static routines to create needed directories before copying files

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18937

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18938

(cherry picked from commit 3eeb2a1ad7)
2025-10-05 04:12:22 -07:00
Seth Hillbrand 4436d93446 When copying global tables, ensure writable
Copying read-only files into the user directory, the files will need to
be read/write in order to work correctly

Fixes https://gitlab.com/kicad/code/kicad/issues/21899

(cherry picked from commit ab7c30a2a1)
2025-10-05 04:10:59 -07:00
JamesJCode 238612d2c2 Use hasExactNetclass() function for all implicit net class DRC rules
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21819

(cherry picked from commit 7c8dd9bf92)
2025-10-04 10:42:00 +01:00
Seth Hillbrand f787c01b47 Clean up lib table cherry-pick and hide
For now, we place this behind the advanced config flag for v9 testing
2025-10-03 17:24:26 -07:00
Seth Hillbrand f8e60b11c9 Fix lib_fields column attributes
Need to properly display footprint selector and datasheet globe

(cherry picked from commit 05d04e665a)
2025-10-03 16:07:22 -07:00
Seth Hillbrand 0f07c4ef78 Prompt for unsaved changes in the lib fields table editor
(cherry picked from commit 344fab5741)
2025-10-03 16:07:22 -07:00
John Beard 6fcfcd28ca Symbol editor: allow to inject the symbol list into DIALOG_LIB_FIELDS
This will permit editing fields for subsets (e.g. only symbols in
a certain inheritance hierarchy)

(cherry picked from commit 9b14434fc3)
2025-10-03 16:06:08 -07:00
Seth Hillbrand 1773eb2b1c ADDED: Library Table Editor
Edits all symbols in a library at once.  Supports copy/paste, multiple
field assignment and selective coloration based on existing data

Fixes https://gitlab.com/kicad/code/kicad/-/issues/11506

(cherry picked from commit 9cba910d53)
2025-10-03 16:05:52 -07:00
Seth Hillbrand 45bdde41b3 JP's patch to fix crash in routing empty board
(cherry picked from commit 8592b2ee70)
2025-10-03 08:46:36 -07:00
Seth Hillbrand 292faaa48d Protect against invalid line access
When placing, we may have failed to generate a tail, in which case, we
will have no line to split, so just return

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21883
2025-10-03 08:42:56 -07:00
Wayne Stambaugh 44c473c1b3 Only use front/back layer notation "F&B" for zone definitions.
This prevents false positive DRC footprint parity errors caused by commit
088e0e80a1.

(cherry picked from commit 8b525671b1)
2025-10-01 16:01:11 -04:00
Wayne Stambaugh 85474345d6 Begin version 9.0.6 development. 2025-10-01 15:09:57 -04:00
Wayne Stambaugh fda292bd08 Tag stable version 9.0.5. 2025-10-01 15:09:57 -04:00
Alex Shvartzkop c666bf8626 STEP export: paint board body in soldermask color if soldermask export is off
Was broken in 54e9a97b26

Fixes (part of) https://gitlab.com/kicad/code/kicad/-/issues/21865
2025-10-01 21:56:34 +03:00
Alex Shvartzkop 96f20d102b Update translations 2025-09-30 15:10:36 +03:00
Henrik Kauhanen f57cdb52dd Translated using Weblate (Swedish)
Currently translated at 99.8% (10061 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-09-30 14:06:53 +02:00
Frank Sonnenberg a5d2294ec3 Translated using Weblate (German)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-30 14:06:53 +02:00
Frank Sonnenberg 72fdb41b73 Translated using Weblate (German)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-30 14:06:53 +02:00
Pferd O 2ca04123d4 Translated using Weblate (German)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-30 14:06:53 +02:00
2tama3 07a4710363 Translated using Weblate (Japanese)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-09-30 14:06:52 +02:00
Sárkány Lőrinc c01e37304f Translated using Weblate (Hungarian)
Currently translated at 39.2% (3960 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-30 14:06:52 +02:00
Stefan Bjornelund the Gnome 52b57b1145 Translated using Weblate (Swedish)
Currently translated at 99.8% (10060 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-09-30 14:06:52 +02:00
2tama3 7b4e444f6c Translated using Weblate (Japanese)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-09-30 14:06:52 +02:00
Sárkány Lőrinc a9f4f85746 Translated using Weblate (Hungarian)
Currently translated at 39.2% (3955 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-30 14:06:52 +02:00
Pferd O bc7ece44eb Translated using Weblate (German)
Currently translated at 99.9% (10070 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-30 14:06:52 +02:00
Sárkány Lőrinc 51cc22a4f2 Translated using Weblate (Hungarian)
Currently translated at 39.1% (3951 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-30 14:06:52 +02:00
Frank Sonnenberg 38f2541a3f Translated using Weblate (German)
Currently translated at 99.9% (10070 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-30 14:06:52 +02:00
Ivan Chuba a05e3de852 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/uk/
2025-09-30 14:06:52 +02:00
co8 j 908e7205e7 Translated using Weblate (Japanese)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-09-30 14:06:52 +02:00
Sárkány Lőrinc a80e410683 Translated using Weblate (Hungarian)
Currently translated at 39.1% (3947 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-30 14:06:52 +02:00
Frank Sonnenberg fa234e4b58 Translated using Weblate (German)
Currently translated at 99.9% (10070 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-30 14:06:52 +02:00
Pferd O fb82e722e1 Translated using Weblate (German)
Currently translated at 99.9% (10070 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-30 14:06:52 +02:00
Максим Горпиніч b45f9e7392 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/uk/
2025-09-30 14:06:52 +02:00
dsa-t d496b281ef Translated using Weblate (Russian)
Currently translated at 100.0% (10080 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ru/
2025-09-30 14:06:51 +02:00
Sárkány Lőrinc 2a46ff370a Translated using Weblate (Hungarian)
Currently translated at 39.1% (3942 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-30 14:06:51 +02:00
Pferd O 44d0b27544 Translated using Weblate (German)
Currently translated at 99.8% (10064 of 10080 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-30 14:06:51 +02:00
Jeff Young 7d76868c5c Fix latent bug in UpdatePins().
(It was failing to update the unit and bodystyle.)

(cherry picked from commit 3f1999795c)
2025-09-29 17:30:49 +01:00
Jeff Young e4d9d1829f Honour alternate pin definitions.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21618

(cherry picked from commit 19133bc6bd)
2025-09-27 13:36:42 +01:00
Jeff Young e585948861 Formatting.
(cherry picked from commit d140261ab1)
2025-09-27 13:15:02 +01:00
Jeff Young e31b177335 Static cast safety.
(cherry picked from commit 48c9145177)
2025-09-27 13:09:29 +01:00
jean-pierre charras 4624d57bc2 FRAME_FOOTPRINT_CHOOSER and FRAME_FOOTPRINT_VIEWER: fix incorrect save settings
They were saved in cvpcb.json instead of pcbnew.json, and especially for
FRAME_FOOTPRINT_CHOOSER, some settings were incorrectly retrieved because
not actually updated.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21818

(cherry picked from commit 8f8edf8d69)
2025-09-26 12:40:21 +02:00
jean-pierre charras 4f2d1ec5a1 French translation update 2025-09-24 08:36:57 +02:00
Alex Shvartzkop 5bcb3edae1 Update translations 2025-09-23 13:55:59 +03:00
Sárkány Lőrinc 30fbfd53c1 Translated using Weblate (Hungarian)
Currently translated at 39.0% (3931 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-23 12:53:01 +02:00
Sárkány Lőrinc dc979be459 Translated using Weblate (Hungarian)
Currently translated at 36.5% (3679 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-23 12:53:01 +02:00
Frank Sonnenberg 450c4517b5 Translated using Weblate (German)
Currently translated at 100.0% (10069 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-23 12:53:01 +02:00
Sárkány Lőrinc 47cd4d6b7a Translated using Weblate (Hungarian)
Currently translated at 36.2% (3648 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-23 12:53:01 +02:00
Pferd O 8842c575c3 Translated using Weblate (German)
Currently translated at 100.0% (10069 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-23 12:53:01 +02:00
CloverGit 858c23f731 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.9% (10063 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-09-23 12:53:01 +02:00
Toni Laiho 1d879d51c5 Translated using Weblate (Finnish)
Currently translated at 97.7% (9842 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/fi/
2025-09-23 12:53:00 +02:00
Pferd O 6e0df489eb Translated using Weblate (German)
Currently translated at 99.9% (10060 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-23 12:53:00 +02:00
Henrik Kauhanen a9be5c5759 Translated using Weblate (Swedish)
Currently translated at 99.8% (10057 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-09-23 12:53:00 +02:00
Stefan De Raedemaeker 258e2fd46f Translated using Weblate (Dutch)
Currently translated at 90.6% (9127 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/nl/
2025-09-23 12:53:00 +02:00
Pferd O f5852f0869 Translated using Weblate (German)
Currently translated at 99.9% (10059 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-23 12:53:00 +02:00
Henrik Kauhanen 1d0adbc5d6 Translated using Weblate (Swedish)
Currently translated at 99.8% (10056 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-09-23 12:53:00 +02:00
Pferd O 34834fd963 Translated using Weblate (German)
Currently translated at 99.8% (10058 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-23 12:53:00 +02:00
Frank Sonnenberg 2f095aeafb Translated using Weblate (German)
Currently translated at 99.8% (10058 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-23 12:53:00 +02:00
CloverGit 47bb72179f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.9% (10063 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-09-23 12:53:00 +02:00
Pferd O 9f7af4a3a7 Translated using Weblate (German)
Currently translated at 99.9% (10060 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-23 12:53:00 +02:00
Frank Sonnenberg dda127ceec Translated using Weblate (German)
Currently translated at 99.9% (10060 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-23 12:53:00 +02:00
Максим Горпиніч 68e6e0a742 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (10069 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/uk/
2025-09-23 12:53:00 +02:00
2tama3 a844ba713a Translated using Weblate (Japanese)
Currently translated at 100.0% (10069 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-09-23 12:53:00 +02:00
Frank Sonnenberg 5d75bd0f0a Translated using Weblate (German)
Currently translated at 99.9% (10060 of 10069 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-23 12:53:00 +02:00
jean-pierre charras c492565ee8 DIALOG_LIB_SYMBOL_PROPERTIES: fix incorrect handling of vertical pos. of fields
The Y pos was negated twice when saving the field position.
Note also this is a fast fix. A better fix should be removing these Y pos sign
change in dialog because they are now not needed, but it will wait 9.0.6.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21781
2025-09-21 16:43:20 +02:00
Wayne Stambaugh 879d2bef4b Tag stable version 9.0.5 release candidate 1. 2025-09-20 15:52:28 -04:00
Olliver Schinagl 05376a39ac export_vrml: Skip missing 3D models with warning
(cherry picked from commit 98d77db5ae)
2025-09-20 11:43:55 -04:00
oskarwires 9c01c2aeb8 Fix pin length change and push
(cherry picked from commit abba11031a)
2025-09-20 11:36:25 -04:00
Alex Shvartzkop 72db7bfedc Fix some warnings. 2025-09-19 17:07:47 +03:00
Alex Shvartzkop 95cfe2cc2e STEP export: don't return non-zero error code on non-fatal errors. 2025-09-19 17:06:38 +03:00
Mark Roszko c6f5daf87f Make ERC/DRC jobs default to fail on violation count
(cherry picked from commit 94856f1ffa)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-09-19 12:01:51 +00:00
Seth Hillbrand b1711d692a Do not hang onto previous elements
When using multi-label input or repeat commands, the previous element
should be deselected so that we can properly transform the current
element

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21765

(cherry picked from commit 5ed46b823b)
2025-09-18 12:28:55 -07:00
Seth Hillbrand d538182f1f Fix Windows Builds 2025-09-18 11:15:52 -07:00
Wayne Stambaugh b4b87b5c38 Prevent crash dereferencing null pointer when creating schematic table. 2025-09-18 14:05:05 -04:00
Seth Hillbrand eed95e612d Skip exterior segments when splitting
We need to avoid fracture points when choosing how to split exterior
segments

(cherry picked from commit 50274352b1)
2025-09-18 10:30:43 -07:00
Seth Hillbrand 68d3c7f5c2 Force type in wxString 2025-09-17 21:05:39 -07:00
Seth Hillbrand 848d5484d8 Fix mocks 2025-09-17 13:42:22 -07:00
Alexander Boehm d3b84f219c generate rule areas dialog: vertical scroll bars
With many entries the dialog could not be resized by dragging
nor were scroll bars displayed (at least under Linux).

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20195

(cherry picked from commit 4111140f93)
2025-09-17 11:38:04 -07:00
Seth Hillbrand 58ccf62d2f Unify sheet name validators and apply to properties
Properties panel and properties dialog now share a validator with shared
strings

Fixes https://gitlab.com/kicad/code/kicad/issues/21689

(cherry picked from commit 733a379ca3)
2025-09-17 11:36:53 -07:00
Seth Hillbrand 021229647f Prevent lines from drawing on netclass layer
Only wires and busses get netclasses

Fixes https://gitlab.com/kicad/code/kicad/issues/21731

(cherry picked from commit 5fdfff2b9c)
2025-09-17 11:19:58 -07:00
Seth Hillbrand 9a812bc63c Remove noise from orthographic projection raytracing
We generally add some jitter to the raytracing lines in order to smooth
out over multiple iterations some of the imperfections.  However, when
we do this to an orthographic projection (where all lines are parallel
to start, we don't average and just introduce noticeable noise in the
render

Fixes https://gitlab.com/kicad/code/kicad/issues/8863

(cherry picked from commit abf3438ed6)
2025-09-17 11:18:47 -07:00
Seth Hillbrand 8a9201b79c Update properties to show units
The function duplicated our built-in funcitonality and did not properly
handly outputs

Fixes https://gitlab.com/kicad/code/kicad/issues/21685

(cherry picked from commit 3f8abe3744)
2025-09-17 11:06:25 -07:00
Jeff Young f8e9b3402f Comboboxes for units and body styles.
Also for pin-types in pad properties.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19904

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19905

(cherry picked from commit ec155c00f3)
2025-09-17 11:05:57 -07:00
Seth Hillbrand 808c645933 Don't convert URI slashes on Windows
We auto-convert paths for windows boxes but this should not happen for
uri schemes that have the form <URI>://<path>

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20381

(cherry picked from commit e85a8056f5)
2025-09-17 10:46:41 -07:00
Adrián García ea467c1bac Fix crash in LIB_SYMBOL::SetUnitCount when reducing unit count
When decreasing the number of units in a symbol, the previous code erased
items directly from m_drawings using a single iterator. Because m_drawings
is a MULTIVECTOR, this could invalidate iterators and attempt to erase
from the wrong bucket, leading to segmentation faults.

This patch iterates bucket by bucket and erases items belonging to units
greater than the requested count. This ensures iterator safety and avoids
accessing invalid memory.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21631

(cherry picked from commit fb558eee3c)
2025-09-17 10:46:14 -07:00
Seth Hillbrand c51b6a0cd2 Prevent GTK from providing stale position
When the library name and symbol/footprint name both match the filter,
we try to display both but ensure visible can move things to the wrong
place.  We need to ensure the filtered list is up to date prior to
moving by ensureVisible

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18000

(cherry picked from commit dc7e0665c3)
2025-09-17 10:45:40 -07:00
Seth Hillbrand 10f16ed82e Prevent modifying teardrops on lock/unlock
This action doesn't affect geometry, so don't dirty the teardrops

Fixes https://gitlab.com/kicad/code/kicad/issues/21342

(cherry picked from commit ad80113f47)
2025-09-17 10:45:17 -07:00
Seth Hillbrand ab9cf326e8 Consider visibility when colliding in DRC
Most places we check this but we should also check it in physical
clearance

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21625

(cherry picked from commit d9741fd46a)
2025-09-17 10:44:53 -07:00
Seth Hillbrand 4e6087c183 Prevent main KiCad window from expanding based on DPI events
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21602

(cherry picked from commit f5904cf2ac)
2025-09-17 10:44:32 -07:00
Seth Hillbrand e7abf472ba Make properties panel obey free pads setting
Pads should almost never be moved without their parent.  Only allow this
in the case where free pads has explicitly been checked

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21591

(cherry picked from commit b22f259ccb)
2025-09-17 10:42:58 -07:00
Addo White f0c6b57ab9 Fix for Cursor rendering on Linux+EGL+Nvidia in accelerated graphics mode
EGL/NVidia can sometimes clip the cursor based on its plane regardless
of the depth mask.  This avoids the issue by forcing the cursor up over the existing plane.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/12183

(cherry picked from commit 843eea259d)
2025-09-17 10:42:13 -07:00
Seth Hillbrand e830709cda Make Expand Connection respect the filter
Prevents expansion that would require traversing elements that are
disabled in the selection filter

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21581

(cherry picked from commit a811f61c39)
2025-09-17 10:39:58 -07:00
Seth Hillbrand 415aac7fc5 Fix Chessboard splitting
Due to a bug(?) in Clipper2, 45° collinear edges may not be detected.
See https://github.com/AngusJohnson/Clipper2/issues/1008 for current
status.  In the meantime, we pre-process these to remove the extraneous
joints preventing our triangulation from getting mixed up

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18176

(cherry picked from commit 408e1feae2)
2025-09-17 10:37:44 -07:00
modbw 21f15c3b2a Fix net assignment messed up in Eagle import
When there is a polygon in the Eagle project withput any pad connected
netCode was not incremented and so the wrong nets were assigned to the
following elements.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21243

(cherry picked from commit 57ad779797)
2025-09-17 10:36:17 -07:00
Seth Hillbrand 0f8df0bcee Ensure that we check tracks exiting pads for gaps
The DP gap check should look for sections of track that are coupled by
wider than a given spacing.  Our primitive check of looking for
collisions on the segment between the start poins causes tracks exiting
but not entering pads to be excluded.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21561

(cherry picked from commit 1e76f1a11d)
2025-09-17 10:34:50 -07:00
Seth Hillbrand d6ef6252a2 Maintain group membership when shoving
Keep track of the original group membership and assign this to the newly
created element as well

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20862

(cherry picked from commit 2db8c6eca0)
2025-09-17 10:33:36 -07:00
Seth Hillbrand f13c9cbd49 Prevent stale names in fp browser
When switching libraries, if there is an additional footprint with the
same name, we don't want to select it by default as this will prevent
updating the footprint display.  Instead, force the update

Fixes https://gitlab.com/kicad/code/kicad/-/issues/9763

(cherry picked from commit cb620338db)
2025-09-17 10:29:31 -07:00
Seth Hillbrand c2af66a44b Specialize the pad wall drawing
Avoids slowdown when zoom/pan with many THTs as everything remains
cached.  Still slow in Cairo but this is expected

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20506

(cherry picked from commit 3ef862f7b6)
2025-09-17 10:27:56 -07:00
Seth Hillbrand 40c50c94fb Help is always valid
Return 0 and no error, just help when the --help flag is present

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21538

(cherry picked from commit 9dc76f658d)
2025-09-17 10:27:21 -07:00
Seth Hillbrand 0103f92d0e Add more parent safety checks
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21317

(cherry picked from commit e346139301)
2025-09-17 10:26:51 -07:00
Seth Hillbrand 0f27f8b7fc Enforce board-level hole to hole on diff pairs
Makes the router behave like the DRC

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21240

(cherry picked from commit cac334bb45)
2025-09-17 10:25:56 -07:00
Seth Hillbrand 5631b61dbc Find the proper line split
And avoid leaving duplicate tracks when overlapping

Fixes https://gitlab.com/kicad/code/kicad/-/issues/10422

(cherry picked from commit 8acdcafe90)
2025-09-17 10:25:32 -07:00
Seth Hillbrand da659f5d05 Manually check pad layers before inserting
We do not rely on GetEffectiveShape(layer) to return null for layers
that the pad does not exist on.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21523

(cherry picked from commit 2e1910ca86)
2025-09-17 10:23:46 -07:00
Seth Hillbrand 2029c5389f Move IPC2581 output to REPORTER
Adds a wx_reporter_panel to the 2581 output window, shunt messages
through the reporter instance

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16314

(cherry picked from commit 44228bd580)
2025-09-17 10:23:21 -07:00
Seth Hillbrand 4205e70775 Update cache when modifying schematic
Fixes https://gitlab.com/kicad/code/kicad/-/issues/18297

(cherry picked from commit 2347b290cb)
2025-09-17 10:17:08 -07:00
Seth Hillbrand 4f66225de7 Allow multiple pad->single pin in 2581 correctly
Grouped pads by pin number in the IPC-2581 exporter so only one pin node
is created per number.  Still output multiple pad shapes with the same
number.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18688

(cherry picked from commit c1cd4dd157)
2025-09-17 10:16:42 -07:00
Seth Hillbrand 18e4682c3a Set embedded delegate to update view properly
When embedding a 3d model we want to be able to see it immediately but
this requires getting the embedded files from the delegate model

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19991

(cherry picked from commit bd86f979ed)
2025-09-17 10:16:17 -07:00
Seth Hillbrand 6b540ae1e3 Add embed option to standard file dialog for 3dmodels
Fixes https://gitlab.com/kicad/code/kicad/-/issues/20025

(cherry picked from commit 09cdca876c)
2025-09-17 10:15:51 -07:00
Seth Hillbrand 1f12b6c17d Force overlapping wires to share labels
Crossing wires with pathological label in the center are actually
connected for the netlist.  This is an ERC error but we should keep
things consistent.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21494

(cherry picked from commit c995d47c87)
2025-09-17 10:11:43 -07:00
Seth Hillbrand e2c23c70f1 Allow soldermask bridging between nettie items
Previously we only allowed graphical items but within the net-tie we
need to allow bridging for connected items as well

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19288

(cherry picked from commit 8faf1b4d0e)
2025-09-17 10:06:32 -07:00
Seth Hillbrand f60f0394be Fix preferential coordinates in rule display
Fixes https://gitlab.com/kicad/code/kicad/-/issues/11546

(cherry picked from commit eb89d7ffcc)
2025-09-17 10:06:23 -07:00
Seth Hillbrand bd64bcf446 Keep the ruler measurements on screen
Fixes https://gitlab.com/kicad/code/kicad/-/issues/11546

(cherry picked from commit b2fbb326b0)
2025-09-17 10:04:42 -07:00
Seth Hillbrand 176d0f5820 Slight modification to followTrivialPath
Now keeps track of branch points, recursing through them to find the
longest path it can in both directions.  This helps to ignore
overlapping segments

Fixes https://gitlab.com/kicad/code/kicad/-/issues/7809

(cherry picked from commit 4c5b44545f)
2025-09-17 10:04:13 -07:00
Seth Hillbrand 118ee1c072 Prevent autosave error from cluttering the screen
Once per session, per editor we can show the error.  After that, assume
that the designer has seen and knows about the issue.

Fixes https://gitlab.com/kicad/code/kicad/issues/21464

(cherry picked from commit 9f2b04c7e2)
2025-09-17 09:57:32 -07:00
Seth Hillbrand fd15a1108b Allow wildcard matching for Netclass naming
Fixes https://gitlab.com/kicad/code/kicad/issues/21455

(cherry picked from commit fcd2da354d)
2025-09-17 09:56:46 -07:00
Seth Hillbrand 43b5d4d91f Ensure archives without ext are given .zip
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21423

(cherry picked from commit 2ded7b87af)
2025-09-17 09:56:19 -07:00
Seth Hillbrand d11ab8201f Allow generator actions to affect children
Changing the generator will often modify the underlying children's
properties.  We should store these data in the stack.  Also add the
ability to change layers

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21476

(cherry picked from commit 3ec380d93c)
2025-09-17 09:55:52 -07:00
Seth Hillbrand 86bae558b4 Fix broken cherry-pick 2025-09-17 09:55:52 -07:00
Seth Hillbrand 68991a7644 Make move tool obey snap settings
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21192

(cherry picked from commit 8bf7975440)
2025-09-17 09:40:06 -07:00
Seth Hillbrand 0701640c5a Prevent error message when backpropagating
Need to allow only processing other fields

Fixes https://gitlab.com/kicad/code/kicad/issues/21467

(cherry picked from commit 8a081f60b1)
2025-09-17 09:39:14 -07:00
Seth Hillbrand 9fe656a33c Remove namespacing from IPC2581 output
Because some readers maintain global namespace per the standard, we make
sure that we don't overlap names between namespaces but keep the minimum
viable name for each element

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19914

(cherry picked from commit 8f625086b1)
2025-09-17 09:38:48 -07:00
Seth Hillbrand 3fb8f22fd3 Have Find dialog update its cache on board mod
We don't want to find stale references

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21445

(cherry picked from commit 1a8dac9296)
2025-09-17 09:30:30 -07:00
Seth Hillbrand 929930fb3a Show inherited fields in symbols
When working with derived symbols, make sure that we show all of the
fields, not just the ones that are defined in the current level since
they are all attached to the output.

Inherited fields are shown in italics until changed

Fixes https://gitlab.com/kicad/code/kicad/-/issues/11422

(cherry picked from commit ff5a309386)
2025-09-17 09:12:09 -07:00
Seth Hillbrand 4195b874d5 Properly order netlist pages
We cannot reorder these without updating the defines.  So, keep the GUI
in line with the definitions

Fixes https://gitlab.com/kicad/code/kicad/issues/21730

(cherry picked from commit 497afffd48)
2025-09-17 17:59:08 +02:00
Jeff Young ae0d6c80dd Don't overwrite footprint filters created from multiple tokens in footprint column.
(cherry picked from commit 9ddb5465e1)
2025-09-17 13:13:23 +01:00
Jeff Young 4e2f84727c ADDED: support for multiple footprints in the footprint json from HTTP libraries
These are semi-colon-separated.

This is different from the footprint_filters dict entry, which is space-separated.

The first footprint in the footprint dict entry
will go into the "Footprint" field, while the rest
will go into the symbol's footprint filters.

(cherry picked from commit 91405ae34d)
2025-09-17 13:13:17 +01:00
Jeff Young 35889130e8 Formatting and naming conventions.
(cherry picked from commit 2eb3518e49)
2025-09-17 13:10:56 +01:00
Jeff Young 2e7145cc4b ADDED: handling of meta-data items in REST libraries.
"description" and "keywords" must hold string values;
"footprint_filters" can either hold a (space-
separated) string value, or an array of strings.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20750

(cherry picked from commit 1f1f490887)
2025-09-17 13:02:09 +01:00
Jeff Young e0d955993c Catch all errors thrown by nanodbc.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21707

(cherry picked from commit 37df36be62)
2025-09-17 13:00:45 +01:00
Mark Roszko cd7a646fcc Fix up arm assembly compiling on windows 2025-09-15 21:01:50 -04:00
Mark Roszko cb2a09d17c Edit ConfigurePlatform.cmake
(cherry picked from commit bda994c00a)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-09-15 23:47:12 +00:00
Mark Roszko d0cb210427 Also set CMAKE_SYSTEM_PROCESSOR in win cross compile
(cherry picked from commit e02008630f)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-09-15 23:43:55 +00:00
Seth Hillbrand b89d77bf36 Do not leave stale edges floating around
We assume that all net edges are valid in too many places

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21745
2025-09-15 07:01:18 -07:00
Mark Roszko 7fdeb4796a Manually set CMAKE_CROSSCOMPILING on MSVC.
(cherry picked from commit accb0ddcd1)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-09-14 15:00:49 +00:00
Roberto Fernandez Bautista e82088a59b Windows CI: custom vcpkg triplet to ensure shareable binary cache
(cherry picked from commit 8d8bd7253f)
2025-09-13 23:45:41 +02:00
Seth Hillbrand 5a5191361f Second pass at fixing warping and grids
First attempt caused additional problems for #21535

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18196

(cherry picked from commit 2cdeb0cd7c)
2025-09-12 10:52:36 +02:00
jean-pierre charras b47f8f4504 Revert "Remove the forced ancillary grid"
This reverts commit 7b602142b1.
2025-09-12 10:51:29 +02:00
jean-pierre charras 00ae91d6b5 Gerbview: fix broken behavior for deprecated command IPPOS and IPNEG
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21715

(cherry picked from commit 45166bf5c3)
2025-09-11 14:32:17 +02:00
Jeff Young 097e0eadf1 LIBEVAL::CONTEXT manages its own local VALUEs.
Don't use std::unique_ptr as we'll just free the
value right after storing it.

Also, don't try to execute a non-existent function.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21697

(cherry picked from commit 6ab6283e2e)
2025-09-11 12:50:31 +01:00
Jeff Young c8c293dca8 Don't allow stack addresses to escape via long-life handlers.
(cherry picked from commit cff261ce2e)
2025-09-09 14:57:13 +01:00
Jeff Young e6cfd1cdcf Formatting.
(cherry picked from commit b98621c8c8)
2025-09-09 14:57:13 +01:00
Jeff Young 905170b4f4 Only test parameters under the same conditions as we'd write them to the file.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21520

(cherry picked from commit 8ae2ad3586)
2025-09-09 14:57:12 +01:00
Jeff Young 57fa8ea2b9 Use WX_GRID::ClearRows() to avoid assertions.
Fixes KICAD-VM1.

(cherry picked from commit 0b102fc085)
2025-09-09 14:57:12 +01:00
Jeff Young c7730a00c4 Fix typo.
(cherry picked from commit 330361d0cb)
2025-09-09 14:57:12 +01:00
Alex Shvartzkop beaaf3b5be Update translations 2025-09-09 01:19:33 +03:00
dsa-t b644f15d7f Translated using Weblate (Hungarian)
Currently translated at 36.0% (3630 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-09 00:18:33 +02:00
Sárkány Lőrinc af398762db Translated using Weblate (Hungarian)
Currently translated at 36.0% (3630 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-09 00:18:33 +02:00
CloverGit dfd40b566d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-09-09 00:16:32 +02:00
KB e056ef2693 Translated using Weblate (Hungarian)
Currently translated at 36.0% (3630 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-09 00:16:32 +02:00
ZbeeGin 02d0944546 Translated using Weblate (Polish)
Currently translated at 99.5% (10019 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/pl/
2025-09-09 00:16:32 +02:00
Nguyễn Ngọc Khánh 1aba70ca37 Translated using Weblate (Vietnamese)
Currently translated at 23.5% (2368 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/vi/
2025-09-09 00:16:32 +02:00
Frank Sonnenberg ff8b82d060 Translated using Weblate (German)
Currently translated at 99.9% (10065 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:31 +02:00
ssantos 68d1e3223a Translated using Weblate (Portuguese)
Currently translated at 98.5% (9922 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/pt/
2025-09-09 00:16:31 +02:00
Frank Sonnenberg 9e64d52a38 Translated using Weblate (German)
Currently translated at 99.9% (10065 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:31 +02:00
CloverGit f7b3c0226b Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-09-09 00:16:31 +02:00
Frank Sonnenberg 17fc05ec45 Translated using Weblate (German)
Currently translated at 99.9% (10065 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:31 +02:00
Pferd O b64f1f2bd3 Translated using Weblate (German)
Currently translated at 99.9% (10063 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:31 +02:00
Frank Sonnenberg b32d8862da Translated using Weblate (German)
Currently translated at 99.9% (10063 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:31 +02:00
Hesham Eina Abdalla ff061e51a0 Translated using Weblate (Arabic)
Currently translated at 1.1% (117 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ar/
2025-09-09 00:16:31 +02:00
Ivan Chuba 6020e6d6f9 Translated using Weblate (Estonian)
Currently translated at 3.5% (357 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/et/
2025-09-09 00:16:31 +02:00
Frank Sonnenberg a3fffc868f Translated using Weblate (German)
Currently translated at 99.9% (10065 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:31 +02:00
Frank Sonnenberg 9670aa1b8a Translated using Weblate (German)
Currently translated at 99.9% (10065 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:30 +02:00
Frank Sonnenberg 85ba5ae406 Translated using Weblate (German)
Currently translated at 99.9% (10065 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:30 +02:00
Pferd O faa3287fd6 Translated using Weblate (German)
Currently translated at 99.9% (10065 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:30 +02:00
ZbeeGin 33ab1d9242 Translated using Weblate (Polish)
Currently translated at 99.5% (10018 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/pl/
2025-09-09 00:16:30 +02:00
Frank Sonnenberg 01aa2d7e42 Translated using Weblate (German)
Currently translated at 99.9% (10065 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:30 +02:00
Sárkány Lőrinc b24e2ac00d Translated using Weblate (Hungarian)
Currently translated at 35.9% (3617 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-09 00:16:30 +02:00
Frank Sonnenberg 2bc3ef82dc Translated using Weblate (German)
Currently translated at 99.9% (10065 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:30 +02:00
Sárkány Lőrinc 672ba5cd41 Translated using Weblate (Hungarian)
Currently translated at 35.6% (3591 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-09 00:16:30 +02:00
Pferd O 905b9ae6c5 Translated using Weblate (German)
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:30 +02:00
CloverGit f81a203c22 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-09-09 00:16:29 +02:00
Sárkány Lőrinc 7aa0431a60 Translated using Weblate (Hungarian)
Currently translated at 34.3% (3459 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-09 00:16:29 +02:00
Pferd O 57505674f8 Translated using Weblate (German)
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:29 +02:00
2tama3 558bef00cc Translated using Weblate (Japanese)
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-09-09 00:16:29 +02:00
Sárkány Lőrinc 28f9bd797a Translated using Weblate (Hungarian)
Currently translated at 34.2% (3446 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-09 00:16:29 +02:00
CloverGit 52d6fc66f1 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-09-09 00:16:28 +02:00
Максим Горпиніч ab49e9b29d Translated using Weblate (Ukrainian)
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/uk/
2025-09-09 00:16:28 +02:00
Henrik Kauhanen f6710e64de Translated using Weblate (Swedish)
Currently translated at 99.9% (10058 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-09-09 00:16:28 +02:00
dsa-t 804154e21d Translated using Weblate (Russian)
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ru/
2025-09-09 00:16:28 +02:00
2tama3 03cb8521bc Translated using Weblate (Japanese)
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-09-09 00:16:28 +02:00
Sárkány Lőrinc 3ee940e3fb Translated using Weblate (Hungarian)
Currently translated at 34.2% (3445 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/hu/
2025-09-09 00:16:28 +02:00
Frank Sonnenberg 8b25c3b0fe Translated using Weblate (German)
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:28 +02:00
Pferd O 529cf246d2 Translated using Weblate (German)
Currently translated at 100.0% (10066 of 10066 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-09-09 00:16:27 +02:00
Mark Roszko 7e7c281a64 Fix unit binder dropdown not working on windows
Fixes https://gitlab.com/kicad/code/kicad/-/issues/20626


(cherry picked from commit 0f97f51ba1)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-09-08 10:41:03 +00:00
Mark Roszko 350925f10a Shoehorn an improvement to table sorting to keep files more stable
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21652
2025-09-07 10:34:12 -04:00
Mark Roszko 5e8982600a Update ngspice to 45.2
(cherry picked from commit 922699f388)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-09-06 17:41:01 +00:00
Mark Roszko e633af9216 Update kicad-vcpkg and ngspice 2025-09-06 12:49:44 +00:00
jean-pierre charras b0f21e5452 DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR_BASE: fix a incorrect widgets type
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21662

From master branch
2025-09-06 13:28:41 +02:00
jean-pierre charras d2d582cc00 PCB_DIM_CENTER: fix incorrect bounding box size for 90deg cross.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21643

From master branch
2025-09-05 10:03:44 +02:00
jean-pierre charras 4f11681c4a French translation: fix typo 2025-09-05 09:51:45 +02:00
Mark Roszko 897ebee00f Fix position of package properties that must follow packages
(cherry picked from commit 9f1aa612ec)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-09-04 11:16:28 +00:00
Mark Roszko be0a42a09a Fix typo in allegro output for nets
(cherry picked from commit 9de2548064)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-09-04 11:09:35 +00:00
Mark Roszko 3069799a2d Fix double quoting tol for some reason
(cherry picked from commit a899da7cb7)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2025-09-04 03:00:05 +00:00
Mark Roszko ad22e53518 Fix the allegro netlist export and move mostly to {fmt}
Weirdly $PACKAGES header got shifted out of position.
Drop generating empty references.
2025-09-03 22:56:25 -04:00
Seth Hillbrand 2ef05eb191 Fix image pasting for MacOS
Apparently, GetImage() on MacOS does not always convert the image
properly.  So do a two-step here to get the Bitmap first, forcing the
conversion and then going back to an image

(cherry picked from commit 9f06d1f66b)
2025-09-03 09:20:12 -07:00
Seth Hillbrand 235e583182 Prevent crash in nettie
We need to avoid collecting invalid layers in the net ties regardless of
their origins

(cherry picked from commit 826f15a103)
2025-09-02 19:19:50 -07:00
Seth Hillbrand 76ce4ec535 Prevent pads from moving inappropriately
Free pads is a setting unless we are in the footprint editor and needs
to be respected by the alignmen tool

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21626

(cherry picked from commit 1f1f8699e0)
2025-09-02 09:11:48 -07:00
Jeff Young 0226481156 Give Mac dock icon menu a kick.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17596

(cherry picked from commit 98b63389c1)
2025-09-01 22:36:37 +01:00
Seth Hillbrand 8fab2d8ca3 Disable snap when moving with keyboard
Keyboard movement is for precision control, so avoid snapping behavior

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21235

(cherry picked from commit 9e326c29db)
2025-09-01 14:23:36 -07:00
Jeff Young 1c6d8b3f5e Don't reference stack variables from a long-life lambda.
In particular, a lambda for conditional menus should
never capture more than `[this]`.  Even the tool's
frame pointer could change.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21615
2025-09-01 12:37:43 +01:00
Jeff Young 32e9ab9b75 Don't reference stack variables from a long-life lambda. 2025-09-01 12:37:43 +01:00
Jon Evans ca0207016e API: Add ability to set enabled board layers and copper layer count 2025-08-31 22:18:53 -04:00
Mark Roszko 9ca1bf63d9 jobsets: fix Replace button to overwrite existing files (#19900)
(cherry picked from commit 5fb55ccb30)

1ea009e6 jobsets: allow replacing existing jobset files

Co-authored-by: Adrián García <adrgarcia@outlook.com>
2025-09-01 01:14:25 +00:00
Jeff Young 7e13870ae3 Allow stitching of graphic shapes.
(cherry picked from commit 1309b436da)
2025-08-31 19:34:22 +01:00
Jeff Young 3c907b5589 Set free vias to graphic net if available.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21578

(cherry picked from commit c47b7459aa)
2025-08-31 19:34:19 +01:00
Jeff Young e9efd9971c Don't set point to a value we're not going to keep.
It just causes flicker.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/19947

(cherry picked from commit a2e98fb53c)
2025-08-31 17:15:17 +01:00
Jeff Young 2bf9a6f5d1 Better interactive feedback.
Don't wait for mouse to move before refreshing after a command.

Also fixes a crash bug deleting an item after an
Unstage() (the Unstage() has already deleted the item).

Also fixes a crash when changing label type during
creation of a label produces a mess.

Also Keep cursor aligned to grid when not warping
back to original point.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16828

(cherry picked from commit 9d7db3d135)
2025-08-31 16:13:07 +01:00
jean-pierre charras 42c67b40b1 fix issues in ROUNDRECT: Fix incorrect ROUNDRECT Ctor.
- Do not throw  an error in CTor: this is not the place. It is much easy to
fix the value of incorrect radius.
Moreover, the Ctor is called without catching a throw-ed error in code.
- fix the test about radius validity, broken.

From master branch.
2025-08-31 08:25:14 +02:00
jean-pierre charras 5ae3c55a99 Step exporter: fix overzealous validity test.
When converting poly shapes with arcs in STEP_PCB_MODEL::MakeShapes,
when an error happens, a second try is made using a full polygonal shape.
However a fatal error was emitted at the first attempt, before the second try.
Now at first try, only a debug message is emitted on error. The fatal error
is emitted only if the second try fails.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21589

(cherry picked from commit aeafbe48fe)
2025-08-31 08:00:06 +02:00
Jeff Young 54e9a97b26 ADDED: separate front/back silk and mask colours for STEP export.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21593

(cherry picked from commit acc7b1e508)
2025-08-30 17:46:42 +01:00
Jeff Young 1e3b879d93 Run collision check on correct layer.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21586
2025-08-29 17:12:33 +01:00
Seth Hillbrand 7ca6a93436 Don't both designers with unneeded changes
If we are not asking for fields to be removed when updating, then don't
say we're doing anything if all we have to do is remove fields

(cherry picked from commit ea8206eca5)
2025-08-27 13:31:59 -07:00
jean-pierre charras 05c11d023f GERBER_JOBFILE_WRITER: fix incorrect layer id in File Attributes for inner layers.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21569

(cherry picked from commit 9725ac2215)
2025-08-27 13:28:55 +02:00
jean-pierre charras 996c3d7fa1 PAD: better HitTest( const VECTOR2I& aPosition, int aAccuracy, PCB_LAYER_ID aLayer )
(cherry picked from commit b349f1988a)
2025-08-27 13:27:45 +02:00
jean-pierre charras b204742fe3 Pcbnew: fix teardrop generation for pads having different shapes by layer.
Teardrop generator used pad::HitTest not testing the hit of a specific layer.
It created false test for some complex pads. Now use a test specific to a layer.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21560

(cherry picked from commit 963aa47778)
2025-08-27 11:35:07 +02:00
Emmanuel Vera 2b8e62e0b9 Update power filter for power symbols placement
(cherry picked from commit b5df0ad3eb)
2025-08-27 08:52:24 +02:00
jean-pierre charras c3d122becf French translation cleanup and update 2025-08-27 08:48:02 +02:00
John Beard 43c828474a Pcbnew: fix sensitivity of via placement to large grids
Another case where large grids are overly "grabby" for snaps.

In this case, because the via was moved to the grid-snap first,
and then THAT position was used to look for things like pad-snaps,
the pad snaps would not be found if a coarse grid meant the cursor
was outside the pad.

Instead, use the mouse position when looking for the non-grid snaps
in VIA_PLACER::SnapItem.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/18626
(cherry picked from commit 0f0527bd03)
2025-08-26 23:50:35 +08:00
John Beard 8073185c36 Pcbnew: use R-tree for pad checks in via place tool
Otherwise this is an O(n-pads-on-board) operation for every new
candidate via position.

(cherry picked from commit 3d8803f579)
2025-08-26 23:50:35 +08:00
Jeff Young f1ddcfe799 Expose shape in prop inspector for sheet pins.
(cherry picked from commit 3058bc6355)
2025-08-25 17:21:04 +01:00
jean-pierre charras 9d6f9c84d0 French translation update 2025-08-23 12:41:37 +02:00
jean-pierre charras 680a693c04 DIALOG_CHANGE_SYMBOLS: fix hanging is some cases and shows a better message.
When (happens after converting old schematics to the new format) trying to
update symbols having a bad lib id can hang Eeschema (infinite loop)
It can easily happens when the user has badly converted the schematic.
Also display a error message when happens.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21536

(cherry picked from commit 61aeea9237)
2025-08-23 12:40:48 +02:00
Alex Shvartzkop 4f72dd421a REPORTER's HasMessage indicates that any message got reported, not stored. 2025-08-23 00:27:41 +03:00
dsa-t bc533de0a3 Revert "Use board stackup colors by default in 3D render job."
This reverts commit f7380ae015
2025-08-23 00:09:53 +03:00
dsa-t c08109d63e Revert "Add FOLLOW_PCB, FOLLOW_PLOT_SETTINGS appearance presets to 3D render job dialog."
This reverts commit efc6c3e45e
2025-08-22 21:26:51 +03:00
Jeff Young b11f0a31b9 Read legacy tokens before current tokens.
(So current can overwrite.)

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21525

(cherry picked from commit 03c230dd64)
2025-08-22 17:03:32 +01:00
Jeff Young f6fabdc8ee Don't double mirror groups.
Also removes previous fix, which had side-effects.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/8121

Fixes https://gitlab.com/kicad/code/kicad/-/issues/20465

(cherry picked from commit 3f85071f91)
2025-08-22 17:03:25 +01:00
Jeff Young 965abb46d0 Avoid div-by-zero.
(cherry picked from commit c287d9a222)
2025-08-22 17:00:04 +01:00
Jeff Young c9f53c607e Fix missing initialization.
(cherry picked from commit de1c6c86ab)
2025-08-22 16:59:45 +01:00
Jeff Young 7b91b51bcf Add spacing for Mac file dialog custom controls.
(cherry picked from commit e841ca1906)
2025-08-22 16:59:29 +01:00
Jeff Young a3354dc352 Always provide a SCH_SCREEN to SCH_COMMIT.
Fixes KICAD-YKY

(cherry picked from commit a0940b10d4)
2025-08-22 16:57:17 +01:00
Jeff Young 6723964cdd Fix copy/pasta.
(cherry picked from commit c2f953e3f7)
2025-08-22 16:48:19 +01:00
Jeff Young df5f4ba541 Improve quasimodal comment.
(cherry picked from commit c85e5c08e4)
2025-08-22 16:46:39 +01:00
Jeff Young 926f41a0f5 Don't show locked shadow in pad preview.
(cherry picked from commit 60dbfd3eec)
2025-08-22 16:44:19 +01:00
Jeff Young db801c8d7e Remove stale comment.
(cherry picked from commit 3f1f9e8e72)
2025-08-22 16:43:35 +01:00
Jeff Young ad433b9468 ADDED: follow-pcb and follow-plot-settings to render job settings.
Also added Follow-board-stackup-colors to both
render job settings and render CLI arguments

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21341

(cherry picked from commit 2e629ca55c)
2025-08-22 16:41:58 +01:00
Jeff Young 1eefb2b70a Allow deletion of nested embedded files.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/20581

(cherry picked from commit ea84879b06)
2025-08-22 16:40:10 +01:00
Jeff Young 3d6527c1be Formatting.
(cherry picked from commit 7240128130)
2025-08-22 16:40:07 +01:00
Jeff Young 319530ad01 Grid is already updated by AddFile() callback.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/20565

(cherry picked from commit 2c3408aad5)
2025-08-22 16:38:19 +01:00
Jeff Young 24efca1db1 Focus second column control after property grid navigation.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/20651

(cherry picked from commit 95da436ddd)
2025-08-22 16:37:49 +01:00
Alex Shvartzkop a009d859d0 Fix some warnings. 2025-08-22 17:40:37 +03:00
Alex Shvartzkop 44a3bb9274 Prevent jobs from affecting each other via reporters when running jobsets from CLI. 2025-08-22 17:40:12 +03:00
Alex Shvartzkop 72e1904708 Fix ODB++ path creation. 2025-08-22 15:07:38 +03:00
Alex Shvartzkop 279a30974e Increase default precision in ODB++ export job dialog. 2025-08-22 14:34:43 +03:00
Alex Shvartzkop efc6c3e45e Add FOLLOW_PCB, FOLLOW_PLOT_SETTINGS appearance presets to 3D render job dialog. 2025-08-22 13:35:14 +03:00
Alex Shvartzkop f7380ae015 Use board stackup colors by default in 3D render job. 2025-08-22 13:34:25 +03:00
Alex Shvartzkop 26b6c28bef EasyEDA import: Add footprint Reference text on F_Fab. 2025-08-21 17:40:53 +03:00
Alex Shvartzkop 8cd7b73b2a EasyEDA import: Build basic Courtyard box for footprints. 2025-08-21 17:08:41 +03:00
Alex Shvartzkop c2d31699bf EasyEDA import: Place component shape and marking on F_Fab. 2025-08-21 17:04:23 +03:00
Alex Shvartzkop 47c5918c3d Add green color indication to length tuning status popup. 2025-08-21 15:38:08 +03:00
Alex Shvartzkop 12cf3f9301 router: Inline drag by track end even if cursor is slightly outside the track shape. 2025-08-21 13:56:25 +03:00
Alex Shvartzkop 013aab58d6 Update golden ERC QA files after 316a9511e8 2025-08-21 12:30:38 +03:00
Alex Shvartzkop 316a9511e8 Show errors before warnings in DRC/ERC. 2025-08-21 00:24:21 +03:00
Alex Shvartzkop 29fadcb931 Update translations 2025-08-21 00:16:37 +03:00
Pedro Moreira d73fecd2a1 Translated using Weblate (Korean)
Currently translated at 98.6% (9933 of 10065 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ko/
2025-08-20 23:15:12 +02:00
CloverGit 35caf91c31 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.9% (10059 of 10065 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-08-20 23:15:12 +02:00
2tama3 352cf21ffc Translated using Weblate (Japanese)
Currently translated at 100.0% (10065 of 10065 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-08-20 23:15:12 +02:00
CloverGit 21335f604f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 99.9% (10059 of 10065 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/zh_Hans/
2025-08-20 23:15:12 +02:00
Henrik Kauhanen c6b7f90408 Translated using Weblate (Swedish)
Currently translated at 99.9% (10058 of 10065 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/sv/
2025-08-20 23:15:12 +02:00
2tama3 a5dee0c2b1 Translated using Weblate (Japanese)
Currently translated at 100.0% (10065 of 10065 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/ja/
2025-08-20 23:15:12 +02:00
Ettore Atalan bf73ad42ca Translated using Weblate (German)
Currently translated at 99.9% (10062 of 10065 strings)

Translation: KiCad EDA/v9
Translate-URL: https://hosted.weblate.org/projects/kicad/v9/de/
2025-08-20 23:15:11 +02:00
John Beard 7d905948f5 Pcbnew: fix refdes ordering in arrays
The first cell of the array needs to not be reannotated, or it will
skips its own number(s) and take what we expect for the second cell.
The repeats until the last entry, which didn't reannotate anything,
leaving the original numbers. Producing a 'rotation' like 2,3,4,5,1
rather than the expected 1,2,3,4,5.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/20935
(cherry picked from commit f31a109ab4)
2025-08-21 00:26:50 +08:00
John Beard 5c8c0e0648 Pcbnew: fix occasional failure-to-select for dragging
In the Drag tool client filter function, sometimes,
GuessSelectionCandidates trims the collector's item list.
But we used the old contents of the per-type vectors to make
judgements about what was connected.

If a call came in with 2 tracks (e.g. near a knee) and one
was removed by GuessSelectionCandidates, sometimes the
other one would be the one selected for removal in the
2 tracks/0 via case. This leaves the collector empty.

The other case, where the item removed by GuessSelectionCandidates
was removed from the collector is silent, as removing an item
not in the collector is a no-op.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/21517
(cherry picked from commit 105b9fcfe8)
2025-08-20 20:40:01 +08:00
Alex Shvartzkop 4cfa2e3a38 Remove unnecessary newlines in STEP exporter logging. 2025-08-20 14:54:27 +03:00
Alex Shvartzkop eecf0cd685 Remove a Message_Printer holding a stale REPORTER pointer from OCCT.
Fixes KICAD-V8A
2025-08-20 13:57:48 +03:00
Alex Shvartzkop 91e5e81bb4 Record execute command job input and error streams in the log.
Also print the resolved command.
2025-08-20 13:07:29 +03:00
JamesJCode 5b3cd96641 Don't assume SCH_SYMBOLs have a LIB_SYMBOL when resolving embedded files
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21497

(cherry picked from commit ee9e94df04)
2025-08-19 14:17:02 +01:00
John Beard db0967d5c9 Pcbnew: fix bug in private layer selection
USer-defined layers now occur in steps of 2, otherwise
illegal layers for the grid get used.
2025-08-19 16:25:02 +08:00
jean-pierre charras 5165ced528 Eeschema: Reset m_ercRun flag when cleaning all markers.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21113

(cherry picked from commit 54085c4e50)
2025-08-18 17:33:30 +02:00
Alex Shvartzkop eb4f9fa093 Wrap command text control in execute command job dialog. 2025-08-18 17:06:17 +03:00
Alex Shvartzkop 47381f3d90 Disable ibeam cursor setter for search fields on non-OSX.
The ibeam cursor gets stuck on MSW when mouse leaves the field.
2025-08-18 15:53:37 +03:00
jean-pierre charras e697339bc6 PLOT_CONTROLLER::PlotLayer(): fix bug when drill marks must be plotted.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21474

(cherry picked from commit 20d8c9c7f9) and
(cherry picked from commit 2afd752bbc)
2025-08-18 11:48:07 +02:00
jean-pierre charras 6159cee2b0 Kicad manager: display the number of GDI objects in About Dialog (Windows only)
On Windows, if the number of GDI objects reach a limit (usually 10000) some can
be not shown, thus creating  a strange behavior not easy to diagnose.
Displaying the number in use can help.

(cherry picked from commit de208b3f00)
2025-08-18 09:07:31 +02:00
jean-pierre charras 3460b33ccf DIALOG_IMPORT_SETTINGS: fix some minor issues.
From master branch.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/21483
2025-08-18 08:43:40 +02:00
jean-pierre charras 5baaa89131 Reapply "SHAPE_ARC::GetCentralAngle(): better algo to calculate actual arc."
This new algo is now tested since more than 2 months, so it should be good.
This reverts commit 88ad461514.
2025-08-18 08:25:33 +02:00
Wayne Stambaugh d45a38f086 Begin version 9.0.5 development. 2025-08-17 15:48:17 -04:00
506 changed files with 213876 additions and 219285 deletions
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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 )
+38 -3
View File
@@ -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"
+33
View File
@@ -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;
+34
View File
@@ -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;
}
+22
View File
@@ -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;
}
+5
View File
@@ -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
+15 -29
View File
@@ -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 -2
View File
@@ -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)
-51
View File
@@ -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)
+17
View File
@@ -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 ) );
+52
View File
@@ -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>");
}
}
+10
View File
@@ -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
+3 -2
View File
@@ -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 ) )
+14 -13
View File
@@ -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;
}
+2 -1
View File
@@ -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() ) );
+7 -1
View File
@@ -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" ) ) );
+13 -2
View File
@@ -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();
+5 -2
View File
@@ -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
+2 -1
View File
@@ -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 )
{
+48 -8
View File
@@ -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() );
}
}
+1
View File
@@ -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;
+4 -4
View File
@@ -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
View File
@@ -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();
+79
View File
@@ -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 )
{
+2 -7
View File
@@ -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 );
+2 -1
View File
@@ -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() ) );
+8
View File
@@ -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
+61 -12
View File
@@ -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 )
{
+5
View File
@@ -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;
+58 -4
View File
@@ -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
+28 -5
View File
@@ -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();
}
+6 -3
View File
@@ -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
+38 -62
View File
@@ -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",
+3 -5
View File
@@ -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 ) );
}
+4 -1
View File
@@ -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 );
}
}
+25 -6
View File
@@ -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;
}
+3
View File
@@ -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 )
{
+3 -3
View File
@@ -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() )
+1 -1
View File
@@ -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 ) );
+1
View File
@@ -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 ) );
+1
View File
@@ -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;
+1 -1
View File
@@ -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 ) );
+3
View File
@@ -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
+1 -18
View File
@@ -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;
}
+10
View File
@@ -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 );
+6 -6
View File
@@ -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
View File
@@ -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 );
} );
}
+20
View File
@@ -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
}
+25
View File
@@ -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,
+1 -1
View File
@@ -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 );
}
+2 -2
View File
@@ -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++ )
{
+18 -2
View File
@@ -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 );
+80 -1
View File
@@ -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();
+3 -1
View File
@@ -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 ) )
{
+46 -77
View File
@@ -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;
}
+3
View File
@@ -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
View File
@@ -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;
}
+6
View File
@@ -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 )
+384 -77
View File
@@ -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();
}
+1 -1
View File
@@ -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
View File
@@ -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 );
}
+3
View File
@@ -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 );
+2
View File
@@ -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
View File
@@ -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 )
+16
View File
@@ -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 )
{
+4 -2
View File
@@ -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() );
}
+47
View File
@@ -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;
}
}
+27 -7
View File
@@ -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() );
+53 -33
View File
@@ -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();
+1 -1
View File
@@ -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;
+5 -1
View File
@@ -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();
}
+3
View File
@@ -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
+2 -2
View File
@@ -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
View File
@@ -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 );
+14 -2
View File
@@ -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();
+23
View File
@@ -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();
+2 -7
View File
@@ -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_
+156 -52
View File
@@ -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>&lt;path to SPICE binary&gt; \"%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>&lt;path to SPICE binary&gt; \"%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>&lt;path to SPICE binary&gt; \"%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
}
}
+1 -6
View File
@@ -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
+4 -1
View File
@@ -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
+87
View File
@@ -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
+203
View File
@@ -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 );
}
+898
View File
@@ -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>
+92
View File
@@ -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();
};
+107 -21
View File
@@ -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;
+2
View File
@@ -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
}
+2 -1
View File
@@ -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