Compare commits

...

241 Commits

Author SHA1 Message Date
Wayne Stambaugh 61a17e4c8b Tag stable version 8.0.2. 2024-04-27 13:08:12 -04:00
Mark Roszko 67dda92437 Hackfix crash in configure paths using non-ascii chars in column headers
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17743


(cherry picked from commit a565db58c5)

Co-authored-by: Marek Roszko <mark.roszko@gmail.com>
2024-04-27 14:17:22 +00:00
Seth Hillbrand 4dfe564243 Update translations 2024-04-26 19:52:18 -07:00
CloverGit 5b3c0028ea Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (9170 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-27 04:50:46 +02:00
Tokita, Hiroshi 53d219e9d5 Translated using Weblate (Japanese)
Currently translated at 99.9% (9168 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ja/
2024-04-27 04:50:46 +02:00
2tama3 a4da356ac7 Translated using Weblate (Japanese)
Currently translated at 99.9% (9167 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ja/
2024-04-27 04:50:46 +02:00
Ulices 2915a9d1a2 Translated using Weblate (Spanish (Mexico))
Currently translated at 99.8% (9156 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/es_MX/
2024-04-27 04:50:46 +02:00
Tokita, Hiroshi 6778eb8352 Translated using Weblate (Japanese)
Currently translated at 99.9% (9168 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ja/
2024-04-27 04:50:46 +02:00
CloverGit bdf8c04daf Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (9170 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-27 04:50:46 +02:00
Henrik Kauhanen a32ca5d0c4 Translated using Weblate (Swedish)
Currently translated at 99.9% (9168 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sv/
2024-04-27 04:50:46 +02:00
Tokita, Hiroshi 992bee7ec9 Translated using Weblate (Japanese)
Currently translated at 99.9% (9167 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ja/
2024-04-27 04:50:46 +02:00
Henrik Kauhanen 7216527224 Translated using Weblate (Finnish)
Currently translated at 99.7% (9148 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/fi/
2024-04-27 04:50:46 +02:00
Jan Straka 09bbabeef3 Translated using Weblate (Czech)
Currently translated at 80.9% (7422 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/cs/
2024-04-27 04:50:46 +02:00
CloverGit 3ee74e2966 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (9170 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-27 04:50:46 +02:00
dsa-t 312356c284 Translated using Weblate (Russian)
Currently translated at 100.0% (9170 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ru/
2024-04-27 04:50:46 +02:00
Nicoara Alex 6b9dba3d45 Translated using Weblate (Romanian)
Currently translated at 27.0% (2479 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ro/
2024-04-27 04:50:46 +02:00
ZbeeGin 02c03ba2b6 Translated using Weblate (Polish)
Currently translated at 99.9% (9169 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pl/
2024-04-27 04:50:45 +02:00
Laurens Holst c35ba8f4cd Translated using Weblate (Dutch)
Currently translated at 100.0% (9170 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/nl/
2024-04-27 04:50:45 +02:00
taotieren c344e170b9 Translated using Weblate (Chinese (Traditional))
Currently translated at 99.9% (9166 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
2024-04-27 04:50:45 +02:00
taotieren 5b5253b6e2 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (9170 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-27 04:50:45 +02:00
ZbeeGin 2954378f58 Translated using Weblate (Polish)
Currently translated at 99.9% (9165 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pl/
2024-04-27 04:50:45 +02:00
Pferd O eea71b9209 Translated using Weblate (German)
Currently translated at 100.0% (9170 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/de/
2024-04-27 04:50:45 +02:00
Hubert Hu 8eb98a2094 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (9168 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-27 04:50:45 +02:00
CloverGit 85d9feefff Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (9168 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-27 04:50:45 +02:00
Henrik Kauhanen c059cbce12 Translated using Weblate (Swedish)
Currently translated at 99.9% (9168 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sv/
2024-04-27 04:50:45 +02:00
dsa-t a84aa449b2 Translated using Weblate (Russian)
Currently translated at 99.9% (9169 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ru/
2024-04-27 04:50:45 +02:00
Tokita, Hiroshi a4a2ec07c4 Translated using Weblate (Japanese)
Currently translated at 99.8% (9154 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ja/
2024-04-27 04:50:45 +02:00
Pferd O d5557caa33 Translated using Weblate (German)
Currently translated at 99.9% (9164 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/de/
2024-04-27 04:50:45 +02:00
Wellington Terumi Uemura 47717ca779 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (9170 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pt_BR/
2024-04-27 04:50:45 +02:00
Tokita, Hiroshi d7f742f911 Translated using Weblate (Japanese)
Currently translated at 99.6% (9135 of 9170 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ja/
2024-04-27 04:50:44 +02:00
Seth Hillbrand 86ebc85404 Avoid assert on unhandled properties call 2024-04-26 19:50:00 -07:00
jean-pierre charras 5d4ed4b21a French translation: fix a typo 2024-04-26 09:58:07 +02:00
Seth Hillbrand 1ca0737c34 Replace stale pin references with UNDO copy
When we replace a symbol with one that has fewer pins, the old pins
are released, which leaves points to them in the connection graph
dangling.  This updates the pointer to use the cloned copy in the undo
stack until the connection graph is rebuilt with the new data

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

(cherry picked from commit 315ad0e071)
2024-04-24 12:55:30 -07:00
Seth Hillbrand 3a29fa44e3 Ensure that missing pins are added to extraction
When changing from a larger part to a smaller part, the previously
existing pins may be removed from the screen but still linked to
elements in the connection graph because we don't set them dirty unless
the changed element overlaps

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

(cherry picked from commit 0cd3e17db7)
2024-04-23 19:37:59 -07:00
Wayne Stambaugh 3517d25aec Tag stable version 8.0.2 release candidate 2. 2024-04-18 16:21:19 -04:00
Wayne Stambaugh 8d62a5fd3f Fix missing instance data when reusing an already loaded schematic.
Remove duplicate sheet instance page numbering.  It's already done when
the sheet is loaded from an exiting file or an already loaded schematic.
Remove the unnecessary page update code from the drawing tool.

(cherry picked from commit 17bcc27ff6)
2024-04-18 16:07:36 -04:00
Seth Hillbrand 9e5876df5c Remember to set the root sheet before loading
This is done in the frame for GUI loading so we need to explicitly set
this when loading files in the cli

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

(cherry picked from commit f8a25d20f8)
2024-04-18 10:48:15 -07:00
Seth Hillbrand fdc3806ed1 Protect courtyard cache regen
The courtyards are referenced by multiple calls and will be rebuilt on
command.  If this happens during zone fill (because the board timestamp
has incremented since the start) multiple threads may generate the cache
at the same time, leaving one with an invalid pointer

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

(cherry picked from commit df5dd15c6f)
2024-04-18 08:41:43 -07:00
jean-pierre charras 798b827a12 Plot pads: Do not use pad offset twice when plotting chamfered rect pads
from Master branch

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17793
2024-04-18 14:03:11 +02:00
Seth Hillbrand 4ade0ac73d Don't sort on lost references
The arraystring reference is lost when we don't keep the wxFileName
variable in scope.

This also adds removing invalid paths and checking for correct version
before sorting

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

(cherry picked from commit d2701323a8)
2024-04-17 12:24:17 -07:00
Seth Hillbrand 65fd8d22ed Mask aperture pads can have multiple layers
But as long as they don't have copper, we should treat them as mask
apertures

(cherry picked from commit 02cdb0c6b9)
2024-04-16 15:54:36 -07:00
Alex Shvartzkop 481c1592ae STEP export: don't fail when can't construct a wire.
This can happen with very small shapes.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17774
2024-04-17 01:35:00 +03:00
Mark Roszko 9af12e60d2 Close bom file earlier
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17779

(cherry picked from commit 5d7e96841b)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2024-04-16 14:30:13 +00:00
Marco Ciampa 048448296d Updated Italian translation 2024-04-15 23:38:28 +02:00
Wayne Stambaugh e03308e5ca Tag stable version 8.0.2 release candidate 1. 2024-04-15 06:20:59 -04:00
Wayne Stambaugh 16691c8d03 Fix string so it gets translated properly. 2024-04-15 06:18:20 -04:00
jean-pierre charras dac0296e3a French translation update 2024-04-15 10:41:22 +02:00
Seth Hillbrand 52ce4c0313 Update translations 2024-04-14 14:22:32 -07:00
Henrik Kauhanen 1956204635 Translated using Weblate (Swedish)
Currently translated at 99.9% (9161 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sv/
2024-04-14 23:19:57 +02:00
pominglee b4bd14ba10 Translated using Weblate (Chinese (Traditional))
Currently translated at 93.6% (8583 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
2024-04-14 23:19:57 +02:00
pominglee 8f7f6739c3 Translated using Weblate (Chinese (Traditional))
Currently translated at 93.6% (8583 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
2024-04-14 23:19:57 +02:00
pominglee 4eebd8ad6c Translated using Weblate (Chinese (Traditional))
Currently translated at 93.5% (8573 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
2024-04-14 23:19:57 +02:00
Marek 4b3d67ffda Translated using Weblate (Polish)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pl/
2024-04-14 23:19:57 +02:00
Ulices f3e3236a43 Translated using Weblate (Spanish (Mexico))
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/es_MX/
2024-04-14 23:19:57 +02:00
Ulices 82ee4a81ed Translated using Weblate (Spanish)
Currently translated at 99.1% (9082 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/es/
2024-04-14 23:19:57 +02:00
Alex Gellen 55fbdddbb7 Translated using Weblate (Romanian)
Currently translated at 27.0% (2477 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ro/
2024-04-14 23:19:57 +02:00
Henrik Kauhanen 7cce1901b2 Translated using Weblate (Swedish)
Currently translated at 99.9% (9161 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sv/
2024-04-14 23:19:57 +02:00
김랑기 0f4f1c0d3b Translated using Weblate (Korean)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ko/
2024-04-14 23:19:57 +02:00
j.Kolod 78849ba5c0 Translated using Weblate (Polish)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pl/
2024-04-14 23:19:56 +02:00
김랑기 a066c57fcc Translated using Weblate (Korean)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ko/
2024-04-14 23:19:56 +02:00
CloverGit 8684c0f9be Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (9162 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-14 23:19:56 +02:00
ssantos db94f8c8ef Translated using Weblate (Portuguese)
Currently translated at 99.9% (9162 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pt/
2024-04-14 23:19:56 +02:00
co8 j db0f7ec457 Translated using Weblate (Japanese)
Currently translated at 99.6% (9128 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ja/
2024-04-14 23:19:56 +02:00
Jan Straka 2bf4cca58a Translated using Weblate (Czech)
Currently translated at 80.6% (7390 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/cs/
2024-04-14 23:19:56 +02:00
Laurens Holst 4470f4e6d8 Translated using Weblate (Dutch)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/nl/
2024-04-14 23:19:56 +02:00
pondahai e516ab5114 Translated using Weblate (Chinese (Traditional))
Currently translated at 93.5% (8572 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
2024-04-14 23:19:56 +02:00
김랑기 0282b142b8 Translated using Weblate (Korean)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ko/
2024-04-14 23:19:56 +02:00
Ulices 676108952e Translated using Weblate (Spanish (Mexico))
Currently translated at 99.7% (9141 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/es_MX/
2024-04-14 23:19:56 +02:00
aris-kimi 8470091a4b Translated using Weblate (Greek)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/el/
2024-04-14 23:19:56 +02:00
Jan Straka 3302ef537f Translated using Weblate (Czech)
Currently translated at 80.1% (7348 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/cs/
2024-04-14 23:19:56 +02:00
CloverGit 366f7aea6b Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (9162 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-14 23:19:56 +02:00
Dmitry Mikhirev eed2221651 Translated using Weblate (Russian)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ru/
2024-04-14 23:19:56 +02:00
Laurens Holst 90093c0fdd Translated using Weblate (Dutch)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/nl/
2024-04-14 23:19:55 +02:00
simmon 2adccce3b8 Translated using Weblate (Korean)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ko/
2024-04-14 23:19:55 +02:00
CloverGit 6bf9653bef Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (9162 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-14 23:19:55 +02:00
dsa-t 04c083ac48 Translated using Weblate (Russian)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ru/
2024-04-14 23:19:55 +02:00
Laurens Holst 9a236e5972 Translated using Weblate (Dutch)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/nl/
2024-04-14 23:19:55 +02:00
pominglee 521e773f2c Translated using Weblate (Chinese (Traditional))
Currently translated at 93.5% (8572 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
2024-04-14 23:19:55 +02:00
Andrej Valek e28aa6d16c Translated using Weblate (Slovak)
Currently translated at 65.0% (5956 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sk/
2024-04-14 23:19:55 +02:00
Andrej Valek 001c90c69f Translated using Weblate (Slovak)
Currently translated at 64.8% (5944 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sk/
2024-04-14 23:19:55 +02:00
Laurens Holst cba73e6cea Translated using Weblate (Dutch)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/nl/
2024-04-14 23:19:55 +02:00
Ulices 5af4f3f9df Translated using Weblate (Spanish (Mexico))
Currently translated at 99.5% (9125 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/es_MX/
2024-04-14 23:19:55 +02:00
pominglee e1b922ae19 Translated using Weblate (Chinese (Traditional))
Currently translated at 93.5% (8568 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
2024-04-14 23:19:55 +02:00
CloverGit f1d988788a Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (9162 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-14 23:19:55 +02:00
dsa-t 8e6cb7b350 Translated using Weblate (Russian)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ru/
2024-04-14 23:19:55 +02:00
Toni Laiho 6685eefc8e Translated using Weblate (Finnish)
Currently translated at 99.9% (9159 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/fi/
2024-04-14 23:19:55 +02:00
aris-kimi 8d231b8c96 Translated using Weblate (Greek)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/el/
2024-04-14 23:19:54 +02:00
ZbeeGin 313e09cfd3 Translated using Weblate (Polish)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pl/
2024-04-14 23:19:54 +02:00
Laurens Holst 5a05a1337e Translated using Weblate (Dutch)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/nl/
2024-04-14 23:19:54 +02:00
Ulices a40929fa71 Translated using Weblate (Spanish (Mexico))
Currently translated at 99.5% (9120 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/es_MX/
2024-04-14 23:19:54 +02:00
CloverGit 37eb5f4a8d Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (9162 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-04-14 23:19:54 +02:00
Henrik Kauhanen b7d1fb944c Translated using Weblate (Swedish)
Currently translated at 99.9% (9161 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sv/
2024-04-14 23:19:54 +02:00
Marcel Hecko 9797d2d133 Translated using Weblate (Slovak)
Currently translated at 64.6% (5923 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sk/
2024-04-14 23:19:54 +02:00
dsa-t e34bb98ba1 Translated using Weblate (Russian)
Currently translated at 99.9% (9161 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ru/
2024-04-14 23:19:54 +02:00
Pedro Moreira 60440094ba Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pt_BR/
2024-04-14 23:19:54 +02:00
Laurens Holst c198e5ee15 Translated using Weblate (Dutch)
Currently translated at 99.9% (9162 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/nl/
2024-04-14 23:19:54 +02:00
김랑기 ceedfd9b7e Translated using Weblate (Korean)
Currently translated at 99.9% (9162 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ko/
2024-04-14 23:19:54 +02:00
Pedro Moreira a4fbbaaa0b Translated using Weblate (Korean)
Currently translated at 99.9% (9162 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ko/
2024-04-14 23:19:54 +02:00
Pferd O 6cbdac5bf1 Translated using Weblate (German)
Currently translated at 100.0% (9163 of 9163 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/de/
2024-04-14 23:19:54 +02:00
Seth Hillbrand 26629928c3 Incremental updates should not clear globals
Netclass assignments are stored in the project level but
CONNECTION_GRAPH updates would clear the assignments.  This keeps
existing netname->netclass assignments but updates any netnames that
were changed by the incremental updates.  Absolute updates are not
affected and fully recreate the net name to netclass map

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

(cherry picked from commit e538b98286)
2024-04-14 14:14:38 -07:00
Seth Hillbrand 55c864ec45 Fix incremental connectivity
The connectivity routine would consider symbols, overwriting unused
subgraphs for pins that were not in the change list.  This is resolved
by updating the full connectivity to only use pins in the graph since
symbols are not connected independently.

In the process of adding QA tests for this change, additional issues
with the schematic QA were discovered.  Specifically, we were not
properly setting the root sheet UUID.  This was partially masked by a
const_cast setting of the RefDes in sch_symbol when called the RefDes
getter.  This exposed the fact that our QA ERC numbers did not match the
schematic editor stand alone ERC numbers.  So the test value for one
check needed to be updated

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

(cherry picked from commit a9f35ba42e)
2024-04-14 14:14:38 -07:00
Seth Hillbrand 07b5fd342a Ensure that we are not calculating self-collision
Ratsnest may have connections from a zone to two different items.  This
should be avoided as we never want to draw the ratsnest line with the
same element as start and finish

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

(cherry picked from commit 8760519a87)
2024-04-14 13:50:44 -07:00
Seth Hillbrand 4481fcc75e Check for valid shared pointer before locking
We don't neccesarily have a valid pointer to the parent lib symbol when
checking if it is a power symbol, so fall back to the local flag if this
is the case

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17182
2024-04-11 14:42:53 -07:00
Seth Hillbrand a155dd32e8 Do not set optional defaults
In the file format, the 'mirror' tag is optional (not written unless on)
so we cannot default the new text to 'mirror' on just because the
footprint is on the back layer as it won't be turned off by the
footprint loader.

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

(cherry picked from commit d0fe2e06aa)
2024-04-11 09:43:55 -07:00
Wayne Stambaugh c4c804edf7 Update hierarchy navigator when undoing or redoing sheet name changes.
Use new schematic commit object in the edit sheet properties dialog.

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

(cherry picked from commit ec310ac3ed)
2024-04-11 10:51:04 -04:00
Wayne Stambaugh b26ca0e21a Maintain hierarchy navigator expansion state between edits.
Prevent the hierarchy navigator from being rebuilt unless there are actual
sheet changes that would cause a change to the tree.

Save the tree expansion state before rebuilding the tree and then restore
the expansion state to the previous state sans edits.

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

(cherry picked from commit 797ab998cc)
2024-04-11 10:32:40 -04:00
Alex Shvartzkop 97b15a1708 Show actual IO_ERROR message at VRML import.
https://gitlab.com/kicad/code/kicad/-/issues/17727
2024-04-11 14:36:44 +03:00
Seth Hillbrand e808ab7409 Re-add routine to remove duplicate points
The router needs to elimitate duplicate points but keep colinear
segments.  This re-creates the partial routine from the old Simplify()
function

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

(cherry picked from commit 59f99d9a6a)
2024-04-11 14:20:50 +03:00
Huang Rui 7dc8527022 libgit2-1.8.0 compatibility: adjusted parent pointer type
- Adjusted parent pointer type in git_commit_create call for compatibility
  with libgit2 1.8.0 and above.
- Included preprocessor checks to maintain support for versions older than
  1.8.0.
- Ensures consistent function behavior across different libgit2 versions.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17536
Signed-off-by: Huang Rui <vowstar@gmail.com>


(cherry picked from commit 1cbf6a1872)
2024-04-11 08:45:19 +00:00
afkiwers f7765ea5b9 add support to update an already existing field
(cherry picked from commit d45911f54b)
2024-04-09 23:37:52 +00:00
Marco Ciampa f1d687cfdb Updated Italian translation 2024-04-08 23:17:23 +02:00
Marek Roszko 57468c29f9 Use kicad-vcpkg fork of liblzma to fix builds
(cherry picked from commit 6ac1f39e62)
2024-04-07 14:55:55 +00:00
Jon Evans 30df673ffa Check for bus no-connects in ERC
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13285


(cherry picked from commit ce846f5c22)
2024-04-07 12:50:45 +00:00
Jon Evans 55b7852a65 Disable lazy-loading of 3D models on macOS
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17198


(cherry picked from commit b36312ff24)
2024-04-07 12:21:11 +00:00
JamesJ 026685ee48 Check a SHAPE_POLY_SET outline exists before attempting to get it by index
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17687
2024-04-06 20:17:39 +02:00
Jon Evans 8b5c292397 Fix SWIG wrapper for AddPrimitive
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17676


(cherry picked from commit c1e7668d80)
2024-04-05 03:09:35 +00:00
Marek Roszko 941420abed Add missing gltf find in occ 7.8
(cherry picked from commit 58913a0616)
2024-04-03 01:07:18 +00:00
Jon Evans a042d1aab4 Show all library children if library name matches search 2024-04-02 18:51:19 -04:00
Jon Evans 53c2543474 Fix parsing of legacy text hide token 2024-04-02 18:26:30 -04:00
Alex Shvartzkop bac0820864 Improve moving, rendering and plotting of very small angle arcs.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17110


(cherry picked from commit b905b4eac8)
2024-04-02 21:41:09 +00:00
Seth Hillbrand e0381f25f7 Prevent OOB access in polygon split
Check for vertex placement against original size.  Since we are
potentially adding vertices that are out of order with the original
polygon, we only want to check against the first set of vertices when
checking for polygon collision

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

(cherry picked from commit 8260c174e9)
2024-04-02 11:23:30 -07:00
Mike Williams ce2ea3f3ae PCB: update footprint field when changing footprints
Fixes: https://gitlab.com/kicad/code/kicad/-/issues/17598
2024-04-02 08:18:23 -04:00
Seth Hillbrand c0d38de280 Add some corrections to IPC2581 export syntax
Outline fonts need lineDesc
Padstack def need the location for the pad relative to the padstack

(cherry picked from commit 2123e2ca9c)
2024-04-01 22:59:40 -07:00
Marek Roszko 9a728c37df Use macro not function for the occ lib find
(cherry picked from commit 303bc19ce8)
2024-04-02 01:55:08 +00:00
Seth Hillbrand 6be6210b67 Recreate teardrop QA board for v8 2024-04-01 17:55:29 -07:00
Seth Hillbrand b21165722b Forward and reverse test for point in poly collisions
(cherry picked from commit 4e6cd0d293)
2024-04-01 17:55:29 -07:00
Seth Hillbrand fd5d68ca9b Remove duplicated clearanceEpsilon
We already get clearance epsilon in the clearance resolver.  Don't
subtract it twice or we end up getting DRC errors

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

(cherry picked from commit 10c1072479)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 9f26cbb89a Add colored tab to fileicons
Allows differentiation when Windows badges the bottom left

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

(cherry picked from commit e11cc322fd)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 0dc894356b Check singular arcs connection
Even if there are no other segments in the line chain, we still should
check for arc connections in cases of individual arcs on a line chain

(cherry picked from commit 6b915049d1)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 6b5acdea1f When dragging a via, we need to get all obstacles
The clearance epsilon should not be used to limit which force elements
we return in the query.  Otherwise, we can drag elements into a
DRC-violating space

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

(cherry picked from commit 5e850911c5)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 892c5726f5 Move logging message after vertex check
When creating the list, we may have fewer than needed vertices, which
prevents calculating the area

(cherry picked from commit 6c05f2c67c)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 6c7261a223 Utilize hash_combine to avoid hash collision
Most of our pointers will share the top 32 or more bits of their pointer
addresses, making cache collisions highly likely.  This uses a hash
combiner to mix the bits more effectively

(cherry picked from commit e4756c811e)
2024-04-01 17:55:29 -07:00
Seth Hillbrand ae11213622 Handle small holes in DRC Connection width test
If there is a small hole (smaller than the conn width), we can loop
around in a circle checking all points and not move past the mimimum
distance.

To avoid this, if we detect a loop, we exit the substantial checker.
This should return with true because a large hole will return true and
we are only checking to see if there is a minimum amount of copper
between two open areas

(cherry picked from commit c841d0df6d)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 4bf35cbed8 Remove duplicated clearanceEpsilon
We already get clearance epsilon in the clearance resolver.  Don't
subtract it twice or we end up getting DRC errors

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

(cherry picked from commit 10c1072479)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 7916e56963 Avoid crashing on missing tracks in CADSTAR
We can't assume that the ignored connection exists when trying to set
the junction size.  We use int_max for the default instead of 0 so that
later, we don't try to create a minor track with 0 width in loadNets()

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

(cherry picked from commit 00d108498f)
2024-04-01 17:55:29 -07:00
StefanBruens b9b4ff6f5e Fix triangulationValid check race for zone fill
The m_triangulationValid flag is used in several places without holding
the mutex, thus it should only ever be set when the triangulation is
guaranteed to be valid.

This can either be done by protecting both data and flag by the same
mutex, or updating the flag only after the triangulation has finished.

Also fix the case when the triangulation actually fails, the flag should
not be set in this case.

While at it, simplify the recalculation check. Only if both the
triangulation is valid, and the data hash is unchanged the recalculation
can be skipped - this is typically the case when two threads try to
update the cache concurrently, the second one will block at the mutex,
and will see the valid data after the first thread has finished.

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

(cherry picked from commit e07b4ce8e4)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 734222bd88 Fix race condition in zone fill
When checking collisions, the SHAPE_POLY_SET::Collide() routine is not
const because it will regenerate the triangulation cache if it is out of
date (using a const_cast, grrr).  This sidesteps the issue by assigning
a mutex to the triangulation caching

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

(cherry picked from commit 81cb6d0c3f)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 01590385c7 Handle issue with alternate SHAPE_LINE_CHAIN
SHAPE_LINE_CHAIN_BASE can include things that are not SHAPE_LINE_CHAIN
like the triangle SHAPE_LINE primitive.  To check arcs, we need to avoid
these elements as they do not have the full SHAPE_LINE_CHAIN class
available.

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

(cherry picked from commit 347c50b26d)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 9be4bf0d14 Fix slow selection time when calculating clearance
The clearance between two zones could be rather slow.  This was in part
to trying to do triangle-triangle collisions between zones when we only
need outline collision and in part to the shape_line_chain collision
routine.  The shape_line_chain collisions don't need to recreate
segments on each iteration and should instead create them once and using
this to check all collisions

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

(cherry picked from commit 3cc1617f5a)
2024-04-01 17:55:29 -07:00
Seth Hillbrand b1677d5f47 Clean and standardize cross-probing action
Between schematic and pcb editors, we want the following actions:

- Single click on ERC/DRC item should show the item in the ERC/DRC
  window.  But if the window is not visible, it should only update the
  status bar
- Double click on ERC/DRC item should show and raid the ERC/DRC window
  as well as select the line item

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

(cherry picked from commit 0f57d76ecd)
2024-04-01 17:55:29 -07:00
Seth Hillbrand 1e13a7640e Tidy up some remaining triangulation cases
Found and fixed a few corner cases where triangulation point removal
could reset expected points

(cherry picked from commit 553e4a25bf)
2024-04-01 17:55:29 -07:00
Marek Roszko 804283877c Fix cmake find of opencascade libraries for occt 7.8
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17654


(cherry picked from commit c8e41dcfe8)
2024-04-02 00:50:12 +00:00
jean-pierre charras 65ace8d03d 3D viewer: Allow setting colors not in board stackup, when use board stackup option is set.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17632
2024-04-01 09:38:24 +02:00
Seth Hillbrand 890376d04f Do not use cache when we modify vertices
When we add vertices to the tesselation routines, we cannot reuse these
without the original vertex points.

It may be possible to copy and modify the vertices from the hint data so
that they are properly positioned but naive attempts (moving based on
first point) did not work, so for now, we disable the hint cache when
the vertex sizes do not match as this prevents OOB access

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

(cherry picked from commit 06b199fd41)
2024-03-31 15:01:16 -07:00
JamesJ 18990587b9 Only delete grouped / generated BOARD_ITEMS from the root item
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17527

This is required as during an undo / redo operation, rebuilding
the previous selection can result in a group / generator being
selected as well as all of their contained items. This prunes
the contained items to remove the possibility of a double-delete.

(cherry picked from commit 6c73f1feef28925bf26fcc3669cb6333aad5f1d3)
2024-03-30 14:20:58 +00:00
James J 75ef003747 Add option to preserve custom power flag values in Update Symbols from Library dialog
(cherry picked from commit bf7896a0e1)
2024-03-30 14:15:29 +00:00
Marek Roszko b9a6f47929 Fix DRC slowdown due to UI yields
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17434


(cherry picked from commit fd501b4bc8)
2024-03-30 03:34:27 +00:00
Jeff Young 857219d70d Fix merge error. 2024-03-29 18:26:14 +00:00
Jeff Young 92275c41cc ADDED: Expose units and DeMorgan to properties system.
(Also fixes inheritance bug in LIB_PIN's properties.)

(cherry picked from commit 58df9c96f4)
2024-03-29 17:49:48 +00:00
Jeff Young 09985988e7 Fix footprint undo for new UUID caches.
The footprint's children get swapped by the parent's std::swap
call, so they need to get removed/added to their parent around
the swap.

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

(cherry picked from commit 2c21ef1ed0)
2024-03-29 17:48:12 +00:00
Jeff Young 524d431438 More defensive coding for KICAD-YP.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17560

(cherry picked from commit 2f2c42a06b)
2024-03-29 17:46:07 +00:00
Jeff Young ccd052cc99 Attempt to prevent KICAD-YP.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17560

(cherry picked from commit a53bc9e026)
2024-03-29 17:46:04 +00:00
Jeff Young 1f461c7508 Close active cell editor when showing/hiding columns.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17425

(cherry picked from commit f3ce3bc758)
2024-03-29 17:45:35 +00:00
Jeff Young 4bea619855 Make sure users don't run into min text size.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17543

(cherry picked from commit fc572bfbc6)
2024-03-29 17:45:13 +00:00
Jeff Young f3621496fb Don't show hidden text in symbol previews.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17526

(cherry picked from commit 1e6eb652aa)
2024-03-29 17:44:47 +00:00
Jeff Young 1238c081c6 Expose groups to property manager.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17496

(cherry picked from commit 82c851a4a7)
2024-03-29 17:44:14 +00:00
jean-pierre charras 663e857df6 3D viewer: fix some graphic issues:
Avoid issue when a copper layers thickness is 0 (min value is now 1 micrometer)
Fix incorrect rendering of plated graphic items and vias (vertical walls not drawn)
From master branch
2024-03-29 07:39:49 +01:00
Seth Hillbrand 92ffd898f5 Update triangulation to handle poly-intersection
Polygon intersections happen against the original outline, not against
the currently remaining polygon.  This avoids pathalogical cases

Adds new simplification system to avoid duplicated points
Adds new edge-splitting algorithm to provide additional fall-back
Verifies that polygon cuts do not swap holes for outlines (negative
area)

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

(cherry picked from commit c3f6a84d66)
2024-03-28 13:55:06 -07:00
Céleste Wouters 76e0f94532 Improve SHAPE_POLY_SET fracture performance
Refactors `SHAPE_POLY_SET::fractureSingle()` to be more efficient, while
not changing the actual algorithm:

* increase cache locality by using contiguous arrays instead of what was
effectively a linked list
* reduce latency and jitter by replacing per-edge allocator calls with
ahead-of-time std::vector reserves
* increase cache efficiency by making the vertex struct smaller
* replace O(n^2) leftmost edge search with O(n log n) std::sort
* sort the polygons instead of the edges
* cut iteration count in half in the remaining O(polygons * edges) part

(cherry picked from commit e98c9f283f)
2024-03-28 13:10:43 -07:00
Seth Hillbrand ff2d0cfb10 Fix typo in triangulation return
(cherry picked from commit a793fa8b17)
2024-03-28 13:10:43 -07:00
Seth Hillbrand 1cc10be443 Skip small triangles
The minor triangles cost the same amount of compute time as larger ones
but do not have a material effect on the zone display.  This skips these
minor triangles when earcutting

(cherry picked from commit a58e7b37ff)
2024-03-28 13:10:43 -07:00
Seth Hillbrand d2db96886d Add logging and area check to tesselation
Logging is useful when we find an area that cannot be triangulated.
This will be used to generated test cases.

Skipping minor untesselated areas means that the polygon will still be
considered fully tesselated (and not sent back again and again) even if
the tesselation misses an area less than the configured limit.
Currently, this is 31^2nm.

(cherry picked from commit 7e7fec69f6)
2024-03-28 13:10:43 -07:00
Seth Hillbrand 3d4a7c7c3f Update triangulation
(cherry picked from commit 4f03bb2fb6)
2024-03-28 13:10:43 -07:00
arturo182 d46139d5e3 kicad_advanced: Make OCE tesselation deflection configurable
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17168

(cherry picked from commit 41147dc3b3)
2024-03-28 13:10:43 -07:00
Seth Hillbrand 40f938dc75 Sort netnames in properties panel
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15590

(cherry picked from commit c3a5b92ed0)
2024-03-28 13:06:18 -07:00
JamesJ 30dbafaf7c Use bulk BOARD_LISTENER calls following undo or redo operations
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17561
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17420

(cherry picked from commit f51e775f26)
2024-03-24 19:39:25 +00:00
Alex Shvartzkop 05dedbd892 Fix spelling mistake.
(cherry picked from commit bd59fb7768)
2024-03-23 18:43:47 +00:00
Alex Shvartzkop c0dba1e00d Don't print unnecessary digits after decimal point for imperial units.
1 nm = 0.00003937 mils = 0.00000003937 inches,
So there's no reason to print more decimal places than 5 for mils and 8 for inches.

Related: https://gitlab.com/kicad/code/kicad/-/issues/15539


(cherry picked from commit 93581607a8)
2024-03-23 18:40:11 +00:00
JamesJ cc3e57b52f Don't re-highlight nets on every bulk segment change in net inspector
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17068
2024-03-23 15:35:21 +00:00
Alex Shvartzkop 70a6697c16 Fix warning due to unused angle in EasyEDA Pro schematic parser.
(cherry picked from commit 1c7e3871b5)
2024-03-23 14:52:05 +00:00
wh201906 869f30e291 Add toggleHV45Mode item to the measure tool's context menu
The behavior of the measure tool is influenced by the
horizontal/vertical/45-degree mode, but the context menu of the measure
tool lacks an option to toggle this mode. In contrast, the drawing
tools are also affected by this mode, and their context menu has the
item to toggle this mode.


(cherry picked from commit 806daecf85)
2024-03-23 13:33:32 +00:00
Jeff Young 4c78652690 Ignore graphic shapes that implement netties.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17223


(cherry picked from commit 88c1fa3e26)
2024-03-23 13:19:37 +00:00
jean-pierre charras afcda88ee3 GERBER_JOBFILE_WRITER: use UTF8 encoding according to current specif.
Since 2020, non ASCII7 chars are encoded using UTF8 encoding.
A old but incorrect encoding was previously used.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17534
2024-03-22 10:09:47 +01:00
dsa-t 605fe4ce99 Disallow cross-probing when not on Symbol Fields Table Edit tab.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17531


(cherry picked from commit db12f2af49)

ce625541 Disallow cross-probing when not on Symbol Fields Table Edit tab.
2024-03-21 19:09:34 +00:00
Jeff Young a3ee317277 Fix copy/pasta in tooltips.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17515

(cherry picked from commit 913e6b47d7)
2024-03-21 18:19:48 +00:00
Jeff Young f7bce264bb Don't take too long worrying about very small exposed areas.
(And in particular, don't take forever if the min / 10 results
in step being 0.)

(cherry picked from commit b285545aee)
2024-03-21 18:19:48 +00:00
jean-pierre charras dfe6cb7afa Do not run DRAWING_TOOL::PlaceTuningPattern() inside the footprint editor
The footprint editor cannot run the router.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17522
2024-03-21 15:22:13 +01:00
jean-pierre charras 8bdc62c111 Avoid using a nullptr. 2024-03-20 18:35:26 +01:00
Alex Shvartzkop 350687f355 STEP export: add location info to edge add failures.
(cherry picked from commit 800ff9ffb1)
2024-03-19 23:11:20 +03:00
Alex Shvartzkop 3a5a911012 STEP export: handle small segments connecting two arcs better.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17499

(cherry picked from commit 75037dd1d1)
2024-03-19 22:55:17 +03:00
Roberto Fernandez Bautista b40d19eb79 nanodbc: Fix use after free
Cherry picked from upstream commit e24383436703c9151af1e22652e7d4dbbb52fc15

https://github.com/nanodbc/nanodbc/commit/e24383436703c9151af1e22652e7d4dbbb52fc15
(cherry picked from commit 69107816f1)
2024-03-19 18:56:43 +01:00
jean-pierre charras 3e4ca3a1c7 Step exporter: workaround to fix issue for boards with main round outline
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17446
2024-03-19 16:13:13 +01:00
Mark Roszko 663918107e Add missing text var override to cli gerbers
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17283

(cherry picked from commit d904535a15)
2024-03-19 14:35:30 +00:00
Mike Williams 1ac1f0445f prettifier: add newlines to golden samples 2024-03-19 09:46:42 -04:00
Mike Williams bce982877c prettifier: add newline to end of file
Fixes: https://gitlab.com/kicad/code/kicad/-/issues/17480
2024-03-19 09:46:42 -04:00
Jeff Young 9704543b7a Don't assume all glyphs are outline with an outline font.
Underline and overbar may be stroke glyphs.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17478
2024-03-18 22:20:44 +00:00
jean-pierre charras f90c3ef075 hotkey selector dialog: accept hotkey using Alt key modifier on Windows.
On Windows, Alt key is specific, and the dialog did not accept the modifier

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17453
2024-03-18 18:19:39 +01:00
wh201906 11177bf658 Fix selected item count in the properties panel
The code for updating selected item count is skipped if the properties
items don't change.


(cherry picked from commit 3f2e3d89e2)
2024-03-17 22:27:05 +00:00
Jeff Young 81f55dfc9c Fix layer swapping for multi-layer items.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17371

(cherry picked from commit 44c14b1935)
2024-03-17 12:40:58 +00:00
Roberto Fernandez Bautista c935ef890a Database library cache: fix memory leak
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17435

(cherry picked from commit 4851b0f1ac)
2024-03-17 11:41:46 +01:00
jean-pierre charras 71af5b106a Demos update 2024-03-16 14:55:47 +01:00
jean-pierre charras d24012bef5 Revert "Demos update."
This reverts commit b4131f2575.
Files from 8.99 were committed by mistake
2024-03-16 14:55:47 +01:00
Wayne Stambaugh e904731e28 Do not update schematic connectivity for irrelevant property changes.
Prior to this change, the schematic connectivity was updated any time a
change was made to a connectable object.  Now the connectivity is only
updated when an object change actually affects the connectivity.  Other
properties like line width, fill type, custom fonts, etc. will not cause
the connectivity graph to be rebuilt.

The SCH_COMMIT flag SKIP_CONNECTIVITY has been removed.  All schematic
objects can test if they are connectable and if there have been changes
to any connection properties that require a connectivity rebuild.

Remove duplicate rebuild connectivity calls from editor control tool.
This was causing the tangling end test to get called four times on every
undo and redo action because the dangling end test is already called in
the connectivity graph calculation code.

Update connectivity when changing label names which fixes an unreported
connectivity bug.

(cherry picked from commit c5a02fc266)
2024-03-16 09:36:56 -04:00
Mojca Miklavec dcd304c5d8 Change the platform detection order
Make sure that windows-specific getWindowsKiCadRoot() is only called on Windows


(cherry picked from commit 01cb1543bb)
2024-03-16 12:23:04 +00:00
Jeff Young 8275176792 Report location of FUTURE_FORMAT_ERRORs when reading footprints. 2024-03-15 22:47:00 +00:00
Jeff Young 8589bd3773 Correctly handle locked token for PCB_TEXTBOX and PCB_TABLECELL.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17439

(cherry picked from commit d17151ac1b)
2024-03-15 22:24:53 +00:00
Jeff Young c07604bb03 Add autocomplete accept & cancel to the hotkeys list.
(cherry picked from commit da2610b93b)
2024-03-15 22:24:53 +00:00
jean-pierre charras b4131f2575 Demos update. 2024-03-15 15:41:16 +01:00
jean-pierre charras b718c228fe Symbol Editor: do not allow to select fully invisible pins and fields
Of course, invisible pins or fields shown by using option Show invisible
pins or Show invisible fields can be selected.
From master branch
2024-03-15 15:03:38 +01:00
jean-pierre charras 3d04d78f76 Symbol Editor do not display bounding box of invisible pins and fields 2024-03-15 15:03:38 +01:00
Yon Uriarte 6ebccdecc6 Responsive: Avoid excessive repaints when toggling a netclass' rastnest visibility.
Toggling netclasses visibility toggles the member nets' visibility one by one. Defer redrawing until all toggling is done.

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

(cherry picked from commit 4e8e14ae3a)
2024-03-15 09:45:09 -04:00
Yon Uriarte 4e8d6de1de Responsive: OPENGL_GAL::DrawArc reserve linequads to reduce drawing time
(cherry picked from commit 77576e1a80)
2024-03-15 09:45:09 -04:00
Yon Uriarte 8b281b4d1c Performance: Cache BOARD::GetMaxClearanceValue
(cherry picked from commit fe1c73ed7c)

1b35a512  Performance
2024-03-15 13:34:19 +00:00
Wayne Stambaugh 8ce12fb1af Fix Eagle footprint library QA test failure.
Unfortunately the KiCad library I/O does not unescape file names so do not
escape them in the Eagle board plugin.

(cherry picked from commit cf97432833)
2024-03-15 07:59:20 -04:00
Wayne Stambaugh 9e4efe5d72 Fix Eagle board import when footprint library versions exist.
This was a crude hack that appends the library URN ordinal to the name of
the footprint so that it can be correctly looked up by the "element" node.
The Eagle XML DTD does not make it clear how the URN "ASSET_ID" and
"VERSION" are used to look up the appropriate "ASSET_TYPE" so this is a
best guess and seems to work correctly.

The inferred edge clearance dialog had to be disabled when importing third
party boards because on GTK (and possibly other platforms) the dialog would
completely hang KiCad preventing the imported board and possible schematic
from being saved.

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

(cherry picked from commit 34ec57958d)
2024-03-15 07:59:20 -04:00
Wayne Stambaugh ab6c64b49a Clean up debugging output accidentally left in previous commit.
(cherry picked from commit 33566f88a9)
2024-03-15 07:59:20 -04:00
Wayne Stambaugh dd71173263 Fix broken paste special keep existing symbol annotations.
This was only broken for symbols on the sheet where the symbols were
copied from.  The symbol annotation for all sub-sheets was preserved.

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

(cherry picked from commit 0ff8d21459)
2024-03-15 07:59:20 -04:00
Alex Shvartzkop 89ed09744b Fix a crash in PNS zone sync when there's more outlines than triangulated polygons.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17351

(cherry picked from commit b56ee20e22)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop ddec1d5317 Disable infinite panning when using XWayland.
Cursor warping doesn't work properly in this scenario.

https://gitlab.com/kicad/code/kicad/-/issues/14109
(cherry picked from commit 463b609993)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop 50dd6185bb Do not write alpha to the main framebuffer when performing antialiasing.
This allows correct background display when the main framebuffer has alpha.
Noticeable on Wayland with Mesa 24.0.2 Iris driver.

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

(cherry picked from commit bf6ff5b805)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop 6df17bba99 Fix rendering/plotting of arcs with tiny angle and huge radius.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17343

(cherry picked from commit 4d66a8ebdb)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop ed89827908 Fix zone cross-probing from DRC dialog.
(cherry picked from commit aa68a3817a)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop b61f6c35c7 Fabmaster (CADENCE ASCII): import dimensions graphics.
See https://gitlab.com/kicad/code/kicad/-/issues/17239

(cherry picked from commit a4da829ccc)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop f9253485da Fabmaster (CADENCE ASCII) import: fix position and orientation of footprint graphics.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17239

(cherry picked from commit cb4ace5561)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop 7dc554ec34 EasyEDA Std: fix importing footprints from footprint editor.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17264

(cherry picked from commit 30573beb48)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop c7608c4bad EasyEDA Std: support multiple schematic sheets.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17219

(cherry picked from commit c056ef407a)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop 10ca34e2a7 EasyEDA Std: support Dot and Clock symbol pin styles.
(cherry picked from commit cc181df916)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop e4fc918b11 EasyEDA Std: hide invisible text in symbols.
(cherry picked from commit 69b15e83c5)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop c1a21c9ab1 EasyEDA Pro schematic: place items on root sheet when it's the only sheet.
(cherry picked from commit 563278d0f6)
2024-03-15 01:17:50 +03:00
Alex Shvartzkop 4ac848f18a EasyEDA Std PCB: fix crash when Name/Prefix type text is not in a footprint.
(cherry picked from commit 951c550c1e)
2024-03-15 01:17:49 +03:00
Alex Shvartzkop 46faa0f678 Fix assert in BOARD_ADAPTER::createLayers.
(cherry picked from commit f9ad0a434d)
2024-03-15 01:17:49 +03:00
Alex Shvartzkop 4072bc05af Define __cplusplus according to C++ standard version on MSVC.
Otherwise, macros like KI_FALLTHROUGH are not defined properly.

(cherry picked from commit fa6dc95553)
2024-03-15 01:17:49 +03:00
Alex Shvartzkop e196f71d58 Support Altium Schematic ASCII import
(cherry picked from commit defcb49ac8)
2024-03-15 01:17:49 +03:00
Jon Evans b9d3b571bc Allow specifying a minimum for a via_count constraint
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17234


(cherry picked from commit 3a3ceb8ffc)
2024-03-14 21:01:30 +00:00
Jon Evans 816e3efbd5 Fix a few LIB_TREE search issues
Don't apply pruning to libraries that don't have
any children, since the point of the pruning is to
hide libraries that don't directly match a search
term if they don't have any children that match.

Fix searching for full LIB_IDs that got broken by
the implementation of "AND"

Fix searching for library names alone

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


(cherry picked from commit 0c2a084a47)
2024-03-14 21:01:13 +00:00
Jon Evans 8afbe544a3 Set description on Altium imported symbols
Fixes https://gitlab.com/kicad/code/kicad/-/issues/16943


(cherry picked from commit 4bc69183ab)
2024-03-14 21:00:58 +00:00
Jon Evans c7b7830495 Add environment variable for configuring stock data home
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15687


(cherry picked from commit 9b54537e38)
2024-03-14 21:00:40 +00:00
Jeff Young af3654d389 Reset penWidth before stroking.
(PlotPoly will have set it to "1".)

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

(cherry picked from commit f22f5f47cb)
2024-03-14 18:07:53 +00:00
Jeff Young 838cefaf48 Default is a valid netclass, even if it's not in m_NetClasses.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17388

(cherry picked from commit dac16a02cc)
2024-03-14 18:07:48 +00:00
Jeff Young 4dca966c5d Don't test non-overlapping non-through-hole vias.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17426

(cherry picked from commit a091767551)
2024-03-14 18:07:28 +00:00
Jeff Young 2609882346 Update m_LastLegendPosition after setting dirty bit.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17411

(cherry picked from commit 7341d4bf37)
2024-03-14 18:07:07 +00:00
Jeff Young 36fc9191b9 Remove netclass/custom rule handling from Track & Via Properties.
(These should be done in Edit > Edit Track & Via Properties.)

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

(cherry picked from commit 4b6a1f4dbd)
2024-03-14 18:06:44 +00:00
Jeff Young 4583522ea2 Make Edit Track & Via Sizes "specified sizes" dropdowns clearer.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17216

(cherry picked from commit 1844bf1708)
2024-03-14 18:06:41 +00:00
Jeff Young f0e2adc3df Don't allow selection of footprint text in board editor.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17271

(cherry picked from commit 25e181db5c)
2024-03-14 18:06:11 +00:00
Jeff Young 091b34c05f Don't show normal cut/copy/paste items in Signals grid.
(Do allow a copy of signal names though.)

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

(cherry picked from commit ed61c5593f)
2024-03-14 18:05:47 +00:00
Jeff Young 09bc9cd77a Grid properties for GerbView.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17372

(cherry picked from commit 1152b0462c)
2024-03-14 18:05:18 +00:00
Jeff Young e893ed4590 Pass symbol's netlist to footprint preview widget.
This allows us to show the pin functions on the corresponding
pads.

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

(cherry picked from commit 72ba31ba27)
2024-03-14 18:04:52 +00:00
Jeff Young c0ad519e53 Run Edge.Cuts & Margin clearance tests on zone layer.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17292

(cherry picked from commit d1d9636598)
2024-03-14 18:04:06 +00:00
Jeff Young 03af8dcc88 Convert OP text variables pin names/numbers to SPICE vectors.
Also fixes a wrap-around bug in SPICE_VALUE::Normalize() where
it would lose the run of itself if the value was already
normalized to either the largest or smallest UNIT_PREFIX.

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

(cherry picked from commit ff8ddae9bd)
2024-03-14 18:03:42 +00:00
Jeff Young 45e17307a1 Resolve double-indirection CURRENT_DATE in title blocks.
If ${COMMENT1} resolves to ${CURRENT_DATE} then we need to resolve again.

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

(cherry picked from commit da634a618f)
2024-03-14 18:02:50 +00:00
Wayne Stambaugh 357226eb71 Begin version 8.0.2 development. 2024-03-13 11:58:22 -04:00
394 changed files with 93746 additions and 78173 deletions
+15 -10
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2015-2023 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 2023 CERN
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-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
@@ -142,8 +142,8 @@ BOARD_ADAPTER::BOARD_ADAPTER() :
m_offboardPadsFront = nullptr;
m_offboardPadsBack = nullptr;
m_frontPlatedPadPolys = nullptr;
m_backPlatedPadPolys = nullptr;
m_frontPlatedPadAndGraphicPolys = nullptr;
m_backPlatedPadAndGraphicPolys = nullptr;
m_frontPlatedCopperPolys = nullptr;
m_backPlatedCopperPolys = nullptr;
@@ -397,13 +397,18 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
break;
case BS_ITEM_TYPE_COPPER:
if( item->GetBrdLayerId() == F_Cu )
m_frontCopperThickness3DU = item->GetThickness() * m_biuTo3Dunits;
else if( item->GetBrdLayerId() == B_Cu )
m_backCopperThickness3DU = item->GetThickness() * m_biuTo3Dunits;
else if( item->IsEnabled() )
thickness += item->GetThickness();
{
// The copper thickness must be > 0 to avoid draw issues (divide by 0 for instance)
// We use a minimal arbitrary value = 1 micrometer here:
int copper_thickness = std::max( item->GetThickness(), pcbIUScale.mmToIU( 0.001 ) );
if( item->GetBrdLayerId() == F_Cu )
m_frontCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
else if( item->GetBrdLayerId() == B_Cu )
m_backCopperThickness3DU = copper_thickness * m_biuTo3Dunits;
else if( item->IsEnabled() )
thickness += copper_thickness;
}
break;
default:
@@ -449,7 +454,7 @@ void BOARD_ADAPTER::InitSettings( REPORTER* aStatusReporter, REPORTER* aWarningR
for( ; layer < MAX_CU_LAYERS; layer++ )
{
m_layerZcoordBottom[layer] = -( m_boardBodyThickness3DU / 2.0f );
m_layerZcoordTop[layer] = -( m_boardBodyThickness3DU / 2.0f ) - m_backCopperThickness3DU;
m_layerZcoordTop[layer] = m_layerZcoordBottom[layer] - m_backCopperThickness3DU;
}
// This is the top of the copper layer thickness.
+4 -4
View File
@@ -331,8 +331,8 @@ public:
*/
const MAP_POLY& GetPolyMap() const noexcept { return m_layers_poly; }
const SHAPE_POLY_SET* GetFrontPlatedPadPolys() { return m_frontPlatedPadPolys; }
const SHAPE_POLY_SET* GetBackPlatedPadPolys() { return m_backPlatedPadPolys; }
const SHAPE_POLY_SET* GetFrontPlatedPadAndGraphicPolys() { return m_frontPlatedPadAndGraphicPolys; }
const SHAPE_POLY_SET* GetBackPlatedPadAndGraphicPolys() { return m_backPlatedPadAndGraphicPolys; }
const MAP_POLY& GetHoleIdPolysMap() const noexcept { return m_layerHoleIdPolys; }
const MAP_POLY& GetHoleOdPolysMap() const noexcept { return m_layerHoleOdPolys; }
@@ -438,8 +438,8 @@ private:
MAP_POLY m_layers_poly; ///< Amalgamated polygon contours for various types
///< of items
SHAPE_POLY_SET* m_frontPlatedPadPolys;
SHAPE_POLY_SET* m_backPlatedPadPolys;
SHAPE_POLY_SET* m_frontPlatedPadAndGraphicPolys;
SHAPE_POLY_SET* m_backPlatedPadAndGraphicPolys;
SHAPE_POLY_SET* m_frontPlatedCopperPolys;
SHAPE_POLY_SET* m_backPlatedCopperPolys;
+24 -11
View File
@@ -117,8 +117,8 @@ void BOARD_ADAPTER::destroyLayers()
DELETE_AND_FREE_MAP( m_layers_poly );
DELETE_AND_FREE( m_frontPlatedPadPolys )
DELETE_AND_FREE( m_backPlatedPadPolys )
DELETE_AND_FREE( m_frontPlatedPadAndGraphicPolys )
DELETE_AND_FREE( m_backPlatedPadAndGraphicPolys )
DELETE_AND_FREE( m_frontPlatedCopperPolys )
DELETE_AND_FREE( m_backPlatedCopperPolys )
@@ -241,8 +241,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
if( cfg.differentiate_plated_copper )
{
m_frontPlatedPadPolys = new SHAPE_POLY_SET;
m_backPlatedPadPolys = new SHAPE_POLY_SET;
m_frontPlatedPadAndGraphicPolys = new SHAPE_POLY_SET;
m_backPlatedPadAndGraphicPolys = new SHAPE_POLY_SET;
m_frontPlatedCopperPolys = new SHAPE_POLY_SET;
m_backPlatedCopperPolys = new SHAPE_POLY_SET;
@@ -586,10 +586,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
// ADD PLATED PADS contours
for( FOOTPRINT* footprint : m_board->Footprints() )
{
footprint->TransformPadsToPolySet( *m_frontPlatedPadPolys, F_Cu, 0, maxError,
footprint->TransformPadsToPolySet( *m_frontPlatedPadAndGraphicPolys, F_Cu, 0, maxError,
ERROR_INSIDE, true, false, true );
footprint->TransformPadsToPolySet( *m_backPlatedPadPolys, B_Cu, 0, maxError,
footprint->TransformPadsToPolySet( *m_backPlatedPadAndGraphicPolys, B_Cu, 0, maxError,
ERROR_INSIDE, true, false, true );
}
}
@@ -1050,21 +1050,33 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
SHAPE_POLY_SET::PM_FAST );
}
// SUBTRACT PLATED COPPER FROM (UNPLATED) COPPER
// Subtract plated copper from unplated copper
bool hasF_Cu = false;
bool hasB_Cu = false;
if( m_layers_poly.find( F_Cu ) != m_layers_poly.end() )
{
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadPolys, SHAPE_POLY_SET::PM_FAST );
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedPadAndGraphicPolys, SHAPE_POLY_SET::PM_FAST );
m_layers_poly[F_Cu]->BooleanSubtract( *m_frontPlatedCopperPolys, SHAPE_POLY_SET::PM_FAST );
hasF_Cu = true;
}
if( m_layers_poly.find( B_Cu ) != m_layers_poly.end() )
{
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedPadPolys, SHAPE_POLY_SET::PM_FAST );
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedPadAndGraphicPolys, SHAPE_POLY_SET::PM_FAST );
m_layers_poly[B_Cu]->BooleanSubtract( *m_backPlatedCopperPolys, SHAPE_POLY_SET::PM_FAST );
hasB_Cu = true;
}
m_frontPlatedPadPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
m_backPlatedPadPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
// Add plated graphic items to build vertical walls
if( hasF_Cu && m_frontPlatedCopperPolys->OutlineCount() )
m_frontPlatedPadAndGraphicPolys->Append( *m_frontPlatedCopperPolys );
if( hasB_Cu && m_backPlatedCopperPolys->OutlineCount() )
m_backPlatedPadAndGraphicPolys->Append( *m_backPlatedCopperPolys );
m_frontPlatedPadAndGraphicPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
m_backPlatedPadAndGraphicPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
m_frontPlatedCopperPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
m_backPlatedCopperPolys->Simplify( SHAPE_POLY_SET::PM_FAST );
@@ -1134,6 +1146,7 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
if( layerPoly != m_layers_poly.end() )
{
// This will make a union of all added contours
layerPoly->second->ClearArcs();
layerPoly->second->Simplify( SHAPE_POLY_SET::PM_FAST );
}
}
+11 -6
View File
@@ -613,12 +613,12 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
if( m_boardAdapter.m_Cfg->m_Render.differentiate_plated_copper )
{
const SHAPE_POLY_SET* frontPlatedPadPolys = m_boardAdapter.GetFrontPlatedPadPolys();
const SHAPE_POLY_SET* backPlatedPadPolys = m_boardAdapter.GetBackPlatedPadPolys();
const SHAPE_POLY_SET* frontPlatedPadAndGraphicPolys = m_boardAdapter.GetFrontPlatedPadAndGraphicPolys();
const SHAPE_POLY_SET* backPlatedPadAndGraphicPolys = m_boardAdapter.GetBackPlatedPadAndGraphicPolys();
if( frontPlatedPadPolys )
if( frontPlatedPadAndGraphicPolys )
{
SHAPE_POLY_SET poly = frontPlatedPadPolys->CloneDropTriangulation();
SHAPE_POLY_SET poly = frontPlatedPadAndGraphicPolys->CloneDropTriangulation();
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
@@ -630,9 +630,9 @@ void RENDER_3D_OPENGL::reload( REPORTER* aStatusReporter, REPORTER* aWarningRepo
m_layers[F_Cu] = generateEmptyLayerList( F_Cu );
}
if( backPlatedPadPolys )
if( backPlatedPadAndGraphicPolys )
{
SHAPE_POLY_SET poly = backPlatedPadPolys->CloneDropTriangulation();
SHAPE_POLY_SET poly = backPlatedPadAndGraphicPolys->CloneDropTriangulation();
poly.BooleanIntersection( m_boardAdapter.GetBoardPoly(), SHAPE_POLY_SET::PM_FAST );
poly.BooleanSubtract( m_boardAdapter.GetTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
poly.BooleanSubtract( m_boardAdapter.GetNPTH_ODPolys(), SHAPE_POLY_SET::PM_FAST );
@@ -917,6 +917,10 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
if( !m_boardAdapter.GetBoard() )
return;
// Building the 3D models late crashes on recent versions of macOS
// Unclear the exact mechanism, but as a workaround, just build them
// all the time. See https://gitlab.com/kicad/code/kicad/-/issues/17198
#ifndef __WXMAC__
if( !m_boardAdapter.m_IsPreviewer
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_normal
&& !m_boardAdapter.m_Cfg->m_Render.show_footprints_insert
@@ -924,6 +928,7 @@ void RENDER_3D_OPENGL::load3dModels( REPORTER* aStatusReporter )
{
return;
}
#endif
// Go for all footprints
for( const FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() )
+15 -2
View File
@@ -83,6 +83,13 @@ const APPEARANCE_CONTROLS_3D::APPEARANCE_SETTING_3D APPEARANCE_CONTROLS_3D::s_la
RR( _HKI( "Background End" ), LAYER_3D_BACKGROUND_BOTTOM, _HKI( "Background gradient end color" ) ),
};
// The list of IDs that can have colors coming from the board stackup, and cannot be
// modified if use colors from stackup is activated
static std::vector<int> inStackupColors{ LAYER_3D_BOARD, LAYER_3D_COPPER_TOP,
LAYER_3D_COPPER_BOTTOM, LAYER_3D_SOLDERPASTE,
LAYER_3D_SILKSCREEN_TOP, LAYER_3D_SILKSCREEN_BOTTOM,
LAYER_3D_SOLDERMASK_TOP, LAYER_3D_SOLDERMASK_BOTTOM
};
APPEARANCE_CONTROLS_3D::APPEARANCE_CONTROLS_3D( EDA_3D_VIEWER_FRAME* aParent,
wxWindow* aFocusOwner ) :
@@ -568,8 +575,14 @@ void APPEARANCE_CONTROLS_3D::UpdateLayerCtls()
{
setting->m_Ctl_color->SetSwatchColor( colors[ setting->m_Id ], false );
if( cfg )
setting->m_Ctl_color->SetReadOnly( cfg->m_UseStackupColors );
// if cfg->m_UseStackupColors is set, board colors cannot be modified locally, but
// other colors can be
if( std::find( inStackupColors.begin(), inStackupColors.end(), setting->m_Id )
!= inStackupColors.end() )
{
if( cfg )
setting->m_Ctl_color->SetReadOnly( cfg->m_UseStackupColors );
}
}
}
+2
View File
@@ -514,6 +514,8 @@ if( MSVC )
string( APPEND CMAKE_CXX_FLAGS " /wd4800" )
# /Zi: create PDB
string( APPEND CMAKE_CXX_FLAGS " /Zi" )
# /Zc:__cplusplus: define this macro according to C++ standard version
string( APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus" )
# /GF: enable string pooling
string( APPEND CMAKE_CXX_FLAGS_RELEASE " /GF" )
string( APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " /GF" )
+39 -19
View File
@@ -27,7 +27,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Set the needed libraries
set( OCC_LIBS
set( OCC_LIBS_COMMON
TKBinL
TKBin
TKBinTObj
@@ -45,7 +45,6 @@ set( OCC_LIBS
TKGeomAlgo
TKGeomBase
TKHLR
TKIGES
TKLCAF
TKMath
TKMesh
@@ -56,18 +55,10 @@ set( OCC_LIBS
TKRWMesh
TKService
TKShHealing
TKSTEP209
TKSTEPAttr
TKSTEPBase
TKSTEP
TKSTL
TKTObj
TKTopAlgo
TKV3d
TKVRML
TKXCAF
TKXDEIGES
TKXDESTEP
TKXMesh
TKXmlL
TKXml
@@ -76,6 +67,27 @@ set( OCC_LIBS
TKXSBase
)
# Libraries valid pre-7.8.0
set( OCC_LIBS_PRE_78
TKIGES
TKSTEP209
TKSTEPAttr
TKSTEPBase
TKSTEP
TKSTL
TKVRML
TKXDEIGES
TKXDESTEP
)
# Libraries for versions >= 7.8.0
set( OCC_LIBS_POST_78
TKDEIGES
TKDEGLTF
TKDESTEP
TKDESTL
)
set(OCC_TYPE "OpenCASCADE Standard Edition")
if(WIN32)
if(CYGWIN OR MINGW)
@@ -178,9 +190,8 @@ endif(OCC_INCLUDE_DIR AND NOT ${OCC_INCLUDE_DIR} STREQUAL "OCC_INCLUDE_DIR-NOTFO
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OCC REQUIRED_VARS OCC_INCLUDE_DIR VERSION_VAR OCC_VERSION_STRING)
if(OCC_FOUND)
foreach(lib IN LISTS OCC_LIBS)
macro(occ_lib_search SEARCH_LIST)
foreach(lib IN LISTS ${SEARCH_LIST})
#Use the specified library location if given
find_library(OCC_TEMP_LIB ${lib} HINTS ${OCC_LIBRARY_DIR} NO_DEFAULT_PATH)
if(${OCC_TEMP_LIB} STREQUAL "OCC_TEMP_LIB-NOTFOUND")
@@ -197,11 +208,20 @@ if(OCC_FOUND)
unset(OCC_TEMP_LIB CACHE)
endforeach(lib)
endmacro()
#Convert path names to absolute for cleaner display
get_filename_component(OCC_INCLUDE_DIR "${OCC_INCLUDE_DIR}" ABSOLUTE)
get_filename_component(OCC_LIBRARY_DIR "${OCC_LIBRARY_DIR}" ABSOLUTE)
message(STATUS "Found ${OCC_TYPE} version: ${OCC_VERSION_STRING}")
message(STATUS " ++ ${OCC_TYPE} include directory: ${OCC_INCLUDE_DIR}")
message(STATUS " ++ ${OCC_TYPE} shared libraries directory: ${OCC_LIBRARY_DIR}")
if(OCC_FOUND)
occ_lib_search( OCC_LIBS_COMMON )
if(OCC_VERSION_STRING VERSION_LESS "7.8.0")
occ_lib_search( OCC_LIBS_PRE_78 )
else()
occ_lib_search( OCC_LIBS_POST_78 )
endif()
#Convert path names to absolute for cleaner display
get_filename_component(OCC_INCLUDE_DIR "${OCC_INCLUDE_DIR}" ABSOLUTE)
get_filename_component(OCC_LIBRARY_DIR "${OCC_LIBRARY_DIR}" ABSOLUTE)
message(STATUS "Found ${OCC_TYPE} version: ${OCC_VERSION_STRING}")
message(STATUS " ++ ${OCC_TYPE} include directory: ${OCC_INCLUDE_DIR}")
message(STATUS " ++ ${OCC_TYPE} shared libraries directory: ${OCC_LIBRARY_DIR}")
endif(OCC_FOUND)
+1 -1
View File
@@ -37,7 +37,7 @@
# KiCad.
#
# Note: This version string should follow the semantic versioning system
set( KICAD_SEMANTIC_VERSION "8.0.1" )
set( KICAD_SEMANTIC_VERSION "8.0.2" )
# Default the version to the semantic version.
# This is overridden by the git repository tag though (if using git)
+3 -1
View File
@@ -388,8 +388,10 @@ set( COMMON_IO_SRCS
io/io_utils.cpp
# Altium
io/altium/altium_parser.cpp
io/altium/altium_binary_parser.cpp
io/altium/altium_ascii_parser.cpp
io/altium/altium_parser_utils.cpp
io/altium/altium_props_utils.cpp
# Cadstar
io/cadstar/cadstar_archive_parser.cpp
+33
View File
@@ -104,6 +104,11 @@ static const wxChar EnableEeschemaPrintCairo[] = wxT( "EnableEeschemaPrintCairo"
static const wxChar DisambiguationTime[] = wxT( "DisambiguationTime" );
static const wxChar PcbSelectionVisibilityRatio[] = wxT( "PcbSelectionVisibilityRatio" );
static const wxChar MinimumSegmentLength[] = wxT( "MinimumSegmentLength" );
static const wxChar OcePluginLinearDeflection[] = wxT( "OcePluginLinearDeflection" );
static const wxChar OcePluginAngularDeflection[] = wxT( "OcePluginAngularDeflection" );
static const wxChar TriangulateSimplificationLevel[] = wxT( "TriangulateSimplificationLevel" );
static const wxChar TriangulateMinimumArea[] = wxT( "TriangulateMinimumArea" );
static const wxChar EnableCacheFriendlyFracture[] = wxT( "EnableCacheFriendlyFracture" );
} // namespace KEYS
@@ -248,6 +253,14 @@ ADVANCED_CFG::ADVANCED_CFG()
m_MinimumSegmentLength = 50;
m_OcePluginLinearDeflection = 0.14;
m_OcePluginAngularDeflection = 30;
m_TriangulateSimplificationLevel = 50;
m_TriangulateMinimumArea = 1000;
m_EnableCacheFriendlyFracture = true;
loadFromConfigFile();
}
@@ -444,6 +457,26 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
&m_MinimumSegmentLength,
m_MinimumSegmentLength, 10, 1000 ) );
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::OcePluginLinearDeflection,
&m_OcePluginLinearDeflection,
m_OcePluginLinearDeflection, 0.01, 1.0 ) );
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::OcePluginAngularDeflection,
&m_OcePluginAngularDeflection,
m_OcePluginAngularDeflection, 0.01, 360.0 ) );
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::TriangulateSimplificationLevel,
&m_TriangulateSimplificationLevel,
m_TriangulateSimplificationLevel, 0, 1000 ) );
configParams.push_back( new PARAM_CFG_INT( true, AC_KEYS::TriangulateMinimumArea,
&m_TriangulateMinimumArea,
m_TriangulateMinimumArea, 0, 100000 ) );
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::EnableCacheFriendlyFracture,
&m_EnableCacheFriendlyFracture,
m_EnableCacheFriendlyFracture ) );
// Special case for trace mask setting...we just grab them and set them immediately
// Because we even use wxLogTrace inside of advanced config
wxString traceMasks;
@@ -70,7 +70,11 @@ DIALOG_CONFIGURE_PATHS::DIALOG_CONFIGURE_PATHS( wxWindow* aParent ) :
m_EnvVars->ClearRows();
m_EnvVars->AppendCols( 1 ); // for the isExternal flags
m_EnvVars->HideCol( TV_FLAG_COL );
#ifndef __WXMAC__
// macos crashes on languages at least using non-ascii characters for the column header here of all places
// if we use native column headers, so guard it for windows to still look nice
m_EnvVars->UseNativeColHeader( true );
#endif
wxGridCellAttr* attr = new wxGridCellAttr;
attr->SetEditor( new GRID_CELL_PATH_EDITOR( this, m_EnvVars, &m_curdir, wxEmptyString ) );
+12
View File
@@ -71,6 +71,18 @@ PANEL_GRID_SETTINGS::PANEL_GRID_SETTINGS( wxWindow* aParent, UNITS_PROVIDER* aUn
m_checkGridOverrideWires->Show( false );
m_gridOverrideWiresChoice->Show( false );
}
if( m_frameType == FRAME_GERBER )
{
m_overridesLabel->Show( false );
m_staticline3->Show( false );
m_checkGridOverrideText->Show( false );
m_gridOverrideTextChoice->Show( false );
m_checkGridOverrideGraphics->Show( false );
m_gridOverrideGraphicsChoice->Show( false );
}
}
int hk1 = ACTIONS::gridFast1.GetHotKey();
+7 -7
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -111,7 +111,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
bSizerRightCol->Add( m_staticline3, 0, wxEXPAND|wxTOP|wxBOTTOM, 2 );
wxFlexGridSizer* fgGridOverrides;
fgGridOverrides = new wxFlexGridSizer( 0, 2, 4, 0 );
fgGridOverrides = new wxFlexGridSizer( 0, 2, 5, 0 );
fgGridOverrides->AddGrowableCol( 1 );
fgGridOverrides->SetFlexibleDirection( wxBOTH );
fgGridOverrides->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
@@ -122,7 +122,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
wxArrayString m_gridOverrideConnectedChoiceChoices;
m_gridOverrideConnectedChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridOverrideConnectedChoiceChoices, 0 );
m_gridOverrideConnectedChoice->SetSelection( 0 );
fgGridOverrides->Add( m_gridOverrideConnectedChoice, 0, wxALL, 5 );
fgGridOverrides->Add( m_gridOverrideConnectedChoice, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_checkGridOverrideWires = new wxCheckBox( this, wxID_ANY, _("Wires:"), wxDefaultPosition, wxDefaultSize, 0 );
fgGridOverrides->Add( m_checkGridOverrideWires, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxLEFT, 8 );
@@ -130,7 +130,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
wxArrayString m_gridOverrideWiresChoiceChoices;
m_gridOverrideWiresChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridOverrideWiresChoiceChoices, 0 );
m_gridOverrideWiresChoice->SetSelection( 0 );
fgGridOverrides->Add( m_gridOverrideWiresChoice, 0, wxALL, 5 );
fgGridOverrides->Add( m_gridOverrideWiresChoice, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_checkGridOverrideVias = new wxCheckBox( this, wxID_ANY, _("Vias:"), wxDefaultPosition, wxDefaultSize, 0 );
fgGridOverrides->Add( m_checkGridOverrideVias, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxLEFT, 8 );
@@ -138,7 +138,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
wxArrayString m_gridOverrideViasChoiceChoices;
m_gridOverrideViasChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridOverrideViasChoiceChoices, 0 );
m_gridOverrideViasChoice->SetSelection( 0 );
fgGridOverrides->Add( m_gridOverrideViasChoice, 0, wxALL, 5 );
fgGridOverrides->Add( m_gridOverrideViasChoice, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_checkGridOverrideText = new wxCheckBox( this, wxID_ANY, _("Text:"), wxDefaultPosition, wxDefaultSize, 0 );
fgGridOverrides->Add( m_checkGridOverrideText, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxLEFT, 8 );
@@ -146,7 +146,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
wxArrayString m_gridOverrideTextChoiceChoices;
m_gridOverrideTextChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridOverrideTextChoiceChoices, 0 );
m_gridOverrideTextChoice->SetSelection( 0 );
fgGridOverrides->Add( m_gridOverrideTextChoice, 0, wxALL, 5 );
fgGridOverrides->Add( m_gridOverrideTextChoice, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_checkGridOverrideGraphics = new wxCheckBox( this, wxID_ANY, _("Graphics:"), wxDefaultPosition, wxDefaultSize, 0 );
fgGridOverrides->Add( m_checkGridOverrideGraphics, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxLEFT, 8 );
@@ -154,7 +154,7 @@ PANEL_GRID_SETTINGS_BASE::PANEL_GRID_SETTINGS_BASE( wxWindow* parent, wxWindowID
wxArrayString m_gridOverrideGraphicsChoiceChoices;
m_gridOverrideGraphicsChoice = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridOverrideGraphicsChoiceChoices, 0 );
m_gridOverrideGraphicsChoice->SetSelection( 0 );
fgGridOverrides->Add( m_gridOverrideGraphicsChoice, 0, wxALL, 5 );
fgGridOverrides->Add( m_gridOverrideGraphicsChoice, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
bSizerRightCol->Add( fgGridOverrides, 0, wxEXPAND|wxTOP|wxBOTTOM|wxRIGHT, 10 );
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
+1
View File
@@ -1202,6 +1202,7 @@ void EDA_BASE_FRAME::ShowPreferences( wxString aStartPage, wxString aStartParent
book->AddPage( new wxPanel( book ), _( "Gerber Viewer" ) );
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_DISPLAY_OPTIONS ), _( "Display Options" ) );
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_COLORS ), _( "Colors" ) );
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_GRIDS ), _( "Grids" ) );
book->AddLazySubPage( LAZY_CTOR( PANEL_GBR_EXCELLON_OPTIONS ), _( "Excellon Options" ) );
}
catch( ... )
+29 -15
View File
@@ -1973,53 +1973,65 @@ static struct EDA_SHAPE_DESC
return false;
};
const wxString shapeProps = _HKI( "Shape Properties" );
auto shape = new PROPERTY_ENUM<EDA_SHAPE, SHAPE_T>( _HKI( "Shape" ),
NO_SETTER( EDA_SHAPE, SHAPE_T ), &EDA_SHAPE::GetShape );
propMgr.AddProperty( shape );
propMgr.AddProperty( shape, shapeProps );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Start X" ),
&EDA_SHAPE::SetStartX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_X_COORD ) )
ORIGIN_TRANSFORMS::ABS_X_COORD ),
shapeProps )
.SetAvailableFunc( isNotPolygonOrCircle );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Start Y" ),
&EDA_SHAPE::SetStartY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD ) )
ORIGIN_TRANSFORMS::ABS_Y_COORD ),
shapeProps )
.SetAvailableFunc( isNotPolygonOrCircle );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Center X" ),
&EDA_SHAPE::SetStartX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_X_COORD ) )
ORIGIN_TRANSFORMS::ABS_X_COORD ),
shapeProps )
.SetAvailableFunc( isCircle );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Center Y" ),
&EDA_SHAPE::SetStartY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD ) )
ORIGIN_TRANSFORMS::ABS_Y_COORD ),
shapeProps )
.SetAvailableFunc( isCircle );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Radius" ),
&EDA_SHAPE::SetRadius, &EDA_SHAPE::GetRadius, PROPERTY_DISPLAY::PT_SIZE,
ORIGIN_TRANSFORMS::NOT_A_COORD ) )
ORIGIN_TRANSFORMS::NOT_A_COORD ),
shapeProps )
.SetAvailableFunc( isCircle );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "End X" ),
&EDA_SHAPE::SetEndX, &EDA_SHAPE::GetEndX, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_X_COORD ) )
ORIGIN_TRANSFORMS::ABS_X_COORD ),
shapeProps )
.SetAvailableFunc( isNotPolygonOrCircle );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "End Y" ),
&EDA_SHAPE::SetEndY, &EDA_SHAPE::GetEndY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD ) )
ORIGIN_TRANSFORMS::ABS_Y_COORD ),
shapeProps )
.SetAvailableFunc( isNotPolygonOrCircle );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Line Width" ),
&EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
&EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::PT_SIZE ),
shapeProps );
void ( EDA_SHAPE::*lineStyleSetter )( LINE_STYLE ) = &EDA_SHAPE::SetLineStyle;
propMgr.AddProperty( new PROPERTY_ENUM<EDA_SHAPE, LINE_STYLE>(
_HKI( "Line Style" ), lineStyleSetter, &EDA_SHAPE::GetLineStyle ) );
propMgr.AddProperty( new PROPERTY_ENUM<EDA_SHAPE, LINE_STYLE>( _HKI( "Line Style" ),
lineStyleSetter, &EDA_SHAPE::GetLineStyle ),
shapeProps );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, COLOR4D>( _HKI( "Line Color" ),
&EDA_SHAPE::SetLineColor, &EDA_SHAPE::GetLineColor ) )
&EDA_SHAPE::SetLineColor, &EDA_SHAPE::GetLineColor ),
shapeProps )
.SetIsHiddenFromRulesEditor();
auto angle = new PROPERTY<EDA_SHAPE, EDA_ANGLE>( _HKI( "Angle" ),
@@ -2033,7 +2045,7 @@ static struct EDA_SHAPE_DESC
return false;
} );
propMgr.AddProperty( angle );
propMgr.AddProperty( angle, shapeProps );
auto fillAvailable =
[=]( INSPECTABLE* aItem ) -> bool
@@ -2056,11 +2068,13 @@ static struct EDA_SHAPE_DESC
};
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, bool>( _HKI( "Filled" ),
&EDA_SHAPE::SetFilled, &EDA_SHAPE::IsFilled ) )
&EDA_SHAPE::SetFilled, &EDA_SHAPE::IsFilled ),
shapeProps )
.SetAvailableFunc( fillAvailable );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, COLOR4D>( _HKI( "Fill Color" ),
&EDA_SHAPE::SetFillColor, &EDA_SHAPE::GetFillColor ) )
&EDA_SHAPE::SetFillColor, &EDA_SHAPE::GetFillColor ),
shapeProps )
.SetAvailableFunc( fillAvailable )
.SetIsHiddenFromRulesEditor();
}
+6 -6
View File
@@ -364,8 +364,8 @@ void EDA_TEXT::SetTextSize( VECTOR2I aNewSize, bool aEnforceMinTextSize )
if( aEnforceMinTextSize )
{
int min = m_IuScale.get().MilsToIU( TEXT_MIN_SIZE_MILS );
int max = m_IuScale.get().MilsToIU( TEXT_MAX_SIZE_MILS );
int min = m_IuScale.get().mmToIU( TEXT_MIN_SIZE_MM );
int max = m_IuScale.get().mmToIU( TEXT_MAX_SIZE_MM );
aNewSize = VECTOR2I( alg::clamp( min, aNewSize.x, max ),
alg::clamp( min, aNewSize.y, max ) );
@@ -380,8 +380,8 @@ void EDA_TEXT::SetTextSize( VECTOR2I aNewSize, bool aEnforceMinTextSize )
void EDA_TEXT::SetTextWidth( int aWidth )
{
int min = m_IuScale.get().MilsToIU( TEXT_MIN_SIZE_MILS );
int max = m_IuScale.get().MilsToIU( TEXT_MAX_SIZE_MILS );
int min = m_IuScale.get().mmToIU( TEXT_MIN_SIZE_MM );
int max = m_IuScale.get().mmToIU( TEXT_MAX_SIZE_MM );
m_attributes.m_Size.x = alg::clamp( min, aWidth, max );
ClearRenderCache();
@@ -391,8 +391,8 @@ void EDA_TEXT::SetTextWidth( int aWidth )
void EDA_TEXT::SetTextHeight( int aHeight )
{
int min = m_IuScale.get().MilsToIU( TEXT_MIN_SIZE_MILS );
int max = m_IuScale.get().MilsToIU( TEXT_MAX_SIZE_MILS );
int min = m_IuScale.get().mmToIU( TEXT_MIN_SIZE_MM );
int max = m_IuScale.get().mmToIU( TEXT_MAX_SIZE_MM );
m_attributes.m_Size.y = alg::clamp( min, aHeight, max );
ClearRenderCache();
+48 -15
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-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
@@ -28,6 +28,22 @@
#include <charconv>
#include <wx/translation.h>
static void removeTrailingZeros( wxString& aText )
{
int len = aText.length();
int removeLast = 0;
while( --len > 0 && aText[len] == '0' )
removeLast++;
if( len >= 0 && ( aText[len] == '.' || aText[len] == ',' ) )
removeLast++;
aText = aText.RemoveLast( removeLast );
}
bool EDA_UNIT_UTILS::IsImperialUnit( EDA_UNITS aUnit )
{
switch( aUnit )
@@ -305,29 +321,46 @@ wxString EDA_UNIT_UTILS::UI::StringFromValue( const EDA_IU_SCALE& aIuScale, EDA_
break;
}
char buf[50];
const wxChar* format = nullptr;
if( value_to_print != 0.0 && fabs( value_to_print ) <= 0.0001 )
switch( aUnits )
{
int len = snprintf( buf, sizeof( buf ) - 1, "%.10f", value_to_print );
while( --len > 0 && buf[len] == '0' )
buf[len] = '\0';
case EDA_UNITS::MILS:
#if defined( EESCHEMA )
format = wxT( "%.3f" );
#else
format = wxT( "%.5f" );
#endif
break;
if( len >= 0 && ( buf[len] == '.' || buf[len] == ',' ) )
buf[len] = '\0';
}
else
{
snprintf( buf, sizeof( buf ) - 1, "%.10g", value_to_print );
case EDA_UNITS::INCHES:
#if defined( EESCHEMA )
format = wxT( "%.6f" );
#else
format = wxT( "%.8f" );
#endif
break;
default:
format = wxT( "%.10f" );
break;
}
wxString stringValue( buf, wxConvUTF8 );
wxString text;
text.Printf( format, value_to_print );
removeTrailingZeros( text );
if( value_to_print != 0.0 && ( text == wxS( "0" ) || text == wxS( "-0" ) ) )
{
text.Printf( wxS( "%.10f" ), value_to_print );
removeTrailingZeros( text );
}
if( aAddUnitsText )
stringValue += EDA_UNIT_UTILS::GetText( aUnits, aType );
text << EDA_UNIT_UTILS::GetText( aUnits, aType );
return stringValue;
return text;
}
+6 -2
View File
@@ -59,7 +59,9 @@ void IO_ERROR::init( const wxString& aProblem, const char* aThrowersFile,
// a short filename will be printed (it is better for user, the full filename has no meaning).
wxString srcname = aThrowersFile;
where.Printf( _( "from %s : %s() line %d" ),
// No need for translations of source code file/line messages (and wxWidget's translation
// stuff has bitten us before. May be related to KICAD-YP.
where.Printf( wxS( "from %s : %s() line %d" ),
srcname.AfterLast( '/' ),
wxString( aThrowersFunction ),
aThrowersLineNumber );
@@ -87,7 +89,9 @@ void PARSE_ERROR::init( const wxString& aProblem, const char* aThrowersFile,
// a short filename will be printed (it is better for user, the full filename has no meaning).
wxString srcname = aThrowersFile;
where.Printf( _( "from %s : %s() line:%d" ),
// No need for translations of source code file/line messages (and wxWidget's translation
// stuff has bitten us before. May be related to KICAD-YP.
where.Printf( wxS( "from %s : %s() line %d" ),
srcname.AfterLast( '/' ),
wxString( aThrowersFunction ),
aThrowersLineNumber );
+15 -3
View File
@@ -82,19 +82,19 @@ std::unique_ptr<GLYPH> STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, cons
end.x *= aGlyphSize.x;
end.y *= aGlyphSize.y;
if( aTilt )
if( aTilt != 0.0 )
end.x -= end.y * aTilt;
glyph->m_boundingBox.SetEnd( end );
glyph->m_boundingBox.Offset( aOffset );
for( std::vector<VECTOR2D>& pointList : *glyph.get() )
for( std::vector<VECTOR2D>& pointList : *glyph )
{
for( VECTOR2D& point : pointList )
{
point *= aGlyphSize;
if( aTilt )
if( aTilt != 0.0 )
point.x -= point.y * aTilt;
point += aOffset;
@@ -111,6 +111,18 @@ std::unique_ptr<GLYPH> STROKE_GLYPH::Transform( const VECTOR2D& aGlyphSize, cons
}
void STROKE_GLYPH::Move( const VECTOR2I& aOffset )
{
m_boundingBox.Offset( aOffset );
for( std::vector<VECTOR2D>& pointList : *this )
{
for( VECTOR2D& point : pointList )
point += aOffset;
}
}
BOX2D OUTLINE_GLYPH::BoundingBox()
{
BOX2I bbox = BBox();
+3 -2
View File
@@ -327,8 +327,9 @@ const FP_LIB_TABLE_ROW* FP_LIB_TABLE::FindRow( const wxString& aNickname, bool a
if( !row )
{
wxString msg = wxString::Format( _( "fp-lib-table files contain no library named '%s'." ),
aNickname );
// We don't generally show this string to the user (who is unlikely to know what
// "fp-lib-table" means), and translating it may produce Sentry KICAD-YP.
wxString msg = wxString::Format( wxS( "'%s' not found in fp-lib-table." ), aNickname );
THROW_IO_ERROR( msg );
}
+8
View File
@@ -185,7 +185,11 @@ void ANTIALIASING_SUPERSAMPLING::Present()
glBindTexture( GL_TEXTURE_2D, compositor->GetBufferTexture( ssaaMainBuffer ) );
compositor->SetBuffer( OPENGL_COMPOSITOR::DIRECT_RENDERING );
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE );
draw_fullscreen_primitive();
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
}
@@ -547,7 +551,11 @@ void ANTIALIASING_SMAA::Present()
glActiveTexture( GL_TEXTURE1 );
glBindTexture( GL_TEXTURE_2D, blendTex );
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE );
pass_3_shader->Use();
draw_fullscreen_triangle();
pass_3_shader->Deactivate();
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
}
+1 -1
View File
@@ -297,7 +297,7 @@ void OPENGL_COMPOSITOR::ClearBuffer( const COLOR4D& aColor )
{
wxASSERT( m_initialized );
glClearColor( aColor.r, aColor.g, aColor.b, 0.0f );
glClearColor( aColor.r, aColor.g, aColor.b, m_curFbo == DIRECT_RENDERING ? 1.0f : 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
}
+25 -4
View File
@@ -1005,11 +1005,20 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
VECTOR2D p( cos( startAngle ) * aRadius, sin( startAngle ) * aRadius );
double alpha;
unsigned int lineCount = 0;
for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
lineCount++;
if( alpha != endAngle )
lineCount++;
reserveLineQuads( lineCount );
for( alpha = startAngle + alphaIncrement; alpha <= endAngle; alpha += alphaIncrement )
{
VECTOR2D p_next( cos( alpha ) * aRadius, sin( alpha ) * aRadius );
DrawLine( p, p_next );
drawLineQuad( p, p_next, false );
p = p_next;
}
@@ -1018,7 +1027,7 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius,
if( alpha != endAngle )
{
VECTOR2D p_last( cos( endAngle ) * aRadius, sin( endAngle ) * aRadius );
DrawLine( p, p_last );
drawLineQuad( p, p_last, false );
}
}
@@ -1058,9 +1067,21 @@ void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
if( seg_count % 2 != 0 )
seg_count += 1;
// Our shaders have trouble rendering null line quads, so delegate this task to DrawSegment.
if( seg_count == 0 )
{
VECTOR2D p_start( aCenterPoint.x + cos( startAngle ) * aRadius,
aCenterPoint.y + sin( startAngle ) * aRadius );
VECTOR2D p_end( aCenterPoint.x + cos( endAngle ) * aRadius,
aCenterPoint.y + sin( endAngle ) * aRadius );
DrawSegment( p_start, p_end, aWidth );
return;
}
// Recalculate alphaIncrement with a even integer number of segment
if( seg_count )
alphaIncrement = ( endAngle - startAngle ) / seg_count;
alphaIncrement = ( endAngle - startAngle ) / seg_count;
Save();
m_currentManager->Translate( aCenterPoint.x, aCenterPoint.y, 0.0 );
+1 -1
View File
@@ -444,7 +444,7 @@ void GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
break;
default:
if( menu_id >= GRIDTRICKS_FIRST_SHOWHIDE )
if( menu_id >= GRIDTRICKS_FIRST_SHOWHIDE && m_grid->CommitPendingChanges( false ) )
{
int col = menu_id - GRIDTRICKS_FIRST_SHOWHIDE;
+5 -1
View File
@@ -32,14 +32,18 @@
class PSEUDO_ACTION : public TOOL_ACTION
{
public:
PSEUDO_ACTION( const wxString& aLabel, int aHotKey )
PSEUDO_ACTION( const wxString& aLabel, int aHotKey, int aHotKeyAlt = 0 )
{
m_friendlyName = aLabel;
m_hotKey = aHotKey;
m_hotKeyAlt = aHotKeyAlt;
}
};
static PSEUDO_ACTION* g_gesturePseudoActions[] = {
new PSEUDO_ACTION( _( "Accept Autocomplete" ), WXK_RETURN, WXK_NUMPAD_ENTER ),
new PSEUDO_ACTION( _( "Cancel Autocomplete" ), WXK_ESCAPE ),
new PSEUDO_ACTION( _( "Toggle Checkbox" ), WXK_SPACE ),
new PSEUDO_ACTION( _( "Pan Left/Right" ), MD_CTRL + PSEUDO_WXK_WHEEL ),
new PSEUDO_ACTION( _( "Pan Up/Down" ), MD_SHIFT + PSEUDO_WXK_WHEEL ),
new PSEUDO_ACTION( _( "Finish Drawing" ), PSEUDO_WXK_DBLCLICK ),
+64 -63
View File
@@ -63,79 +63,80 @@ struct hotkey_name_descr
#define KEY_NON_FOUND -1
static struct hotkey_name_descr hotkeyNameList[] =
{
{ wxT( "F1" ), WXK_F1 },
{ wxT( "F2" ), WXK_F2 },
{ wxT( "F3" ), WXK_F3 },
{ wxT( "F4" ), WXK_F4 },
{ wxT( "F5" ), WXK_F5 },
{ wxT( "F6" ), WXK_F6 },
{ wxT( "F7" ), WXK_F7 },
{ wxT( "F8" ), WXK_F8 },
{ wxT( "F9" ), WXK_F9 },
{ wxT( "F10" ), WXK_F10 },
{ wxT( "F11" ), WXK_F11 },
{ wxT( "F12" ), WXK_F12 },
{ wxT( "F13" ), WXK_F13 },
{ wxT( "F14" ), WXK_F14 },
{ wxT( "F15" ), WXK_F15 },
{ wxT( "F16" ), WXK_F16 },
{ wxT( "F17" ), WXK_F17 },
{ wxT( "F18" ), WXK_F18 },
{ wxT( "F19" ), WXK_F19 },
{ wxT( "F20" ), WXK_F20 },
{ wxT( "F21" ), WXK_F21 },
{ wxT( "F22" ), WXK_F22 },
{ wxT( "F23" ), WXK_F23 },
{ wxT( "F24" ), WXK_F24 },
{ wxT( "F1" ), WXK_F1 },
{ wxT( "F2" ), WXK_F2 },
{ wxT( "F3" ), WXK_F3 },
{ wxT( "F4" ), WXK_F4 },
{ wxT( "F5" ), WXK_F5 },
{ wxT( "F6" ), WXK_F6 },
{ wxT( "F7" ), WXK_F7 },
{ wxT( "F8" ), WXK_F8 },
{ wxT( "F9" ), WXK_F9 },
{ wxT( "F10" ), WXK_F10 },
{ wxT( "F11" ), WXK_F11 },
{ wxT( "F12" ), WXK_F12 },
{ wxT( "F13" ), WXK_F13 },
{ wxT( "F14" ), WXK_F14 },
{ wxT( "F15" ), WXK_F15 },
{ wxT( "F16" ), WXK_F16 },
{ wxT( "F17" ), WXK_F17 },
{ wxT( "F18" ), WXK_F18 },
{ wxT( "F19" ), WXK_F19 },
{ wxT( "F20" ), WXK_F20 },
{ wxT( "F21" ), WXK_F21 },
{ wxT( "F22" ), WXK_F22 },
{ wxT( "F23" ), WXK_F23 },
{ wxT( "F24" ), WXK_F24 },
{ wxT( "Esc" ), WXK_ESCAPE },
{ wxT( "Del" ), WXK_DELETE },
{ wxT( "Tab" ), WXK_TAB },
{ wxT( "Back" ), WXK_BACK },
{ wxT( "Ins" ), WXK_INSERT },
{ wxT( "Esc" ), WXK_ESCAPE },
{ wxT( "Del" ), WXK_DELETE },
{ wxT( "Tab" ), WXK_TAB },
{ wxT( "Back" ), WXK_BACK },
{ wxT( "Ins" ), WXK_INSERT },
{ wxT( "Home" ), WXK_HOME },
{ wxT( "End" ), WXK_END },
{ wxT( "PgUp" ), WXK_PAGEUP },
{ wxT( "PgDn" ), WXK_PAGEDOWN },
{ wxT( "Home" ), WXK_HOME },
{ wxT( "End" ), WXK_END },
{ wxT( "PgUp" ), WXK_PAGEUP },
{ wxT( "PgDn" ), WXK_PAGEDOWN },
{ wxT( "Up" ), WXK_UP },
{ wxT( "Down" ), WXK_DOWN },
{ wxT( "Left" ), WXK_LEFT },
{ wxT( "Right" ), WXK_RIGHT },
{ wxT( "Up" ), WXK_UP },
{ wxT( "Down" ), WXK_DOWN },
{ wxT( "Left" ), WXK_LEFT },
{ wxT( "Right" ), WXK_RIGHT },
{ wxT( "Return" ), WXK_RETURN },
{ wxT( "Return" ), WXK_RETURN },
{ wxT( "Space" ), WXK_SPACE },
{ wxT( "Space" ), WXK_SPACE },
{ wxT( "Num Pad 0" ), WXK_NUMPAD0 },
{ wxT( "Num Pad 1" ), WXK_NUMPAD1 },
{ wxT( "Num Pad 2" ), WXK_NUMPAD2 },
{ wxT( "Num Pad 3" ), WXK_NUMPAD3 },
{ wxT( "Num Pad 4" ), WXK_NUMPAD4 },
{ wxT( "Num Pad 5" ), WXK_NUMPAD5 },
{ wxT( "Num Pad 6" ), WXK_NUMPAD6 },
{ wxT( "Num Pad 7" ), WXK_NUMPAD7 },
{ wxT( "Num Pad 8" ), WXK_NUMPAD8 },
{ wxT( "Num Pad 9" ), WXK_NUMPAD9 },
{ wxT( "Num Pad +" ), WXK_NUMPAD_ADD },
{ wxT( "Num Pad -" ), WXK_NUMPAD_SUBTRACT },
{ wxT( "Num Pad *" ), WXK_NUMPAD_MULTIPLY },
{ wxT( "Num Pad /" ), WXK_NUMPAD_DIVIDE },
{ wxT( "Num Pad ." ), WXK_NUMPAD_SEPARATOR },
{ wxT( "Num Pad F1"), WXK_NUMPAD_F1 },
{ wxT( "Num Pad F2"), WXK_NUMPAD_F2 },
{ wxT( "Num Pad F3"), WXK_NUMPAD_F3 },
{ wxT( "Num Pad F4"), WXK_NUMPAD_F4 },
{ wxT( "Num Pad 0" ), WXK_NUMPAD0 },
{ wxT( "Num Pad 1" ), WXK_NUMPAD1 },
{ wxT( "Num Pad 2" ), WXK_NUMPAD2 },
{ wxT( "Num Pad 3" ), WXK_NUMPAD3 },
{ wxT( "Num Pad 4" ), WXK_NUMPAD4 },
{ wxT( "Num Pad 5" ), WXK_NUMPAD5 },
{ wxT( "Num Pad 6" ), WXK_NUMPAD6 },
{ wxT( "Num Pad 7" ), WXK_NUMPAD7 },
{ wxT( "Num Pad 8" ), WXK_NUMPAD8 },
{ wxT( "Num Pad 9" ), WXK_NUMPAD9 },
{ wxT( "Num Pad +" ), WXK_NUMPAD_ADD },
{ wxT( "Num Pad -" ), WXK_NUMPAD_SUBTRACT },
{ wxT( "Num Pad *" ), WXK_NUMPAD_MULTIPLY },
{ wxT( "Num Pad /" ), WXK_NUMPAD_DIVIDE },
{ wxT( "Num Pad ." ), WXK_NUMPAD_SEPARATOR },
{ wxT( "Num Pad Enter" ), WXK_NUMPAD_ENTER },
{ wxT( "Num Pad F1"), WXK_NUMPAD_F1 },
{ wxT( "Num Pad F2"), WXK_NUMPAD_F2 },
{ wxT( "Num Pad F3"), WXK_NUMPAD_F3 },
{ wxT( "Num Pad F4"), WXK_NUMPAD_F4 },
{ wxT( "" ), 0 },
{ wxT( "" ), 0 },
{ wxT( "Click" ), PSEUDO_WXK_CLICK },
{ wxT( "DblClick" ), PSEUDO_WXK_DBLCLICK },
{ wxT( "Wheel" ), PSEUDO_WXK_WHEEL },
{ wxT( "Click" ), PSEUDO_WXK_CLICK },
{ wxT( "DblClick" ), PSEUDO_WXK_DBLCLICK },
{ wxT( "Wheel" ), PSEUDO_WXK_WHEEL },
// Do not change this line: end of list
{ wxT( "" ), KEY_NON_FOUND }
{ wxT( "" ), KEY_NON_FOUND }
};
+134
View File
@@ -0,0 +1,134 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
* Copyright (C) 2020-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 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "altium_ascii_parser.h"
#include "altium_parser_utils.h"
ALTIUM_ASCII_PARSER::ALTIUM_ASCII_PARSER( const wxString& aInputFile ) :
m_fileInput( aInputFile.fn_str() )
{
}
std::map<wxString, wxString> ALTIUM_ASCII_PARSER::ReadProperties()
{
std::map<wxString, wxString> kv;
std::string str;
std::string line;
// Lines ending with |> continue on the next line
do
{
if( !std::getline( m_fileInput, line ) )
{
m_error = true;
return kv;
}
if( ( line.size() > 2 && line[line.size() - 2] == '|' && line[line.size() - 1] == '>' ) )
{
str.append( line, 0, line.size() - 2 );
}
else
{
str.append( line );
break;
}
} while( true );
std::size_t token_end = 0;
while( token_end < str.size() && token_end != std::string::npos )
{
std::size_t token_start = str.find( '|', token_end );
std::size_t token_equal = str.find( '=', token_end );
std::size_t key_start;
if( token_start <= token_equal )
{
key_start = token_start + 1;
}
else
{
// Leading "|" before "RECORD=28" may be missing in older schematic versions.
key_start = token_end;
}
token_end = str.find( '|', key_start );
if( token_equal >= token_end )
{
continue; // this looks like an error: skip the entry. Also matches on std::string::npos
}
if( token_end == std::string::npos )
{
token_end = str.size() + 1; // this is the correct offset
}
std::string keyS = str.substr( key_start, token_equal - key_start );
std::string valueS = str.substr( token_equal + 1, token_end - token_equal - 1 );
// convert the strings to wxStrings, since we use them everywhere
// value can have non-ASCII characters, so we convert them from LATIN1/ISO8859-1
wxString key( keyS.c_str(), wxConvISO8859_1 );
// Altium stores keys either in Upper, or in CamelCase. Lets unify it.
wxString canonicalKey = key.Trim( false ).Trim( true ).MakeUpper();
// If the key starts with '%UTF8%' we have to parse the value using UTF8
wxString value;
if( canonicalKey.StartsWith( "%UTF8%" ) )
value = wxString( valueS.c_str(), wxConvUTF8 );
else
value = wxString( valueS.c_str(), wxConvISO8859_1 );
if( canonicalKey != wxS( "PATTERN" ) && canonicalKey != wxS( "SOURCEFOOTPRINTLIBRARY" ) )
{
// Breathless hack because I haven't a clue what the story is here (but this character
// appears in a lot of radial dimensions and is rendered by Altium as a space).
value.Replace( wxT( "ÿ" ), wxT( " " ) );
}
// Storage binary data do not need conversion.
if( str.rfind( "|BINARY", 0 ) != 0 )
{
if( canonicalKey == wxT( "DESIGNATOR" ) || canonicalKey == wxT( "NAME" )
|| canonicalKey == wxT( "TEXT" ) )
{
value = AltiumPropertyToKiCadString( value );
}
}
kv.insert( { canonicalKey, value.Trim() } );
}
return kv;
}
bool ALTIUM_ASCII_PARSER::CanRead()
{
return m_fileInput && m_fileInput.peek() != std::ifstream::traits_type::eof();
}
+54
View File
@@ -0,0 +1,54 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
* Copyright (C) 2020-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 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _ALTIUM_PARSER_H
#define _ALTIUM_PARSER_H
#include <map>
#include <string>
#include <fstream>
#include <wx/string.h>
class ALTIUM_ASCII_PARSER
{
public:
ALTIUM_ASCII_PARSER( const wxString& aInputFile );
std::map<wxString, wxString> ReadProperties();
bool CanRead();
bool HasParsingError()
{
return m_error;
}
private:
std::ifstream m_fileInput;
bool m_error = false;
};
#endif //_ALTIUM_PARSER_H
@@ -22,7 +22,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "altium_parser.h"
#include "altium_binary_parser.h"
#include "altium_parser_utils.h"
#include <compoundfilereader.h>
@@ -350,13 +350,13 @@ void ALTIUM_COMPOUND_FILE::cacheLibFootprintNames()
if( m_reader->IsStream( entry ) && fileName == L"Parameters" )
{
ALTIUM_PARSER parametersReader( *this, entry );
ALTIUM_BINARY_PARSER parametersReader( *this, entry );
std::map<wxString, wxString> parameterProperties =
parametersReader.ReadProperties();
wxString key = ALTIUM_PARSER::ReadString(
wxString key = ALTIUM_PROPS_UTILS::ReadString(
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
wxString fpName = ALTIUM_PARSER::ReadUnicodeString(
wxString fpName = ALTIUM_PROPS_UTILS::ReadUnicodeString(
parameterProperties, wxT( "PATTERN" ), wxT( "" ) );
m_libFootprintDirNameCache[key] = fpName;
@@ -370,7 +370,7 @@ void ALTIUM_COMPOUND_FILE::cacheLibFootprintNames()
}
ALTIUM_PARSER::ALTIUM_PARSER( const ALTIUM_COMPOUND_FILE& aFile,
ALTIUM_BINARY_PARSER::ALTIUM_BINARY_PARSER( const ALTIUM_COMPOUND_FILE& aFile,
const CFB::COMPOUND_FILE_ENTRY* aEntry )
{
m_subrecord_end = nullptr;
@@ -384,7 +384,7 @@ ALTIUM_PARSER::ALTIUM_PARSER( const ALTIUM_COMPOUND_FILE& aFile,
}
ALTIUM_PARSER::ALTIUM_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize )
ALTIUM_BINARY_PARSER::ALTIUM_BINARY_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize )
{
m_subrecord_end = nullptr;
m_size = aSize;
@@ -394,7 +394,7 @@ ALTIUM_PARSER::ALTIUM_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize )
}
std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties(
std::map<wxString, wxString> ALTIUM_BINARY_PARSER::ReadProperties(
std::function<std::map<wxString, wxString>( const std::string& )> handleBinaryData )
{
@@ -502,123 +502,3 @@ std::map<wxString, wxString> ALTIUM_PARSER::ReadProperties(
return kv;
}
int32_t ALTIUM_PARSER::ConvertToKicadUnit( const double aValue )
{
constexpr double int_limit = ( std::numeric_limits<int>::max() - 10 ) / 2.54;
int32_t iu = KiROUND( Clamp<double>( -int_limit, aValue, int_limit ) * 2.54 );
// Altium's internal precision is 0.1uinch. KiCad's is 1nm. Round to nearest 10nm to clean
// up most rounding errors. This allows lossless conversion of increments of 0.05mils and
// 0.01um.
return KiROUND( (double) iu / 10.0 ) * 10;
}
int ALTIUM_PARSER::ReadInt( const std::map<wxString, wxString>& aProps, const wxString& aKey,
int aDefault )
{
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
return value == aProps.end() ? aDefault : wxAtoi( value->second );
}
double ALTIUM_PARSER::ReadDouble( const std::map<wxString, wxString>& aProps, const wxString& aKey,
double aDefault )
{
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
if( value == aProps.end() )
return aDefault;
// Locale independent str -> double conversation
std::istringstream istr( (const char*) value->second.mb_str() );
istr.imbue( std::locale::classic() );
double doubleValue;
istr >> doubleValue;
return doubleValue;
}
bool ALTIUM_PARSER::ReadBool( const std::map<wxString, wxString>& aProps, const wxString& aKey,
bool aDefault )
{
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
if( value == aProps.end() )
return aDefault;
else
return value->second == "T" || value->second == "TRUE";
}
int32_t ALTIUM_PARSER::ReadKicadUnit( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault )
{
const wxString& value = ReadString( aProps, aKey, aDefault );
wxString prefix;
if( !value.EndsWith( "mil", &prefix ) )
{
wxLogError( _( "Unit '%s' does not end with 'mil'." ), value );
return 0;
}
prefix.StartsWith( "+", &prefix );
double mils;
if( !prefix.ToCDouble( &mils ) )
{
wxLogError( _( "Cannot convert '%s' to double." ), prefix );
return 0;
}
return ConvertToKicadUnit( mils * 10000 );
}
wxString ALTIUM_PARSER::ReadString( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault )
{
const auto& utf8Value = aProps.find( wxString( "%UTF8%" ) + aKey );
if( utf8Value != aProps.end() )
return utf8Value->second;
const auto& value = aProps.find( aKey );
if( value != aProps.end() )
return value->second;
return aDefault;
}
wxString ALTIUM_PARSER::ReadUnicodeString( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault )
{
const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) );
if( unicodeFlag != aProps.end() && unicodeFlag->second.Contains( wxS( "EXISTS" ) ) )
{
const auto& unicodeValue = aProps.find( wxString( "UNICODE__" ) + aKey );
if( unicodeValue != aProps.end() )
{
wxArrayString arr = wxSplit( unicodeValue->second, ',', '\0' );
wxString out;
for( wxString part : arr )
out += wxString( wchar_t( wxAtoi( part ) ) );
return out;
}
}
return ReadString( aProps, aKey, aDefault );
}
@@ -22,8 +22,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef ALTIUM_PARSER_H
#define ALTIUM_PARSER_H
#ifndef _ALTIUM_BINARY_PARSER_H
#define _ALTIUM_BINARY_PARSER_H
#include "altium_props_utils.h"
#include <map>
#include <memory>
@@ -106,12 +108,12 @@ private:
};
class ALTIUM_PARSER
class ALTIUM_BINARY_PARSER
{
public:
ALTIUM_PARSER( const ALTIUM_COMPOUND_FILE& aFile, const CFB::COMPOUND_FILE_ENTRY* aEntry );
ALTIUM_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize );
~ALTIUM_PARSER() = default;
ALTIUM_BINARY_PARSER( const ALTIUM_COMPOUND_FILE& aFile, const CFB::COMPOUND_FILE_ENTRY* aEntry );
ALTIUM_BINARY_PARSER( std::unique_ptr<char[]>& aContent, size_t aSize );
~ALTIUM_BINARY_PARSER() = default;
template <typename Type>
Type Read()
@@ -229,7 +231,7 @@ public:
int32_t ReadKicadUnit()
{
return ConvertToKicadUnit( Read<int32_t>() );
return ALTIUM_PROPS_UTILS::ConvertToKicadUnit( Read<int32_t>() );
}
int32_t ReadKicadUnitX()
@@ -270,26 +272,6 @@ public:
return std::map<wxString, wxString>();
} );
static int32_t ConvertToKicadUnit( const double aValue );
static int ReadInt( const std::map<wxString, wxString>& aProps,
const wxString& aKey, int aDefault );
static double ReadDouble( const std::map<wxString, wxString>& aProps,
const wxString& aKey, double aDefault );
static bool ReadBool( const std::map<wxString, wxString>& aProps,
const wxString& aKey, bool aDefault );
static int32_t ReadKicadUnit( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault );
static wxString ReadString( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault );
static wxString ReadUnicodeString( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault );
void Skip( size_t aLength )
{
if( GetRemainingBytes() >= aLength )
@@ -447,4 +429,4 @@ private:
}
};
#endif //ALTIUM_PARSER_H
#endif //_ALTIUM_BINARY_PARSER_H
+153
View File
@@ -0,0 +1,153 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
* Copyright (C) 2020-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 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "altium_props_utils.h"
#include <limits>
#include <sstream>
#include <math/util.h>
#include <wx/crt.h>
#include <wx/log.h>
#include <wx/translation.h>
int32_t ALTIUM_PROPS_UTILS::ConvertToKicadUnit( const double aValue )
{
constexpr double int_limit = ( std::numeric_limits<int>::max() - 10 ) / 2.54;
int32_t iu = KiROUND( Clamp<double>( -int_limit, aValue, int_limit ) * 2.54 );
// Altium's internal precision is 0.1uinch. KiCad's is 1nm. Round to nearest 10nm to clean
// up most rounding errors. This allows lossless conversion of increments of 0.05mils and
// 0.01um.
return KiROUND( (double) iu / 10.0 ) * 10;
}
int ALTIUM_PROPS_UTILS::ReadInt( const std::map<wxString, wxString>& aProps, const wxString& aKey,
int aDefault )
{
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
return value == aProps.end() ? aDefault : wxAtoi( value->second );
}
double ALTIUM_PROPS_UTILS::ReadDouble( const std::map<wxString, wxString>& aProps, const wxString& aKey,
double aDefault )
{
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
if( value == aProps.end() )
return aDefault;
// Locale independent str -> double conversation
std::istringstream istr( (const char*) value->second.mb_str() );
istr.imbue( std::locale::classic() );
double doubleValue;
istr >> doubleValue;
return doubleValue;
}
bool ALTIUM_PROPS_UTILS::ReadBool( const std::map<wxString, wxString>& aProps, const wxString& aKey,
bool aDefault )
{
const std::map<wxString, wxString>::const_iterator& value = aProps.find( aKey );
if( value == aProps.end() )
return aDefault;
else
return value->second == "T" || value->second == "TRUE";
}
int32_t ALTIUM_PROPS_UTILS::ReadKicadUnit( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault )
{
const wxString& value = ReadString( aProps, aKey, aDefault );
wxString prefix;
if( !value.EndsWith( "mil", &prefix ) )
{
wxLogError( _( "Unit '%s' does not end with 'mil'." ), value );
return 0;
}
prefix.StartsWith( "+", &prefix );
double mils;
if( !prefix.ToCDouble( &mils ) )
{
wxLogError( _( "Cannot convert '%s' to double." ), prefix );
return 0;
}
return ConvertToKicadUnit( mils * 10000 );
}
wxString ALTIUM_PROPS_UTILS::ReadString( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault )
{
const auto& utf8Value = aProps.find( wxString( "%UTF8%" ) + aKey );
if( utf8Value != aProps.end() )
return utf8Value->second;
const auto& value = aProps.find( aKey );
if( value != aProps.end() )
return value->second;
return aDefault;
}
wxString ALTIUM_PROPS_UTILS::ReadUnicodeString( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault )
{
const auto& unicodeFlag = aProps.find( wxS( "UNICODE" ) );
if( unicodeFlag != aProps.end() && unicodeFlag->second.Contains( wxS( "EXISTS" ) ) )
{
const auto& unicodeValue = aProps.find( wxString( "UNICODE__" ) + aKey );
if( unicodeValue != aProps.end() )
{
wxArrayString arr = wxSplit( unicodeValue->second, ',', '\0' );
wxString out;
for( wxString part : arr )
out += wxString( wchar_t( wxAtoi( part ) ) );
return out;
}
}
return ReadString( aProps, aKey, aDefault );
}
+58
View File
@@ -0,0 +1,58 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019-2020 Thomas Pointhuber <thomas.pointhuber@gmx.at>
* Copyright (C) 2020-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 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _ALTIUM_PROPS_UTILS_H
#define _ALTIUM_PROPS_UTILS_H
#include <stdint.h>
#include <map>
#include <wx/string.h>
class ALTIUM_PROPS_UTILS
{
public:
static int32_t ConvertToKicadUnit( const double aValue );
static int ReadInt( const std::map<wxString, wxString>& aProps, const wxString& aKey,
int aDefault );
static double ReadDouble( const std::map<wxString, wxString>& aProps, const wxString& aKey,
double aDefault );
static bool ReadBool( const std::map<wxString, wxString>& aProps, const wxString& aKey,
bool aDefault );
static int32_t ReadKicadUnit( const std::map<wxString, wxString>& aProps, const wxString& aKey,
const wxString& aDefault );
static wxString ReadString( const std::map<wxString, wxString>& aProps, const wxString& aKey,
const wxString& aDefault );
static wxString ReadUnicodeString( const std::map<wxString, wxString>& aProps,
const wxString& aKey, const wxString& aDefault );
};
#endif //_ALTIUM_PROPS_UTILS_H
+8
View File
@@ -979,13 +979,20 @@ EELEMENT::EELEMENT( wxXmlNode* aElement )
<!ATTLIST element
name %String; #REQUIRED
library %String; #REQUIRED
library_urn %Urn; ""
package %String; #REQUIRED
package3d_urn %Urn; ""
override_package3d_urn %Urn; ""
override_package_urn %Urn; ""
override_locally_modified %Bool; "no"
value %String; #REQUIRED
x %Coord; #REQUIRED
y %Coord; #REQUIRED
locked %Bool; "no"
populate %Bool; "yes"
smashed %Bool; "no"
rot %Rotation; "R0"
grouprefs IDREFS #IMPLIED
>
*/
@@ -1001,6 +1008,7 @@ EELEMENT::EELEMENT( wxXmlNode* aElement )
y = parseRequiredAttribute<ECOORD>( aElement, "y" );
// optional
library_urn = parseOptionalAttribute<wxString>( aElement, "library_urn" );
locked = parseOptionalAttribute<bool>( aElement, "locked" );
smashed = parseOptionalAttribute<bool>( aElement, "smashed" );
rot = parseOptionalAttribute<EROT>( aElement, "rot" );
+1
View File
@@ -817,6 +817,7 @@ struct EELEMENT
{
wxString name;
wxString library;
opt_wxString library_urn;
wxString package;
wxString value;
ECOORD x;
@@ -87,6 +87,7 @@ void EASYEDA::from_json( const nlohmann::json& j, EASYEDA::DOCUMENT& d )
PARSE_VALUE( head );
PARSE_VALUE( canvas );
PARSE_VALUE( title );
PARSE_VALUE( shape );
PARSE_VALUE( dataStr );
}
+4 -3
View File
@@ -73,9 +73,10 @@ struct DOCUMENT
// BBox
// colors
wxString canvas;
wxArrayString shape;
std::optional<nlohmann::json> dataStr;
wxString canvas;
wxString title;
wxArrayString shape;
std::optional<nlohmann::json> dataStr;
};
struct C_PARA
+3
View File
@@ -229,6 +229,9 @@ void Prettify( std::string& aSource, char aQuoteChar )
++cursor;
}
// newline required at end of line / file for POSIX compliance. Keeps git diffs clean.
formatted += '\n';
aSource = std::move( formatted );
}
+28 -9
View File
@@ -247,7 +247,12 @@ void LIB_TREE_NODE_ITEM::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxSt
{
int currentScore = aMatcher->ScoreTerms( m_SearchTerms );
if( m_Score >= 0 && currentScore > 0 )
// This is a hack: the second phase of search in the adapter will look for a tokenized
// LIB_ID and send the lib part down here. While we generally want to prune ourselves
// out here (by setting score to -1) the first time we fail to match a search term,
// we want to give the same search term a second chance if it has been split from a library
// name.
if( ( m_Score >= 0 || !aLib.IsEmpty() ) && currentScore > 0 )
m_Score += currentScore;
else
m_Score = -1; // Item has failed to match this term, rule it out
@@ -290,28 +295,42 @@ LIB_TREE_NODE_ITEM& LIB_TREE_NODE_LIBRARY::AddItem( LIB_TREE_ITEM* aItem )
void LIB_TREE_NODE_LIBRARY::UpdateScore( EDA_COMBINED_MATCHER* aMatcher, const wxString& aLib,
std::function<bool( LIB_TREE_NODE& aNode )>* aFilter )
{
int newScore = 0;
int maxChildScore = 0;
for( std::unique_ptr<LIB_TREE_NODE>& child: m_Children )
{
child->UpdateScore( aMatcher, aLib, aFilter );
newScore = std::max( newScore, child->m_Score );
maxChildScore = std::max( maxChildScore, child->m_Score );
}
// Each time UpdateScore is called for a library, child (item) scores may go up or down.
// If the all go down to zero, we need to make sure to drop the library from the list.
if( newScore > 0 )
m_Score = std::max( m_Score, newScore );
if( maxChildScore > 0 )
m_Score = std::max( m_Score, maxChildScore );
else
m_Score = 0;
// aLib test is additive, but only when we've already accumulated some score from children
if( !aLib.IsEmpty() && m_Name.Lower().Matches( aLib ) && m_Score > 0 )
if( !aLib.IsEmpty()
&& m_Name.Lower().Matches( aLib )
&& ( m_Score > 0 || m_Children.empty() ) )
{
m_Score += 1;
}
// aMatcher test is additive, but only when we've already accumulated some score from children
if( aMatcher && m_Score > 0 )
m_Score += aMatcher->ScoreTerms( m_SearchTerms );
// aMatcher test is additive
if( aMatcher )
{
int ownScore = aMatcher->ScoreTerms( m_SearchTerms );
m_Score += ownScore;
// If we have a hit on a library, show all children in that library
if( maxChildScore <= 0 && ownScore > 0 )
{
for( std::unique_ptr<LIB_TREE_NODE>& child: m_Children )
child->ForceScore( 1 );
}
}
// show all nodes if no search/filter/etc. criteria are given
if( m_Children.empty() && !aMatcher && aLib.IsEmpty() && ( !aFilter || (*aFilter)(*this) ) )
-5
View File
@@ -302,11 +302,6 @@ void LIB_TREE_MODEL_ADAPTER::UpdateSearchString( const wxString& aSearch, bool a
m_tree.UpdateScore( &itemNameMatcher, lib, nullptr );
}
else
{
// In case the full token happens to match a library name
m_tree.UpdateScore( nullptr, '*' + term + '*', nullptr );
}
}
if( firstTerm )
+19 -15
View File
@@ -169,6 +169,10 @@ wxString PATHS::GetStockDataPath( bool aRespectRunFromBuildDir )
path = GetExecutablePath() + wxT( ".." );
#endif
}
else if( wxGetEnv( wxT( "KICAD_STOCK_DATA_HOME" ), &path ) && !path.IsEmpty() )
{
return path;
}
else
{
#if defined( __WXMAC__ )
@@ -291,12 +295,16 @@ wxString PATHS::GetStockPlugins3DPath()
{
wxFileName fn;
#ifdef __WXGTK__
// KICAD_PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
// corresponding to the install path used for constructing KICAD_USER_PLUGIN
wxString tfname = wxString::FromUTF8Unchecked( KICAD_PLUGINDIR );
fn.Assign( tfname, "" );
fn.AppendDir( wxT( "kicad" ) );
#if defined( __WXMSW__ )
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
{
fn.AssignDir( getWindowsKiCadRoot() );
}
else
{
fn.AssignDir( GetExecutablePath() );
}
fn.AppendDir( wxT( "plugins" ) );
#elif defined( __WXMAC__ )
fn.Assign( wxStandardPaths::Get().GetPluginsDir(), wxEmptyString );
@@ -319,15 +327,11 @@ wxString PATHS::GetStockPlugins3DPath()
fn.AppendDir( wxT( "PlugIns" ) );
}
#else
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
{
fn.AssignDir( getWindowsKiCadRoot() );
}
else
{
fn.AssignDir( GetExecutablePath() );
}
// KICAD_PLUGINDIR = CMAKE_INSTALL_FULL_LIBDIR path is the absolute path
// corresponding to the install path used for constructing KICAD_USER_PLUGIN
wxString tfname = wxString::FromUTF8Unchecked( KICAD_PLUGINDIR );
fn.Assign( tfname, "" );
fn.AppendDir( wxT( "kicad" ) );
fn.AppendDir( wxT( "plugins" ) );
#endif
+19 -8
View File
@@ -833,10 +833,21 @@ void GERBER_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
{
SetCurrentLineWidth( aWidth );
EDA_ANGLE endAngle = aStartAngle + aAngle;
double arcLength = std::abs( aRadius * aAngle.AsRadians() );
// aFill is not used here.
plotArc( aCenter, aStartAngle, endAngle, aRadius, false );
if( arcLength < 100 || std::abs( aAngle.AsDegrees() ) < 0.1 )
{
// Prevent plotting very short arcs as full circles, especially with 4.5 mm precision.
// Also reduce the risk of integer overflow issues.
polyArc( aCenter, aStartAngle, aAngle, aRadius, aFill, aWidth );
}
else
{
EDA_ANGLE endAngle = aStartAngle + aAngle;
// aFill is not used here.
plotArc( aCenter, aStartAngle, endAngle, aRadius, false );
}
}
@@ -879,19 +890,19 @@ void GERBER_PLOTTER::plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion )
void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, int aRadius, bool aPlotInRegion )
const EDA_ANGLE& aEndAngle, double aRadius, bool aPlotInRegion )
{
VECTOR2I start, end;
start.x = aCenter.x + KiROUND( aRadius * aStartAngle.Cos() );
start.y = aCenter.y + KiROUND( aRadius * aStartAngle.Sin() );
start.x = KiROUND( aCenter.x + aRadius * aStartAngle.Cos() );
start.y = KiROUND( aCenter.y + aRadius * aStartAngle.Sin() );
if( !aPlotInRegion )
MoveTo( start );
else
LineTo( start );
end.x = aCenter.x + KiROUND( aRadius * aEndAngle.Cos() );
end.y = aCenter.y + KiROUND( aRadius * aEndAngle.Sin() );
end.x = KiROUND( aCenter.x + aRadius * aEndAngle.Cos() );
end.y = KiROUND( aCenter.y + aRadius * aEndAngle.Sin() );
VECTOR2D devEnd = userToDeviceCoordinates( end );
// devRelCenter is the position on arc center relative to the arc start, in Gerber coord.
VECTOR2D devRelCenter = userToDeviceCoordinates( aCenter ) - userToDeviceCoordinates( start );
+10 -3
View File
@@ -565,6 +565,13 @@ void HPGL_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
if( aRadius <= 0 )
return;
// Avoid integer overflow when calculating the center point
if( std::abs( aAngle.AsDegrees() ) < 5 )
{
polyArc( aCenter, aStartAngle, aAngle, aRadius, aFill, aWidth );
return;
}
double const radius_device = userToDeviceSize( aRadius );
double const circumf_device = 2.0 * M_PI * radius_device;
double const target_chord_length = m_arcTargetChordLength;
@@ -581,11 +588,11 @@ void HPGL_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
EDA_ANGLE startAngle = -aStartAngle;
// Calculate arc start point:
VECTOR2I cmap( aCenter.x + KiROUND( aRadius * startAngle.Cos() ),
aCenter.y - KiROUND( aRadius * startAngle.Sin() ) );
VECTOR2I cmap( KiROUND( aCenter.x + aRadius * startAngle.Cos() ),
KiROUND( aCenter.y - aRadius * startAngle.Sin() ) );
VECTOR2D cmap_dev = userToDeviceCoordinates( cmap );
startOrAppendItem( cmap_dev, wxString::Format( "AA %.0f,%.0f,%.0f,%g",
startOrAppendItem( cmap_dev, wxString::Format( "AA %.0f,%.0f,%g,%g",
centre_device.x,
centre_device.y,
angle.AsDegrees(),
+6 -6
View File
@@ -354,21 +354,21 @@ void PDF_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
SetCurrentLineWidth( aWidth );
// Usual trig arc plotting routine...
start.x = aCenter.x + KiROUND( aRadius * (-startAngle).Cos() );
start.y = aCenter.y + KiROUND( aRadius * (-startAngle).Sin() );
start.x = KiROUND( aCenter.x + aRadius * ( -startAngle ).Cos() );
start.y = KiROUND( aCenter.y + aRadius * ( -startAngle ).Sin() );
VECTOR2D pos_dev = userToDeviceCoordinates( start );
fprintf( m_workFile, "%g %g m ", pos_dev.x, pos_dev.y );
for( EDA_ANGLE ii = startAngle + delta; ii < endAngle; ii += delta )
{
end.x = aCenter.x + KiROUND( aRadius * (-ii).Cos() );
end.y = aCenter.y + KiROUND( aRadius * (-ii).Sin() );
end.x = KiROUND( aCenter.x + aRadius * ( -ii ).Cos() );
end.y = KiROUND( aCenter.y + aRadius * ( -ii ).Sin() );
pos_dev = userToDeviceCoordinates( end );
fprintf( m_workFile, "%g %g l ", pos_dev.x, pos_dev.y );
}
end.x = aCenter.x + KiROUND( aRadius * (-endAngle).Cos() );
end.y = aCenter.y + KiROUND( aRadius * (-endAngle).Sin() );
end.x = KiROUND( aCenter.x + aRadius * ( -endAngle ).Cos() );
end.y = KiROUND( aCenter.y + aRadius * ( -endAngle ).Sin() );
pos_dev = userToDeviceCoordinates( end );
fprintf( m_workFile, "%g %g l ", pos_dev.x, pos_dev.y );
+7 -7
View File
@@ -191,8 +191,8 @@ void PLOTTER::polyArc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
SetCurrentLineWidth( aWidth );
start.x = aCenter.x + KiROUND( aRadius * startAngle.Cos() );
start.y = aCenter.y + sign * KiROUND( aRadius * startAngle.Sin() );
start.x = KiROUND( aCenter.x + aRadius * startAngle.Cos() );
start.y = KiROUND( aCenter.y + sign * aRadius * startAngle.Sin() );
if( aFill != FILL_T::NO_FILL )
{
@@ -206,13 +206,13 @@ void PLOTTER::polyArc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
for( EDA_ANGLE ii = startAngle + delta; ii < endAngle; ii += delta )
{
end.x = aCenter.x + KiROUND( aRadius * ii.Cos() );
end.y = aCenter.y + sign * KiROUND( aRadius * ii.Sin() );
end.x = KiROUND( aCenter.x + aRadius * ii.Cos() );
end.y = KiROUND( aCenter.y + sign * aRadius * ii.Sin() );
LineTo( end );
}
end.x = aCenter.x + KiROUND( aRadius * endAngle.Cos() );
end.y = aCenter.y + sign * KiROUND( aRadius * endAngle.Sin() );
end.x = KiROUND( aCenter.x + aRadius * endAngle.Cos() );
end.y = KiROUND( aCenter.y + sign * aRadius * endAngle.Sin() );
if( aFill != FILL_T::NO_FILL )
{
@@ -706,7 +706,6 @@ void PLOTTER::Text( const VECTOR2I& aPos,
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
SetColor( aColor );
SetCurrentLineWidth( aPenWidth, aData );
if( aPenWidth == 0 && aBold ) // Use default values if aPenWidth == 0
aPenWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );
@@ -718,6 +717,7 @@ void PLOTTER::Text( const VECTOR2I& aPos,
// Stroke callback
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
{
SetCurrentLineWidth( aPenWidth );
MoveTo( aPt1 );
LineTo( aPt2 );
PenFinish();
+35 -7
View File
@@ -731,19 +731,47 @@ bool SETTINGS_MANAGER::GetPreviousVersionPaths( std::vector<wxString>* aPaths )
}
}
alg::delete_if( *aPaths, []( const wxString& aPath ) -> bool
{
wxFileName fulldir = wxFileName::DirName( aPath );
const wxArrayString& dirs = fulldir.GetDirs();
if( dirs.empty() || !fulldir.IsDirReadable() )
return true;
std::string ver = dirs.back().ToStdString();
if( !extractVersion( ver ) )
return true;
return false;
} );
std::sort( aPaths->begin(), aPaths->end(),
[&]( const wxString& a, const wxString& b ) -> bool
{
wxString verA = wxFileName::DirName( a ).GetDirs().back();
wxString verB = wxFileName::DirName( b ).GetDirs().back();
wxFileName aPath = wxFileName::DirName( a );
wxFileName bPath = wxFileName::DirName( b );
if( !extractVersion( verA.ToStdString() )
|| !extractVersion( verB.ToStdString() ) )
{
const wxArrayString& aDirs = aPath.GetDirs();
const wxArrayString& bDirs = bPath.GetDirs();
if( aDirs.empty() )
return false;
}
return compareVersions( verA.ToStdString(), verB.ToStdString() ) >= 0;
if( bDirs.empty() )
return true;
std::string verA = aDirs.back().ToStdString();
std::string verB = bDirs.back().ToStdString();
if( !extractVersion( verA ) )
return false;
if( !extractVersion( verB ) )
return true;
return compareVersions( verA, verB ) >= 0;
} );
return aPaths->size() > 0;
+16 -9
View File
@@ -98,6 +98,18 @@ bool TITLE_BLOCK::TextVarResolver( wxString* aToken, const PROJECT* aProject ) c
bool tokenUpdated = false;
wxString originalToken = *aToken;
auto getCurrentDate =
[]() -> wxString
{
// We can choose different formats. Should probably be kept in sync with ISSUE_DATE
// formatting in DIALOG_PAGES_SETTINGS.
//
// return wxDateTime::Now().Format( wxLocale::GetInfo( wxLOCALE_SHORT_DATE_FMT ) );
// return wxDateTime::Now().Format( wxLocale::GetInfo( wxLOCALE_LONG_DATE_FMT ) );
// return wxDateTime::Now().Format( wxT("%Y-%b-%d") );
return wxDateTime::Now().FormatISODate();
};
if( aToken->IsSameAs( wxT( "ISSUE_DATE" ) ) )
{
*aToken = GetDate();
@@ -105,14 +117,7 @@ bool TITLE_BLOCK::TextVarResolver( wxString* aToken, const PROJECT* aProject ) c
}
else if( aToken->IsSameAs( wxT( "CURRENT_DATE" ) ) )
{
// We can choose different formats. Should probably be kept in sync with ISSUE_DATE
// formatting in DIALOG_PAGES_SETTINGS.
//
// *aToken = wxDateTime::Now().Format( wxLocale::GetInfo( wxLOCALE_SHORT_DATE_FMT ) );
// *aToken = wxDateTime::Now().Format( wxLocale::GetInfo( wxLOCALE_LONG_DATE_FMT ) );
// *aToken = wxDateTime::Now().Format( wxT("%Y-%b-%d") );
*aToken = wxDateTime::Now().FormatISODate();
*aToken = getCurrentDate();
tokenUpdated = true;
}
else if( aToken->IsSameAs( wxT( "REVISION" ) ) )
@@ -152,7 +157,9 @@ bool TITLE_BLOCK::TextVarResolver( wxString* aToken, const PROJECT* aProject ) c
if( tokenUpdated )
{
if( aProject )
if( aToken->IsSameAs( wxT( "CURRENT_DATE" ) ) )
*aToken = getCurrentDate();
else if( aProject )
*aToken = ExpandTextVars( *aToken, aProject );
// This is the default fallback, so don't claim we resolved it
+2 -1
View File
@@ -547,7 +547,7 @@ int COMMON_TOOLS::ToggleGridOverrides( const TOOL_EVENT& aEvent )
int COMMON_TOOLS::GridProperties( const TOOL_EVENT& aEvent )
{
auto showGridPrefs =
[this]( wxString aParentName )
[this]( const wxString& aParentName )
{
m_frame->CallAfter(
[this, aParentName]()
@@ -563,6 +563,7 @@ int COMMON_TOOLS::GridProperties( const TOOL_EVENT& aEvent )
case FRAME_PCB_EDITOR: showGridPrefs( _( "PCB Editor" ) ); break;
case FRAME_FOOTPRINT_EDITOR: showGridPrefs( _( "Footprint Editor" ) ); break;
case FRAME_PL_EDITOR: showGridPrefs( _( "Drawing Sheet Editor" ) ); break;
case FRAME_GERBER: showGridPrefs( _( "Gerber Viewer" ) ); break;
default: wxFAIL_MSG( "Unknown frame: " + GetName() ); break;
}
+3
View File
@@ -622,6 +622,9 @@ void VIEW::SetCenter( const VECTOR2D& aCenter, const std::vector<BOX2D>& obscuri
BOX2I bbox = unobscuredPoly.BBox();
int step = std::min( bbox.GetWidth(), bbox.GetHeight() ) / 10;
if( step < 20 )
step = 20;
while( !unobscuredPoly.IsEmpty() )
{
unobscuredCenter = unobscuredPoly.BBox().Centre();
+5 -3
View File
@@ -81,7 +81,8 @@ WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, EDA_DRAW_PANEL_GAL* aParentPane
m_lastTimestamp( 0 ),
#endif
m_cursorPos( 0, 0 ),
m_updateCursor( true )
m_updateCursor( true ),
m_infinitePanWorks( false )
{
LoadSettings();
@@ -276,7 +277,8 @@ void WX_VIEW_CONTROLS::onMotion( wxMouseEvent& aEvent )
{
if( !justWarped )
{
if( KIPLATFORM::UI::WarpPointer( m_parentPanel, x + warpX, y + warpY ) )
if( m_infinitePanWorks
&& KIPLATFORM::UI::WarpPointer( m_parentPanel, x + warpX, y + warpY ) )
{
m_dragStartPoint += VECTOR2D( warpX, warpY );
justWarped = true;
@@ -452,7 +454,7 @@ void WX_VIEW_CONTROLS::onButton( wxMouseEvent& aEvent )
{
m_dragStartPoint = VECTOR2D( aEvent.GetX(), aEvent.GetY() );
setState( DRAG_PANNING );
KIPLATFORM::UI::InfiniteDragPrepareWindow( m_parentPanel );
m_infinitePanWorks = KIPLATFORM::UI::InfiniteDragPrepareWindow( m_parentPanel );
#if defined USE_MOUSE_CAPTURE
if( !m_parentPanel->HasCapture() )
@@ -92,6 +92,12 @@ void FOOTPRINT_PREVIEW_WIDGET::SetUserUnits( EDA_UNITS aUnits )
}
void FOOTPRINT_PREVIEW_WIDGET::SetPinFunctions( const std::map<wxString, wxString>& aPinFunctions )
{
m_prev_panel->SetPinFunctions( aPinFunctions );
}
void FOOTPRINT_PREVIEW_WIDGET::DisplayFootprint( const LIB_ID& aFPID )
{
if( !m_prev_panel || m_libid == aFPID )
+2 -2
View File
@@ -287,8 +287,8 @@ protected:
/*
* Symbol netlist format:
* pinCount
* fpFilters
* pinNumber pinName <tab> pinNumber pinName...
* fpFilter fpFilter...
*/
std::string m_symbolNetlist;
};
+8 -9
View File
@@ -174,6 +174,14 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
reset();
return;
}
else if( aSelection.Size() == 1 )
{
m_caption->SetLabel( aSelection.Front()->GetFriendlyName() );
}
else
{
m_caption->SetLabel( wxString::Format( _( "%d objects selected" ), aSelection.Size() ) );
}
// Get all the selected types
std::set<TYPE_ID> types;
@@ -292,15 +300,6 @@ void PROPERTIES_PANEL::rebuildProperties( const SELECTION& aSelection )
}
}
if( aSelection.Size() > 1 )
{
m_caption->SetLabel( wxString::Format( _( "%d objects selected" ), aSelection.Size() ) );
}
else
{
m_caption->SetLabel( aSelection.Front()->GetFriendlyName() );
}
const wxString unspecifiedGroupCaption = _( "Basic Properties" );
for( const wxString& groupName : groupDisplayOrder )
+8 -6
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Chris Pavlina <pavlina.chris@gmail.com>
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-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
@@ -202,12 +202,14 @@ protected:
// Let EVT_CHAR handle this one
aEvent.DoAllowNextEvent();
// On Windows, wxEvent::Skip must NOT be called.
// On Linux and OSX, wxEvent::Skip MUST be called.
// No, I don't know why.
#ifndef __WXMSW__
aEvent.Skip();
#ifdef __WXMSW__
// On Windows, looks like a OnChar event is not generated when
// using the Alt key modifier. So ensure m_event is up to date
// to handle the right key code when releasing the key and therefore
// closing the dialog
m_event = aEvent;
#endif
aEvent.Skip();
}
else
{
+2 -15
View File
@@ -465,21 +465,14 @@ void DISPLAY_FOOTPRINTS_FRAME::ReloadFootprint( FOOTPRINT* aFootprint )
return;
GetBoard()->DeleteAllFootprints();
GetBoard()->RemoveUnusedNets( nullptr );
GetCanvas()->GetView()->Clear();
for( PAD* pad : aFootprint->Pads() )
{
const COMPONENT_NET& net = m_currentComp->GetNet( pad->GetNumber() );
if( !net.GetPinFunction().IsEmpty() )
{
NETINFO_ITEM* netinfo = new NETINFO_ITEM( GetBoard() );
netinfo->SetNetname( net.GetPinFunction() );
GetBoard()->Add( netinfo );
pad->SetNet( netinfo );
}
pad->SetPinFunction( net.GetPinFunction() );
}
GetBoard()->Add( aFootprint );
@@ -504,7 +497,6 @@ void DISPLAY_FOOTPRINTS_FRAME::InitDisplay()
return;
GetBoard()->DeleteAllFootprints();
GetBoard()->RemoveUnusedNets( nullptr );
GetCanvas()->GetView()->Clear();
INFOBAR_REPORTER infoReporter( m_infoBar );
@@ -528,12 +520,7 @@ void DISPLAY_FOOTPRINTS_FRAME::InitDisplay()
const COMPONENT_NET& net = comp->GetNet( pad->GetNumber() );
if( !net.GetPinFunction().IsEmpty() )
{
NETINFO_ITEM* netinfo = new NETINFO_ITEM( GetBoard() );
netinfo->SetNetname( net.GetPinFunction() );
GetBoard()->Add( netinfo );
pad->SetNet( netinfo );
}
pad->SetPinFunction( net.GetPinFunction() );
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
(kicad_pcb
(version 20231231)
(version 20240108)
(generator "pcbnew")
(generator_version "7.99")
(generator_version "8.0")
(general
(thickness 1.6002)
(legacy_teardrops no)
File diff suppressed because it is too large Load Diff
+251 -55
View File
@@ -85,8 +85,51 @@ void CONNECTION_SUBGRAPH::RemoveItem( SCH_ITEM* aItem )
}
void CONNECTION_SUBGRAPH::ExchangeItem( SCH_ITEM* aOldItem, SCH_ITEM* aNewItem )
{
m_items.erase( aOldItem );
m_items.insert( aNewItem );
m_drivers.erase( aOldItem );
m_drivers.insert( aNewItem );
if( aOldItem == m_driver )
{
m_driver = aNewItem;
m_driver_connection = aNewItem->GetOrInitConnection( m_sheet, m_graph );
}
SCH_CONNECTION* old_conn = aOldItem->Connection( &m_sheet );
SCH_CONNECTION* new_conn = aNewItem->GetOrInitConnection( m_sheet, m_graph );
if( old_conn && new_conn )
{
new_conn->Clone( *old_conn );
if( old_conn->IsDriver() )
new_conn->SetDriver( aNewItem );
new_conn->ClearDirty();
}
if( aOldItem->Type() == SCH_SHEET_PIN_T )
{
m_hier_pins.erase( static_cast<SCH_SHEET_PIN*>( aOldItem ) );
m_hier_pins.insert( static_cast<SCH_SHEET_PIN*>( aNewItem ) );
}
if( aOldItem->Type() == SCH_HIER_LABEL_T )
{
m_hier_ports.erase( static_cast<SCH_HIERLABEL*>( aOldItem ) );
m_hier_ports.insert( static_cast<SCH_HIERLABEL*>( aNewItem ) );
}
}
bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
{
std::lock_guard lock( m_driver_mutex );
auto candidate_cmp = [&]( SCH_ITEM* a, SCH_ITEM* b ) -> bool
{
// meet irreflexive requirements of std::sort
@@ -574,6 +617,53 @@ void CONNECTION_GRAPH::Merge( CONNECTION_GRAPH& aGraph )
}
void CONNECTION_GRAPH::ExchangeItem( SCH_ITEM* aOldItem, SCH_ITEM* aNewItem )
{
wxCHECK2( aOldItem->Type() == aNewItem->Type(), return );
auto exchange = [&]( SCH_ITEM* aOld, SCH_ITEM* aNew )
{
auto it = m_item_to_subgraph_map.find( aOld );
if( it == m_item_to_subgraph_map.end() )
return;
CONNECTION_SUBGRAPH* sg = it->second;
sg->ExchangeItem( aOld, aNew );
m_item_to_subgraph_map.erase( it );
m_item_to_subgraph_map.emplace( aNew, sg );
for( auto it2 = m_items.begin(); it2 != m_items.end(); ++it2 )
{
if( *it2 == aOld )
{
*it2 = aNew;
break;
}
}
};
exchange( aOldItem, aNewItem );
if( aOldItem->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* oldSymbol = static_cast<SCH_SYMBOL*>( aOldItem );
SCH_SYMBOL* newSymbol = static_cast<SCH_SYMBOL*>( aNewItem );
std::vector<SCH_PIN*> oldPins = oldSymbol->GetPins( &m_schematic->CurrentSheet() );
std::vector<SCH_PIN*> newPins = newSymbol->GetPins( &m_schematic->CurrentSheet() );
wxCHECK2( oldPins.size() == newPins.size(), return );
for( size_t ii = 0; ii < oldPins.size(); ii++ )
{
exchange( oldPins[ii], newPins[ii] );
}
}
}
void CONNECTION_GRAPH::Reset()
{
for( auto& subgraph : m_subgraphs )
@@ -631,6 +721,21 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
items.push_back( item );
dirty_items.insert( item );
}
// If the symbol isn't dirty, look at the pins
// TODO: remove symbols from connectivity graph and only use pins
else if( item->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
for( SCH_PIN* pin : symbol->GetPins( &sheet ) )
{
if( pin->IsConnectivityDirty() )
{
items.push_back( pin );
dirty_items.insert( pin );
}
}
}
// Ensure the hierarchy info stored in the SCH_SCREEN (such as symbol units) reflects
// the current SCH_SHEET_PATH
@@ -672,7 +777,7 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
PROF_TIMER build_graph( "buildConnectionGraph" );
buildConnectionGraph( aChangedItemHandler );
buildConnectionGraph( aChangedItemHandler, aUnconditional );
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
build_graph.Show();
@@ -710,37 +815,76 @@ std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> CONNECTION_GRAPH::ExtractAffected
aSubgraph->getAllConnectedItems( retvals, subgraphs );
};
auto extract_element = [&]( SCH_ITEM* aItem )
{
CONNECTION_SUBGRAPH* item_sg = GetSubgraphForItem( aItem );
if( !item_sg )
{
wxLogTrace( ConnTrace, wxT( "Item %s not found in connection graph" ), aItem->GetTypeDesc() );
return;
}
if( !item_sg->ResolveDrivers( true ) )
{
wxLogTrace( ConnTrace, wxT( "Item %s in subgraph %ld (%p) has no driver" ),
aItem->GetTypeDesc(), item_sg->m_code, item_sg );
}
std::vector<CONNECTION_SUBGRAPH*> sg_to_scan = GetAllSubgraphs( item_sg->GetNetName() );
if( sg_to_scan.empty() )
{
wxLogTrace( ConnTrace, wxT( "Item %s in subgraph %ld with net %s has no neighbors" ),
aItem->GetTypeDesc(), item_sg->m_code, item_sg->GetNetName() );
sg_to_scan.push_back( item_sg );
}
wxLogTrace( ConnTrace,
wxT( "Removing all item %s connections from subgraph %ld with net %s: Found "
"%zu subgraphs" ),
aItem->GetTypeDesc(), item_sg->m_code, item_sg->GetNetName(),
sg_to_scan.size() );
for( CONNECTION_SUBGRAPH* sg : sg_to_scan )
{
traverse_subgraph( sg );
for( auto& bus_it : sg->m_bus_neighbors )
{
for( CONNECTION_SUBGRAPH* bus_sg : bus_it.second )
traverse_subgraph( bus_sg );
}
for( auto& bus_it : sg->m_bus_parents )
{
for( CONNECTION_SUBGRAPH* bus_sg : bus_it.second )
traverse_subgraph( bus_sg );
}
}
alg::delete_matching( m_items, aItem );
};
for( SCH_ITEM* item : aItems )
{
auto it = m_item_to_subgraph_map.find( item );
if( it == m_item_to_subgraph_map.end() )
continue;
CONNECTION_SUBGRAPH* sg = it->second;
traverse_subgraph( sg );
for( auto& bus_it : sg->m_bus_neighbors )
if( item->Type() == SCH_SHEET_T )
{
for( CONNECTION_SUBGRAPH* bus_sg : bus_it.second )
traverse_subgraph( bus_sg );
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
extract_element( pin );
}
for( auto& bus_it : sg->m_bus_parents )
{
for( CONNECTION_SUBGRAPH* bus_sg : bus_it.second )
traverse_subgraph( bus_sg );
}
alg::delete_matching( m_items, item );
if( item->Type() == SCH_SYMBOL_T )
else if ( item->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
for( SCH_PIN* pin : symbol->GetPins( &sg->m_sheet ) )
alg::delete_matching( m_items, pin );
for( SCH_PIN* pin : symbol->GetPins( &m_schematic->CurrentSheet() ) )
extract_element( pin );
}
else
{
extract_element( item );
}
}
@@ -770,6 +914,7 @@ void CONNECTION_GRAPH::RemoveItem( SCH_ITEM* aItem )
void CONNECTION_GRAPH::removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgraphs )
{
wxLogTrace( ConnTrace, wxT( "Removing %zu subgraphs" ), aSubgraphs.size() );
std::sort( m_driver_subgraphs.begin(), m_driver_subgraphs.end() );
std::sort( m_subgraphs.begin(), m_subgraphs.end() );
std::set<int> codes_to_remove;
@@ -928,12 +1073,30 @@ void CONNECTION_GRAPH::removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgrap
void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
const std::vector<SCH_ITEM*>& aItemList )
{
wxLogTrace( wxT( "Updating connectivity for sheet %s with %zu items" ),
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 );
// 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 ) );
}
};
for( SCH_ITEM* item : aItemList )
{
std::vector<VECTOR2I> points = item->GetConnectionPoints();
item->ConnectedItems( aSheet ).clear();
item->ClearConnectedItems( aSheet );
if( item->Type() == SCH_SHEET_T )
{
@@ -941,7 +1104,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
{
pin->InitializeConnection( aSheet, this );
pin->ConnectedItems( aSheet ).clear();
pin->ClearConnectedItems( aSheet );
connection_map[ pin->GetTextPos() ].push_back( pin );
m_items.emplace_back( pin );
@@ -953,23 +1116,10 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
for( SCH_PIN* pin : symbol->GetPins( &aSheet ) )
{
SCH_CONNECTION* conn = pin->InitializeConnection( aSheet, this );
VECTOR2I pos = pin->GetPosition();
// because calling the first time is not thread-safe
wxString name = pin->GetDefaultNetName( aSheet );
pin->ConnectedItems( aSheet ).clear();
// power symbol pins need to be post-processed later
if( pin->IsGlobalPower() )
{
conn->SetName( name );
m_global_power_pins.emplace_back( std::make_pair( aSheet, pin ) );
}
connection_map[ pos ].push_back( pin );
m_items.emplace_back( pin );
SCH_CONNECTION* conn = pin->InitializeConnection( aSheet, this );
updatePin( pin, conn );
connection_map[ pin->GetPosition() ].push_back( pin );
}
}
else
@@ -994,7 +1144,10 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
break;
case SCH_PIN_T:
conn->SetType( CONNECTION_TYPE::NET );
if( points.empty() )
points = { static_cast<SCH_PIN*>( item )->GetPosition() };
updatePin( static_cast<SCH_PIN*>( item ), conn );
break;
case SCH_BUS_WIRE_ENTRY_T:
@@ -1075,9 +1228,6 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
connected_item->SetLayer( busLine ? LAYER_BUS_JUNCTION : LAYER_JUNCTION );
}
SCH_ITEM_SET& connected_set = connected_item->ConnectedItems( aSheet );
connected_set.reserve( connection_vec.size() );
for( SCH_ITEM* test_item : connection_vec )
{
bool bus_connection_ok = true;
@@ -1111,7 +1261,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
test_item->ConnectionPropagatesTo( connected_item ) &&
bus_connection_ok )
{
connected_set.push_back( test_item );
connected_item->AddConnectionTo( aSheet, test_item );
}
}
@@ -1213,7 +1363,7 @@ void CONNECTION_GRAPH::buildItemSubGraphs()
connected_conn->SetSubgraphCode( subgraph->m_code );
m_item_to_subgraph_map[connected_item] = subgraph;
subgraph->AddItem( connected_item );
SCH_ITEM_SET& citemset = connected_item->ConnectedItems( sheet );
const SCH_ITEM_VEC& citemset = connected_item->ConnectedItems( sheet );
for( SCH_ITEM* citem : citemset )
{
@@ -1248,6 +1398,8 @@ void CONNECTION_GRAPH::resolveAllDrivers()
return candidate->m_dirty;
} );
wxLogTrace( ConnTrace, wxT( "Resolving drivers for %zu subgraphs" ), dirty_graphs.size() );
std::vector<std::future<size_t>> returns( dirty_graphs.size() );
auto update_lambda = []( CONNECTION_SUBGRAPH* subgraph ) -> size_t
@@ -1378,7 +1530,7 @@ void CONNECTION_GRAPH::generateBusAliasMembers()
for( CONNECTION_SUBGRAPH* subgraph : m_driver_subgraphs )
{
SCH_ITEM_SET vec = subgraph->GetAllBusLabels();
SCH_ITEM_VEC vec = subgraph->GetAllBusLabels();
for( SCH_ITEM* item : vec )
{
@@ -1556,14 +1708,20 @@ void CONNECTION_GRAPH::processSubGraphs()
if( !subgraph->m_strong_driver )
{
std::vector<CONNECTION_SUBGRAPH*>* vec = &m_net_name_to_subgraphs_map.at( name );
std::vector<CONNECTION_SUBGRAPH*> vec_empty;
std::vector<CONNECTION_SUBGRAPH*>* vec = &vec_empty;
if( m_net_name_to_subgraphs_map.count( name ) )
vec = &m_net_name_to_subgraphs_map.at( name );
// If we are a unique bus vector, check if we aren't actually unique because of another
// subgraph with a similar bus vector
if( vec->size() <= 1 && subgraph->m_driver_connection->Type() == CONNECTION_TYPE::BUS )
{
wxString prefixOnly = name.BeforeFirst( '[' ) + wxT( "[]" );
vec = &m_net_name_to_subgraphs_map.at( prefixOnly );
if( m_net_name_to_subgraphs_map.count( prefixOnly ) )
vec = &m_net_name_to_subgraphs_map.at( prefixOnly );
}
if( vec->size() > 1 )
@@ -1858,7 +2016,7 @@ void CONNECTION_GRAPH::processSubGraphs()
// on some portion of the items.
void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* aChangedItemHandler )
void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* aChangedItemHandler, bool aUnconditional )
{
// Recache all bus aliases for later use
wxCHECK_RET( m_schematic, wxT( "Connection graph cannot be built without schematic pointer" ) );
@@ -2216,6 +2374,17 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
for( const auto& [ netname, subgraphs ] : m_net_name_to_subgraphs_map )
checkNetclassDrivers( subgraphs );
if( !aUnconditional )
{
for( auto& [ netname, netclass ] : oldAssignments )
{
if( netSettings->m_NetClassLabelAssignments.count( netname ) )
continue;
netSettings->m_NetClassLabelAssignments[ netname ] = netclass;
}
}
}
@@ -2831,8 +3000,8 @@ CONNECTION_SUBGRAPH* CONNECTION_GRAPH::GetSubgraphForItem( SCH_ITEM* aItem )
}
const std::vector<CONNECTION_SUBGRAPH*> CONNECTION_GRAPH::GetAllSubgraphs(
const wxString& aNetName ) const
const std::vector<CONNECTION_SUBGRAPH*>
CONNECTION_GRAPH::GetAllSubgraphs( const wxString& aNetName ) const
{
std::vector<CONNECTION_SUBGRAPH*> subgraphs;
@@ -3647,6 +3816,33 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph )
if( label_map.empty() )
return true;
// No-connects on net neighbors will be noticed before, but to notice them on bus parents we
// need to walk the graph
for( auto pair : aSubgraph->m_bus_parents )
{
for( CONNECTION_SUBGRAPH* busParent : pair.second )
{
if( busParent->m_no_connect )
{
has_nc = true;
break;
}
CONNECTION_SUBGRAPH* hp = busParent->m_hier_parent;
while( hp )
{
if( hp->m_no_connect )
{
has_nc = true;
break;
}
hp = hp->m_hier_parent;
}
}
}
wxString netName = GetResolvedSubgraphName( aSubgraph );
wxCHECK_MSG( m_schematic, true, wxS( "Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" ) );
+17 -1
View File
@@ -199,6 +199,11 @@ public:
void RemoveItem( SCH_ITEM* aItem );
/**
* Replaces all references to #aOldItem with #aNewItem in the subgraph.
*/
void ExchangeItem( SCH_ITEM* aOldItem, SCH_ITEM* aNewItem );
// Use this to keep a connection pointer that is not owned by any item
// This will be destroyed with the subgraph
void StoreImplicitConnection( SCH_CONNECTION* aConnection )
@@ -301,6 +306,8 @@ private:
/// A cache of connections that are part of this subgraph but that don't have
/// an owning element (i.e. bus members)
std::set<SCH_CONNECTION*> m_bus_element_connections;
std::mutex m_driver_mutex;
};
struct NET_NAME_CODE_CACHE_KEY
@@ -454,6 +461,11 @@ public:
void RemoveItem( SCH_ITEM* aItem );
/**
* Replace all references to #aOldItem with #aNewItem in the graph.
*/
void ExchangeItem( SCH_ITEM* aOldItem, SCH_ITEM* aNewItem );
private:
/**
* Update the graphical connectivity between items (i.e. where they touch)
@@ -497,8 +509,12 @@ private:
* the driver is first selected by CONNECTION_SUBGRAPH::ResolveDrivers(),
* and then the connection for the chosen driver is propagated to all the
* other items in the subgraph.
*
* If the unconitional flag is set, all existing net classes will be removed
* and re-created. Otherwise, we will preserve existing net classes that do not
* conflict with the new net classes.
*/
void buildConnectionGraph( std::function<void( SCH_ITEM* )>* aChangedItemHandler );
void buildConnectionGraph( std::function<void( SCH_ITEM* )>* aChangedItemHandler, bool aUnconditional );
/**
* Generate individual item subgraphs on a per-sheet basis.
+18 -2
View File
@@ -23,6 +23,7 @@
#include <algorithm>
#include <bitmaps.h>
#include <connection_graph.h>
#include <string_utils.h> // WildCompareString
#include <kiway.h>
#include <refdes_utils.h>
@@ -47,6 +48,7 @@ bool g_resetFieldVisibilities[2] = { true, false };
bool g_resetFieldEffects[2] = { true, false };
bool g_resetFieldPositions[2] = { true, false };
bool g_resetAttributes[2] = { true, false };
bool g_resetCustomPower[2] = { false, false };
DIALOG_CHANGE_SYMBOLS::DIALOG_CHANGE_SYMBOLS( SCH_EDIT_FRAME* aParent, SCH_SYMBOL* aSymbol,
@@ -146,6 +148,7 @@ DIALOG_CHANGE_SYMBOLS::DIALOG_CHANGE_SYMBOLS( SCH_EDIT_FRAME* aParent, SCH_SYMBO
m_resetFieldEffects->SetValue( g_resetFieldEffects[ (int) m_mode ] );
m_resetFieldPositions->SetValue( g_resetFieldPositions[ (int) m_mode ] );
m_resetAttributes->SetValue( g_resetAttributes[ (int) m_mode ] );
m_resetCustomPower->SetValue( g_resetCustomPower[ (int) m_mode ] );
// DIALOG_SHIM needs a unique hash_key because classname is not sufficient
// because the update and change versions of this dialog have different controls.
@@ -227,6 +230,7 @@ DIALOG_CHANGE_SYMBOLS::~DIALOG_CHANGE_SYMBOLS()
g_resetFieldEffects[ (int) m_mode ] = m_resetFieldEffects->GetValue();
g_resetFieldPositions[ (int) m_mode ] = m_resetFieldPositions->GetValue();
g_resetAttributes[ (int) m_mode ] = m_resetAttributes->GetValue();
g_resetCustomPower[ (int) m_mode ] = m_resetCustomPower->GetValue();
}
@@ -599,7 +603,17 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
wxCHECK( screen, 0 );
screen->Remove( symbol );
aCommit->Modify( symbol, screen );
SCH_SYMBOL* symbol_copy = static_cast<SCH_SYMBOL*>( symbol->Clone() );
aCommit->Modified( symbol, symbol_copy, screen );
CONNECTION_GRAPH* connectionGraph = screen->Schematic()->ConnectionGraph();
// When we replace the lib symbol below, we free the associated pins if the new symbol has
// fewer than the original. This will cause the connection graph to be out of date unless
// we replace references in the graph to the old symbol/pins with references to the ones stored
// in the undo stack.
if( connectionGraph )
connectionGraph->ExchangeItem( symbol, symbol_copy );
}
for( const auto& [ symbol, symbol_change_info ] : symbols )
@@ -671,7 +685,9 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( SCH_COMMIT* aCommit,
}
else if( i == VALUE_FIELD )
{
symbol->SetValueFieldText( UnescapeString( libField->GetText() ) );
if( ( symbol->IsPower() && m_resetCustomPower->IsChecked() )
|| !symbol->IsPower() )
symbol->SetValueFieldText( UnescapeString( libField->GetText() ) );
}
else if( i == FOOTPRINT_FIELD )
{
@@ -146,6 +146,11 @@ DIALOG_CHANGE_SYMBOLS_BASE::DIALOG_CHANGE_SYMBOLS_BASE( wxWindow* parent, wxWind
m_resetAttributes = new wxCheckBox( m_updateOptionsSizer->GetStaticBox(), wxID_ANY, _("Update/reset symbol attributes"), wxDefaultPosition, wxDefaultSize, 0 );
m_updateOptionsSizer->Add( m_resetAttributes, 0, wxBOTTOM|wxRIGHT, 5 );
m_updateOptionsSizer->Add( 0, 10, 1, wxEXPAND, 5 );
m_resetCustomPower = new wxCheckBox( m_updateOptionsSizer->GetStaticBox(), wxID_ANY, _("Reset custom power symbols"), wxDefaultPosition, wxDefaultSize, 0 );
m_updateOptionsSizer->Add( m_resetCustomPower, 0, wxBOTTOM|wxRIGHT, 5 );
bSizerUpdate->Add( m_updateOptionsSizer, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 8 );
@@ -74,6 +74,7 @@ class DIALOG_CHANGE_SYMBOLS_BASE : public DIALOG_SHIM
wxCheckBox* m_resetFieldEffects;
wxCheckBox* m_resetFieldPositions;
wxCheckBox* m_resetAttributes;
wxCheckBox* m_resetCustomPower;
WX_HTML_REPORT_PANEL* m_messagePanel;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
+34 -13
View File
@@ -429,17 +429,28 @@ DIALOG_LIB_FIELD_PROPERTIES::DIALOG_LIB_FIELD_PROPERTIES( SCH_BASE_FRAME* aParen
if( m_fieldId == FOOTPRINT_FIELD )
{
LIB_SYMBOL* symbol = aField->GetParent();
wxString netlist;
/*
* Symbol netlist format:
* pinCount
* fpFilters
* pinNumber pinName <tab> pinNumber pinName...
* fpFilter fpFilter...
*/
netlist << wxString::Format( wxS( "%d\r" ), symbol->GetPinCount() );
wxString netlist;
wxArrayString fpFilters = symbol->GetFPFilters();
std::vector<LIB_PIN*> pinList;
aField->GetParent()->GetPins( pinList, 0, 1 ); // All units, but a single convert
wxArrayString pins;
for( LIB_PIN* pin : pinList )
pins.push_back( pin->GetNumber() + ' ' + pin->GetShownName() );
if( !pins.IsEmpty() )
netlist << EscapeString( wxJoin( pins, '\t' ), CTX_LINE );
netlist << wxS( "\r" );
wxArrayString fpFilters = aField->GetParent()->GetFPFilters();
if( !fpFilters.IsEmpty() )
netlist << EscapeString( wxJoin( fpFilters, ' ' ), CTX_LINE );
@@ -473,7 +484,7 @@ void DIALOG_LIB_FIELD_PROPERTIES::UpdateField( LIB_FIELD* aField )
}
DIALOG_SCH_FIELD_PROPERTIES::DIALOG_SCH_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent,
DIALOG_SCH_FIELD_PROPERTIES::DIALOG_SCH_FIELD_PROPERTIES( SCH_EDIT_FRAME* aParent,
const wxString& aTitle,
const SCH_FIELD* aField ) :
DIALOG_FIELD_PROPERTIES( aParent, aTitle, aField ),
@@ -483,17 +494,27 @@ DIALOG_SCH_FIELD_PROPERTIES::DIALOG_SCH_FIELD_PROPERTIES( SCH_BASE_FRAME* aParen
if( aField->GetParent() && aField->GetParent()->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aField->GetParent() );
wxString netlist;
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aField->GetParent() );
SCH_SHEET_PATH sheetPath = aParent->GetCurrentSheet();
m_fieldId = aField->GetId();
/*
* Symbol netlist format:
* pinCount
* fpFilters
* pinNumber pinName <tab> pinNumber pinName...
* fpFilter fpFilter...
*/
netlist << wxString::Format( wxS( "%zu\r" ), symbol->GetFullPinCount() );
wxString netlist;
wxArrayString pins;
for( SCH_PIN* pin : symbol->GetPins( &sheetPath ) )
pins.push_back( pin->GetNumber() + ' ' + pin->GetShownName() );
if( !pins.IsEmpty() )
netlist << EscapeString( wxJoin( pins, '\t' ), CTX_LINE );
netlist << wxS( "\r" );
wxArrayString fpFilters = symbol->GetLibSymbolRef()->GetFPFilters();
+1 -1
View File
@@ -136,7 +136,7 @@ public:
class DIALOG_SCH_FIELD_PROPERTIES : public DIALOG_FIELD_PROPERTIES
{
public:
DIALOG_SCH_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent, const wxString& aTitle,
DIALOG_SCH_FIELD_PROPERTIES( SCH_EDIT_FRAME* aParent, const wxString& aTitle,
const SCH_FIELD* aField );
~DIALOG_SCH_FIELD_PROPERTIES() {}
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-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
@@ -594,7 +594,7 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataFromWindow()
if( !commit.Empty() )
{
commit.Push( _( "Edit Text and Graphics" ), SKIP_CONNECTIVITY );
commit.Push( _( "Edit Text and Graphics" ) );
m_parent->HardRedraw();
}
+2 -2
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2018-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
@@ -72,7 +72,7 @@ bool DIALOG_IMAGE_PROPERTIES::TransferDataFromWindow()
m_bitmap->SetPosition( VECTOR2I( m_posX.GetValue(), m_posY.GetValue() ) );
if( !commit.Empty() )
commit.Push( _( "Image Properties" ), SKIP_CONNECTIVITY );
commit.Push( _( "Image Properties" ) );
return true;
}
+2 -3
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-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
@@ -110,8 +110,7 @@ bool DIALOG_JUNCTION_PROPS::TransferDataFromWindow()
m_frame->GetCanvas()->GetView()->Update( junction );
}
commit.Push( m_junctions.size() == 1 ? _( "Edit Junction" ) : _( "Edit Junctions" ),
SKIP_CONNECTIVITY );
commit.Push( m_junctions.size() == 1 ? _( "Edit Junction" ) : _( "Edit Junctions" ) );
return true;
}
+2 -2
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-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
@@ -599,7 +599,7 @@ bool DIALOG_LABEL_PROPERTIES::TransferDataFromWindow()
m_currentLabel->AutoAutoplaceFields( m_Parent->GetScreen() );
if( !commit.Empty() )
commit.Push( _( "Edit Label" ), SKIP_CONNECTIVITY );
commit.Push( _( "Edit Label Properties" ) );
return true;
}
+2 -2
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Seth Hillbrand <hillbrand@ucdavis.edu>
* Copyright (C) 2014-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2014-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
@@ -149,6 +149,6 @@ bool DIALOG_LINE_PROPERTIES::TransferDataFromWindow()
line->SetLineColor( m_colorSwatch->GetSwatchColor() );
}
commit.Push( m_lines.size() == 1 ? _( "Edit Line" ) : _( "Edit Lines" ), SKIP_CONNECTIVITY );
commit.Push( m_lines.size() == 1 ? _( "Edit Line" ) : _( "Edit Lines" ) );
return true;
}
+2 -3
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2021-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
@@ -166,8 +166,7 @@ bool DIALOG_SHAPE_PROPERTIES::TransferDataFromWindow()
if( !commit.Empty() )
{
commit.Push( wxString::Format( _( "Edit %s" ), m_shape->EDA_SHAPE::GetFriendlyName() ),
SKIP_CONNECTIVITY );
commit.Push( wxString::Format( _( "Edit %s" ), m_shape->EDA_SHAPE::GetFriendlyName() ) );
}
return true;
+41 -12
View File
@@ -34,6 +34,7 @@
#include <wildcards_and_files_ext.h>
#include <widgets/std_bitmap_button.h>
#include <kiplatform/ui.h>
#include <sch_commit.h>
#include <sch_edit_frame.h>
#include <sch_sheet.h>
#include <schematic.h>
@@ -45,10 +46,12 @@
#include "wx/dcclient.h"
DIALOG_SHEET_PROPERTIES::DIALOG_SHEET_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_SHEET* aSheet,
bool* aClearAnnotationNewItems ) :
bool* aClearAnnotationNewItems,
bool* aUpdateHierarchyNavigator ) :
DIALOG_SHEET_PROPERTIES_BASE( aParent ),
m_frame( aParent ),
m_clearAnnotationNewItems( aClearAnnotationNewItems ),
m_updateHierarchyNavigator( aUpdateHierarchyNavigator ),
m_borderWidth( aParent, m_borderWidthLabel, m_borderWidthCtrl, m_borderWidthUnits ),
m_dummySheet( *aSheet ),
m_dummySheetNameField( VECTOR2I( -1, -1 ), SHEETNAME, &m_dummySheet )
@@ -257,9 +260,17 @@ static bool positioningChanged( FIELDS_GRID_TABLE<SCH_FIELD>* a, std::vector<SCH
bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
{
wxCHECK( m_sheet && m_frame, false );
if( !wxDialog::TransferDataFromWindow() ) // Calls our Validate() method.
return false;
SCH_COMMIT commit( m_frame );
commit.Modify( m_sheet, m_frame->GetScreen() );
bool isUndoable = true;
// Sheet file names can be relative or absolute.
wxString sheetFileName = m_fields->at( SHEETFILENAME ).GetText();
@@ -328,13 +339,17 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
}
}
if( !onSheetFilenameChanged( newRelativeFilename ) )
if( !onSheetFilenameChanged( newRelativeFilename, &isUndoable ) )
{
if( clearFileName )
currentScreen->SetFileName( wxEmptyString );
return false;
}
else if( m_updateHierarchyNavigator )
{
*m_updateHierarchyNavigator = true;
}
if( clearFileName )
currentScreen->SetFileName( wxEmptyString );
@@ -345,6 +360,9 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
wxString newSheetname = m_fields->at( SHEETNAME ).GetText();
if( ( newSheetname != m_sheet->GetName() ) && m_updateHierarchyNavigator )
*m_updateHierarchyNavigator = true;
if( newSheetname.IsEmpty() )
newSheetname = _( "Untitled Sheet" );
@@ -407,14 +425,26 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
for( SCH_ITEM* item : m_frame->GetScreen()->Items().OfType( SCH_SHEET_T ) )
m_frame->UpdateItem( item );
m_frame->OnModify();
if( isUndoable )
{
commit.Push( _( "Edit Sheet Properties" ) );
}
else
{
// If we are renaming files, the undo/redo list becomes invalid and must be cleared.
m_frame->ClearUndoRedoList();
m_frame->OnModify();
}
return true;
}
bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilename )
bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilename,
bool* aIsUndoable )
{
wxCHECK( aIsUndoable, false );
wxString msg;
wxFileName sheetFileName(
EnsureFileExtension( aNewFilename, FILEEXT::KiCadSchematicFileExtension ) );
@@ -494,7 +524,6 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
}
else // Existing sheet.
{
bool isUndoable = true;
isExistingSheet = true;
if( !m_frame->AllowCaseSensitiveFileNameClashes( newAbsoluteFilename ) )
@@ -515,7 +544,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
if( newAbsoluteFilename.Cmp( oldAbsoluteFilename ) != 0 )
{
// Sheet file name changes cannot be undone.
isUndoable = false;
*aIsUndoable = false;
if( useScreen || loadFromFile ) // Load from existing file.
{
@@ -553,12 +582,6 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
}
}
// If we are renaming files, the undo/redo list becomes invalid and must be cleared
if( isUndoable )
m_frame->SaveCopyInUndoList( m_frame->GetScreen(), m_sheet, UNDO_REDO::CHANGED, false );
else
m_frame->ClearUndoRedoList();
if( renameFile )
{
IO_RELEASER<SCH_IO> pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_KICAD ) );
@@ -614,6 +637,12 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
// It's safe to set the sheet screen now.
m_sheet->SetScreen( useScreen );
SCH_SHEET_LIST sheetHierarchy( m_sheet ); // The hierarchy of the loaded file.
sheetHierarchy.AddNewSymbolInstances( currentSheet );
sheetHierarchy.AddNewSheetInstances( currentSheet,
fullHierarchy.GetLastVirtualPageNumber() );
}
else if( loadFromFile )
{
+5 -3
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2014-2020 KiCad Developers, see AUTHORS.TXT for contributors.
* Copyright (C) 2014-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
@@ -38,12 +38,13 @@ class DIALOG_SHEET_PROPERTIES : public DIALOG_SHEET_PROPERTIES_BASE
{
public:
DIALOG_SHEET_PROPERTIES( SCH_EDIT_FRAME* aParent, SCH_SHEET* aSheet,
bool* aClearAnnotationNewItems );
bool* aClearAnnotationNewItems,
bool* aUpdateHierarchyNavigator );
~DIALOG_SHEET_PROPERTIES() override;
private:
bool onSheetFilenameChanged( const wxString& aNewFilename );
bool onSheetFilenameChanged( const wxString& aNewFilename, bool* aIsUndoable );
bool TransferDataToWindow() override;
bool TransferDataFromWindow() override;
@@ -66,6 +67,7 @@ private:
SCH_EDIT_FRAME* m_frame;
SCH_SHEET* m_sheet;
bool* m_clearAnnotationNewItems;
bool* m_updateHierarchyNavigator;
wxSize m_size;
int m_delayedFocusRow;
@@ -146,13 +146,17 @@ protected:
{
if( m_fieldsCtrl->GetTextValue( row, FIELD_NAME_COLUMN ) == fieldName )
{
m_fieldsCtrl->SetToggleValue( show, row, SHOW_FIELD_COLUMN );
if( m_grid->CommitPendingChanges( false ) )
m_fieldsCtrl->SetToggleValue( show, row, SHOW_FIELD_COLUMN );
break;
}
}
}
else
{
GRID_TRICKS::doPopupSelection( event );
}
}
}
@@ -1039,6 +1043,10 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnTableCellClick( wxGridEvent& event )
void DIALOG_SYMBOL_FIELDS_TABLE::OnTableRangeSelected( wxGridRangeSelectEvent& aEvent )
{
// Cross-probing should only work in Edit page
if( m_nbPages->GetSelection() != 0 )
return;
// Multi-select can grab the rows that are expanded child refs, and also the row
// containing the list of all child refs. Make sure we add refs/symbols uniquely
std::set<SCH_REFERENCE> refs;
@@ -1063,10 +1071,10 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnTableRangeSelected( wxGridRangeSelectEvent& a
if( refs.size() > 0 )
{
// Use of full path based on UUID allows select of not yet annotated or duplicaded symbols
// Use of full path based on UUID allows select of not yet annotated or duplicated symbols
wxString symbol_path = refs.begin()->GetFullPath();
// Focus only handles on item at this time
// Focus only handles one item at this time
editor->FindSymbolAndItem( &symbol_path, nullptr, true, HIGHLIGHT_SYMBOL,
wxEmptyString );
}
@@ -1288,6 +1296,7 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnExport( wxCommandEvent& aEvent )
return;
}
out.Close(); // close the file before we tell the user it's done with the info modal :workflow meme:
msg.Printf( _( "Wrote BOM output to '%s'" ), outputFile.GetFullPath() );
DisplayInfoMessage( this, msg );
}
+1 -1
View File
@@ -536,7 +536,7 @@ bool DIALOG_TEXT_PROPERTIES::TransferDataFromWindow()
}
if( !commit.Empty() )
commit.Push( _( "Edit Text" ), SKIP_CONNECTIVITY );
commit.Push( _( "Edit Text Properties" ) );
return true;
}
+13
View File
@@ -126,6 +126,19 @@ SCHEMATIC* EESCHEMA_HELPERS::LoadSchematic( wxString& aFileName, SCH_IO_MGR::SCH
SCHEMATIC* schematic = new SCHEMATIC( project );
SCH_SHEET* rootSheet = new SCH_SHEET( schematic );
schematic->SetRoot( rootSheet );
SCH_SCREEN* rootScreen = new SCH_SCREEN( schematic );
const_cast<KIID&>( rootSheet->m_Uuid ) = rootScreen->GetUuid();
schematic->Root().SetScreen( rootScreen );
schematic->RootScreen()->SetFileName( wxEmptyString );
// Don't leave root page number empty
schematic->RootScreen()->SetPageNumber( wxT( "1" ) );
wxFileName schFile = aFileName;
schFile.MakeAbsolute();
+5 -1
View File
@@ -559,6 +559,7 @@ int ERC_TESTER::TestMissingNetclasses()
{
int err_count = 0;
std::shared_ptr<NET_SETTINGS>& settings = m_schematic->Prj().GetProjectFile().NetSettings();
wxString defaultNetclass = settings->m_DefaultNetClass->GetName();
auto logError =
[&]( const SCH_SHEET_PATH& sheet, SCH_ITEM* item, const wxString& netclass )
@@ -590,8 +591,11 @@ int ERC_TESTER::TestMissingNetclasses()
{
wxString netclass = field->GetText();
if( settings->m_NetClasses.count( netclass ) == 0 )
if( !netclass.IsSameAs( defaultNetclass )
&& settings->m_NetClasses.count( netclass ) == 0 )
{
logError( sheet, item, netclass );
}
}
}
+27 -7
View File
@@ -62,16 +62,24 @@ enum
static wxString netList( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH& aSheetPath )
{
wxCHECK( aSymbol && aSymbol->GetLibSymbolRef(), wxEmptyString );
/*
* Symbol netlist format:
* pinCount
* fpFilters
* pinNumber pinName <tab> pinNumber pinName...
* fpFilter fpFilter...
*/
wxString netlist;
netlist << wxString::Format( wxS( "%zu\r" ), aSymbol->GetFullPinCount() );
wxArrayString pins;
wxCHECK( aSymbol && aSymbol->GetLibSymbolRef(), wxEmptyString );
for( SCH_PIN* pin : aSymbol->GetPins( &aSheetPath ) )
pins.push_back( pin->GetNumber() + ' ' + pin->GetShownName() );
if( !pins.IsEmpty() )
netlist << EscapeString( wxJoin( pins, '\t' ), CTX_LINE );
netlist << wxS( "\r" );
wxArrayString fpFilters = aSymbol->GetLibSymbolRef()->GetFPFilters();
@@ -88,12 +96,24 @@ static wxString netList( LIB_SYMBOL* aSymbol )
{
/*
* Symbol netlist format:
* pinCount
* fpFilters
* pinNumber pinName <tab> pinNumber pinName...
* fpFilter fpFilter...
*/
wxString netlist;
netlist << wxString::Format( wxS( "%d\r" ), aSymbol->GetPinCount() );
std::vector<LIB_PIN*> pinList;
aSymbol->GetPins( pinList, 0, 1 ); // All units, but a single convert
wxArrayString pins;
for( LIB_PIN* pin : pinList )
pins.push_back( pin->GetNumber() + ' ' + pin->GetShownName() );
if( !pins.IsEmpty() )
netlist << EscapeString( wxJoin( pins, '\t' ), CTX_LINE );
netlist << wxS( "\r" );
wxArrayString fpFilters = aSymbol->GetFPFilters();
+1
View File
@@ -267,6 +267,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
// Make ${SHEETNAME} work on the root sheet until we properly support
// naming the root sheet
Schematic().Root().SetName( _( "Root" ) );
wxLogDebug( "Loaded schematic with root sheet UUID %s", Schematic().Root().m_Uuid.AsString() );
}
if( !pi->GetError().IsEmpty() )
+47
View File
@@ -23,6 +23,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <i18n_utility.h>
#include <pgm_base.h>
#include <font/font.h>
#include <settings/settings_manager.h>
@@ -183,3 +184,49 @@ void LIB_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
aLayers[1] = LAYER_DEVICE_BACKGROUND;
aLayers[2] = LAYER_SELECTION_SHADOWS;
}
static struct LIB_ITEM_DESC
{
LIB_ITEM_DESC()
{
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( LIB_ITEM );
propMgr.AddTypeCast( new TYPE_CAST<LIB_ITEM, EDA_ITEM> );
propMgr.InheritsAfter( TYPE_HASH( LIB_ITEM ), TYPE_HASH( EDA_ITEM ) );
auto multiUnit =
[=]( INSPECTABLE* aItem ) -> bool
{
if( LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( aItem ) )
{
if( LIB_SYMBOL* symbol = libItem->GetParent() )
return symbol->IsMulti();
}
return false;
};
auto multiBodyStyle =
[=]( INSPECTABLE* aItem ) -> bool
{
if( LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( aItem ) )
{
if( LIB_SYMBOL* symbol = libItem->GetParent() )
return symbol->HasAlternateBodyStyle();
}
return false;
};
propMgr.AddProperty( new PROPERTY<LIB_ITEM, int>( _HKI( "Unit" ),
&LIB_ITEM::SetUnit, &LIB_ITEM::GetUnit ) )
.SetAvailableFunc( multiUnit );
propMgr.AddProperty( new PROPERTY<LIB_ITEM, int>( _HKI( "Body Style" ),
&LIB_ITEM::SetBodyStyle, &LIB_ITEM::GetBodyStyle ) )
.SetAvailableFunc( multiBodyStyle );
propMgr.AddProperty( new PROPERTY<LIB_ITEM, bool>( _HKI( "Private" ),
&LIB_ITEM::SetPrivate, &LIB_ITEM::IsPrivate ) );
}
} _LIB_ITEM_DESC;
+2 -1
View File
@@ -1661,7 +1661,8 @@ static struct LIB_PIN_DESC
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
REGISTER_TYPE( LIB_PIN );
propMgr.InheritsAfter( TYPE_HASH( LIB_PIN ), TYPE_HASH( SCH_ITEM ) );
propMgr.AddTypeCast( new TYPE_CAST<LIB_PIN, LIB_ITEM> );
propMgr.InheritsAfter( TYPE_HASH( LIB_PIN ), TYPE_HASH( LIB_ITEM ) );
propMgr.AddProperty( new PROPERTY<LIB_PIN, wxString>( _HKI( "Pin Name" ),
&LIB_PIN::SetName, &LIB_PIN::GetName ) );
+2 -1
View File
@@ -600,7 +600,8 @@ static struct LIB_SHAPE_DESC
FILL_T ( LIB_SHAPE::*fillModeGetter )() const = &LIB_SHAPE::GetFillMode;
propMgr.AddProperty( new PROPERTY_ENUM< LIB_SHAPE, FILL_T>( _HKI( "Fill" ),
fillModeSetter, fillModeGetter ) );
fillModeSetter, fillModeGetter ),
_HKI( "Shape Properties" ) );
}
} _LIB_SHAPE_DESC;
+3 -1
View File
@@ -703,7 +703,9 @@ const wxString LIB_SYMBOL::GetLibraryName() const
bool LIB_SYMBOL::IsPower() const
{
if( LIB_SYMBOL_SPTR parent = m_parent.lock() )
std::shared_ptr<LIB_SYMBOL> parent;
if( !m_parent.expired() && ( parent = m_parent.lock() ) )
{
if( parent->IsRoot() )
return parent->m_options == ENTRY_POWER;
+20 -1
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2004-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-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
@@ -424,6 +424,25 @@ std::vector<VECTOR2I> SCH_BUS_ENTRY_BASE::GetConnectionPoints() const
}
bool SCH_BUS_ENTRY_BASE::HasConnectivityChanges( const SCH_ITEM* aItem,
const SCH_SHEET_PATH* aInstance ) const
{
// Do not compare to ourself.
if( aItem == this )
return false;
const SCH_BUS_ENTRY_BASE* busEntry = dynamic_cast<const SCH_BUS_ENTRY_BASE*>( aItem );
// Don't compare against a different SCH_ITEM.
wxCHECK( busEntry, false );
if( GetPosition() != busEntry->GetPosition() )
return true;
return GetEnd() != busEntry->GetEnd();
}
wxString SCH_BUS_WIRE_ENTRY::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
{
return wxString( _( "Bus to Wire Entry" ) );
+4 -1
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 2004-2021 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2004-2024 KiCad Developers, see change_log.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
@@ -108,6 +108,9 @@ public:
bool IsConnectable() const override { return true; }
bool HasConnectivityChanges( const SCH_ITEM* aItem,
const SCH_SHEET_PATH* aInstance = nullptr ) const override;
std::vector<VECTOR2I> GetConnectionPoints() const override;
VECTOR2I GetPosition() const override { return m_pos; }
+34 -9
View File
@@ -211,23 +211,28 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
if( schItem->IsSelected() )
selectedModified = true;
if( !( aCommitFlags & SKIP_CONNECTIVITY ) && schItem->IsConnectable() )
auto updateConnectivityFlag = [&, this]()
{
dirtyConnectivity = true;
if( schItem->IsConnectable() )
{
dirtyConnectivity = true;
// Do a local clean up if there are any connectable objects in the commit.
if( connectivityCleanUp == NO_CLEANUP )
connectivityCleanUp = LOCAL_CLEANUP;
// Do a local clean up if there are any connectable objects in the commit.
if( connectivityCleanUp == NO_CLEANUP )
connectivityCleanUp = LOCAL_CLEANUP;
// Do a full rebauild of the connectivity if there is a sheet in the commit.
if( schItem->Type() == SCH_SHEET_T )
connectivityCleanUp = GLOBAL_CLEANUP;
}
// Do a full rebauild of the connectivity if there is a sheet in the commit.
if( schItem->Type() == SCH_SHEET_T )
connectivityCleanUp = GLOBAL_CLEANUP;
}
};
switch( changeType )
{
case CHT_ADD:
{
updateConnectivityFlag();
if( !( aCommitFlags & SKIP_UNDO ) )
undoList.PushItem( ITEM_PICKER( screen, schItem, UNDO_REDO::NEWITEM ) );
@@ -250,6 +255,8 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
case CHT_REMOVE:
{
updateConnectivityFlag();
if( !( aCommitFlags & SKIP_UNDO ) )
undoList.PushItem( ITEM_PICKER( screen, schItem, UNDO_REDO::DELETED ) );
@@ -290,6 +297,19 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
ITEM_PICKER itemWrapper( screen, schItem, UNDO_REDO::CHANGED );
wxASSERT( ent.m_copy );
itemWrapper.SetLink( ent.m_copy );
const SCH_ITEM* itemCopy = static_cast<const SCH_ITEM*>( ent.m_copy );
wxCHECK2( itemCopy, continue );
SCH_SHEET_PATH currentSheet;
if( frame )
currentSheet = frame->GetCurrentSheet();
if( itemCopy->HasConnectivityChanges( schItem, &currentSheet ) )
updateConnectivityFlag();
undoList.PushItem( itemWrapper );
ent.m_copy = nullptr; // We've transferred ownership to the undo list
}
@@ -339,7 +359,12 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED, false, dirtyConnectivity );
if( dirtyConnectivity )
{
wxLogTrace( wxS( "CONN_PROFILE" ),
wxS( "SCH_COMMIT::pushSchEdit() %s clean up connectivity rebuild." ),
( connectivityCleanUp == LOCAL_CLEANUP ) ? wxS( "local" ) : wxS( "global" ) );
frame->RecalculateConnections( this, connectivityCleanUp );
}
}
}
+1 -2
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2024 KiCad Developers, see AUTHORS.txt for contributors.
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@@ -40,7 +40,6 @@ class EE_TOOL_BASE;
#define SKIP_UNDO 0x0001
#define APPEND_UNDO 0x0002
#define SKIP_SET_DIRTY 0x0004
#define SKIP_CONNECTIVITY 0x0008
class SCH_COMMIT : public COMMIT
{
+29 -20
View File
@@ -1718,7 +1718,7 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FL
{
PICKED_ITEMS_LIST* changed_list = m_undoList.m_CommandsList.back();
std::set<SCH_ITEM*> changed_items;
std::vector<VECTOR2I> pts;
std::set<VECTOR2I> pts;
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> item_paths;
for( unsigned ii = 0; ii < changed_list->GetCount(); ++ii )
@@ -1733,23 +1733,47 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FL
SCH_SHEET_PATHS& paths = screen->GetClientSheetPaths();
std::vector<VECTOR2I> tmp_pts = item->GetConnectionPoints();
pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
pts.insert( tmp_pts.begin(), tmp_pts.end() );
changed_items.insert( item );
for( SCH_SHEET_PATH& path : paths )
item_paths.insert( std::make_pair( path, item ) );
item = dynamic_cast<SCH_ITEM*>( changed_list->GetPickedItemLink( ii ) );
if( !item || !item->IsConnectable() )
continue;
tmp_pts = item->GetConnectionPoints();
pts.insert( tmp_pts.begin(), tmp_pts.end() );
changed_items.insert( item );
// We have to directly add the pins here because the link may not exist on the schematic
// anymore and so won't be picked up by GetScreen()->Items().Overlapping() below.
if( SCH_SYMBOL* symbol = dynamic_cast<SCH_SYMBOL*>( item ) )
{
std::vector<SCH_PIN*> pins = symbol->GetPins();
changed_items.insert( pins.begin(), pins.end() );
}
for( SCH_SHEET_PATH& path : paths )
item_paths.insert( std::make_pair( path, item ) );
}
for( VECTOR2I& pt: pts )
for( const VECTOR2I& pt: pts )
{
for( SCH_ITEM* item : GetScreen()->Items().Overlapping( pt ) )
{
// Leave this check in place. Overlapping items are not necessarily connectable.
if( !item->IsConnectable() )
continue;
if( item->Type() == SCH_LINE_T )
{
if( item->HitTest( pt ) )
changed_items.insert( item );
}
else if( item->Type() == SCH_SYMBOL_T )
else if( item->Type() == SCH_SYMBOL_T && item->IsConnected( pt ) )
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
std::vector<SCH_PIN*> pins = symbol->GetPins();
@@ -1767,7 +1791,6 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FL
}
else
{
// Non-connectable objects have already been pruned.
if( item->IsConnected( pt ) )
changed_items.insert( item );
}
@@ -1786,21 +1809,7 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_COMMIT* aCommit, SCH_CLEANUP_FL
for( auto&[ path, item ] : all_items )
{
wxCHECK2( item, continue );
switch( item->Type() )
{
case SCH_FIELD_T:
case SCH_PIN_T:
{
SCH_ITEM* parent = static_cast<SCH_ITEM*>( item->GetParent() );
wxCHECK2( parent, continue );
parent->SetConnectivityDirty();
break;
}
default:
item->SetConnectivityDirty();
}
item->SetConnectivityDirty();
}
new_graph.Recalculate( list, false, &changeHandler );
+4 -1
View File
@@ -574,9 +574,12 @@ public:
* this sheet need to have their annotation cleared i.e. when an existing item list is used.
* it can happens when the edited sheet used an existing file, or becomes a new instance
* of a already existing sheet.
* @param aUpdateHierarchyNavigator is an optional flag to indicate the sheet changes require
* the hierarchy navigator panel to be updated.
*/
bool EditSheetProperties( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy,
bool* aClearAnnotationNewItems );
bool* aClearAnnotationNewItems,
bool* aUpdateHierarchyNavigator = nullptr );
void InitSheet( SCH_SHEET* aSheet, const wxString& aNewFilename );
+6 -1
View File
@@ -332,7 +332,12 @@ SCH_FIELD::GetRenderCache( const wxString& forResolvedText, const VECTOR2I& forP
VECTOR2I delta = forPosition - m_renderCachePos;
for( std::unique_ptr<KIFONT::GLYPH>& glyph : m_renderCache )
static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( delta );
{
if( glyph->IsOutline() )
static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() )->Move( delta );
else
static_cast<KIFONT::STROKE_GLYPH*>( glyph.get() )->Move( delta );
}
m_renderCachePos = forPosition;
}
+161 -125
View File
@@ -24,19 +24,21 @@
#include <iostream>
#include <unordered_map>
#include <charconv>
#include <base_units.h>
#include <ki_exception.h>
#include <wx/log.h>
#include "io/altium/altium_parser.h"
#include "sch_io/altium/altium_parser_sch.h"
#include "io/altium/altium_binary_parser.h"
#include "io/altium/altium_props_utils.h"
ALTIUM_SCH_RECORD ReadRecord( const std::map<wxString, wxString>& aProps )
{
int recordId = ALTIUM_PARSER::ReadInt( aProps, "RECORD", -1 );
int recordId = ALTIUM_PROPS_UTILS::ReadInt( aProps, "RECORD", -1 );
return static_cast<ALTIUM_SCH_RECORD>( recordId );
}
@@ -55,8 +57,8 @@ constexpr int Altium2KiCadUnit( const int val, const int frac )
int ReadKiCadUnitFrac( const std::map<wxString, wxString>& aProps, const wxString& aKey )
{
// a unit is stored using two fields, denoting the size in mils and a fraction size
int key = ALTIUM_PARSER::ReadInt( aProps, aKey, 0 );
int keyFrac = ALTIUM_PARSER::ReadInt( aProps, aKey + "_FRAC", 0 );
int key = ALTIUM_PROPS_UTILS::ReadInt( aProps, aKey, 0 );
int keyFrac = ALTIUM_PROPS_UTILS::ReadInt( aProps, aKey + "_FRAC", 0 );
return Altium2KiCadUnit( key, keyFrac );
}
@@ -65,21 +67,21 @@ int ReadKiCadUnitFrac1( const std::map<wxString, wxString>& aProps, const wxStri
{
// a unit is stored using two fields, denoting the size in mils and a fraction size
// Dunno why Altium invents different units for the same purpose
int key = ALTIUM_PARSER::ReadInt( aProps, aKey, 0 );
int keyFrac = ALTIUM_PARSER::ReadInt( aProps, aKey + "_FRAC1", 0 );
int key = ALTIUM_PROPS_UTILS::ReadInt( aProps, aKey, 0 );
int keyFrac = ALTIUM_PROPS_UTILS::ReadInt( aProps, aKey + "_FRAC1", 0 );
return Altium2KiCadUnit( key * 10, keyFrac );
}
int ReadOwnerIndex( const std::map<wxString, wxString>& aProperties )
{
return ALTIUM_PARSER::ReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE );
return ALTIUM_PROPS_UTILS::ReadInt( aProperties, "OWNERINDEX", ALTIUM_COMPONENT_NONE );
}
int ReadOwnerPartId( const std::map<wxString, wxString>& aProperties )
{
return ALTIUM_PARSER::ReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE );
return ALTIUM_PROPS_UTILS::ReadInt( aProperties, "OWNERPARTID", ALTIUM_COMPONENT_NONE );
}
@@ -87,7 +89,7 @@ template <typename T>
T ReadEnum( const std::map<wxString, wxString>& aProps, const wxString& aKey, int aLower,
int aUpper, T aDefault )
{
int value = ALTIUM_PARSER::ReadInt( aProps, aKey, static_cast<int>( aDefault ) );
int value = ALTIUM_PROPS_UTILS::ReadInt( aProps, aKey, static_cast<int>( aDefault ) );
if( value < aLower || value > aUpper )
return aDefault;
@@ -96,7 +98,41 @@ T ReadEnum( const std::map<wxString, wxString>& aProps, const wxString& aKey, in
}
ASCH_STORAGE_FILE::ASCH_STORAGE_FILE( ALTIUM_PARSER& aReader )
ASCH_STORAGE_FILE::ASCH_STORAGE_FILE( const std::map<wxString, wxString>& aProps )
{
filename = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" );
size_t dataSize = ALTIUM_PROPS_UTILS::ReadInt( aProps, "DATA_LEN", 0 );
wxString hexData = ALTIUM_PROPS_UTILS::ReadString( aProps, "DATA", "" );
const size_t charCount = hexData.size();
if( charCount != dataSize * 2 )
{
THROW_IO_ERROR( wxString::Format( "Invalid binary file hex data size. Chars expected: %d, "
"hex string length: %d",
int( dataSize * 2 ), int( hexData.size() ) ) );
}
data.resize( dataSize );
char str[3] = { 0 };
uint8_t b = 0;
size_t outputId = 0;
for( size_t inputId = 1; inputId < charCount; inputId += 2 )
{
str[0] = (char) hexData[inputId - 1];
str[1] = (char) hexData[inputId];
std::from_chars( str, str + 2, b, 16 );
data[outputId] = b;
outputId++;
}
}
ASCH_STORAGE_FILE::ASCH_STORAGE_FILE( ALTIUM_BINARY_PARSER& aReader )
{
aReader.Skip( 5 );
filename = aReader.ReadWxString();
@@ -108,7 +144,7 @@ ASCH_STORAGE_FILE::ASCH_STORAGE_FILE( ALTIUM_PARSER& aReader )
}
ASCH_ADDITIONAL_FILE::ASCH_ADDITIONAL_FILE( ALTIUM_PARSER& aReader )
ASCH_ADDITIONAL_FILE::ASCH_ADDITIONAL_FILE( ALTIUM_BINARY_PARSER& aReader )
{
aReader.Skip( 5 );
FileName = aReader.ReadWxString();
@@ -124,23 +160,23 @@ ASCH_SYMBOL::ASCH_SYMBOL( const std::map<wxString, wxString>& aProps )
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::COMPONENT );
currentpartid = ALTIUM_PARSER::ReadInt( aProps, "CURRENTPARTID", ALTIUM_COMPONENT_NONE );
libreference = ALTIUM_PARSER::ReadString( aProps, "LIBREFERENCE", "" );
sourcelibraryname = ALTIUM_PARSER::ReadString( aProps, "SOURCELIBRARYNAME", "" );
componentdescription = ALTIUM_PARSER::ReadString( aProps, "COMPONENTDESCRIPTION", "" );
currentpartid = ALTIUM_PROPS_UTILS::ReadInt( aProps, "CURRENTPARTID", ALTIUM_COMPONENT_NONE );
libreference = ALTIUM_PROPS_UTILS::ReadString( aProps, "LIBREFERENCE", "" );
sourcelibraryname = ALTIUM_PROPS_UTILS::ReadString( aProps, "SOURCELIBRARYNAME", "" );
componentdescription = ALTIUM_PROPS_UTILS::ReadString( aProps, "COMPONENTDESCRIPTION", "" );
orientation = ALTIUM_PARSER::ReadInt( aProps, "ORIENTATION", 0 );
isMirrored = ALTIUM_PARSER::ReadBool( aProps, "ISMIRRORED", false );
orientation = ALTIUM_PROPS_UTILS::ReadInt( aProps, "ORIENTATION", 0 );
isMirrored = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISMIRRORED", false );
location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
partcount = ALTIUM_PARSER::ReadInt( aProps, "PARTCOUNT", 0 );
displaymodecount = ALTIUM_PARSER::ReadInt( aProps, "DISPLAYMODECOUNT", 0 );
m_indexInSheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", -1 );
partcount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "PARTCOUNT", 0 );
displaymodecount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "DISPLAYMODECOUNT", 0 );
m_indexInSheet = ALTIUM_PROPS_UTILS::ReadInt( aProps, "INDEXINSHEET", -1 );
// DISPLAYMODE may be a string. Leave displaymode at 0 in this case.
displaymode = 0;
wxString displayModeStr = ALTIUM_PARSER::ReadString( aProps, "DISPLAYMODE", "" );
wxString displayModeStr = ALTIUM_PROPS_UTILS::ReadString( aProps, "DISPLAYMODE", "" );
long v = 0;
@@ -154,7 +190,7 @@ ASCH_TEMPLATE::ASCH_TEMPLATE( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::TEMPLATE );
filename = ALTIUM_PARSER::ReadString( aProps, "FILENAME", "" );
filename = ALTIUM_PROPS_UTILS::ReadString( aProps, "FILENAME", "" );
}
@@ -163,29 +199,29 @@ ASCH_PIN::ASCH_PIN( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::PIN );
isKiCadLibPin = ALTIUM_PARSER::ReadBool( aProps, "ISKICADLIBPIN", false );
ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 );
isKiCadLibPin = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISKICADLIBPIN", false );
ownerpartdisplaymode = ALTIUM_PROPS_UTILS::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 );
name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" );
text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" );
designator = ALTIUM_PARSER::ReadString( aProps, "DESIGNATOR", "" );
name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" );
text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" );
designator = ALTIUM_PROPS_UTILS::ReadString( aProps, "DESIGNATOR", "" );
int symbolOuterInt = ALTIUM_PARSER::ReadInt( aProps, "SYMBOL_OUTER", 0 );
int symbolOuterInt = ALTIUM_PROPS_UTILS::ReadInt( aProps, "SYMBOL_OUTER", 0 );
symbolOuter = ASCH_PIN_SYMBOL::FromInt( symbolOuterInt );
int symbolInnerInt = ALTIUM_PARSER::ReadInt( aProps, "SYMBOL_INNER", 0 );
int symbolInnerInt = ALTIUM_PROPS_UTILS::ReadInt( aProps, "SYMBOL_INNER", 0 );
symbolInner = ASCH_PIN_SYMBOL::FromInt( symbolInnerInt );
int symbolOuterEdgeInt = ALTIUM_PARSER::ReadInt( aProps, "SYMBOL_OUTEREDGE", 0 );
int symbolOuterEdgeInt = ALTIUM_PROPS_UTILS::ReadInt( aProps, "SYMBOL_OUTEREDGE", 0 );
symbolOuterEdge = ASCH_PIN_SYMBOL::FromInt( symbolOuterEdgeInt );
int symbolInnerEdgeInt = ALTIUM_PARSER::ReadInt( aProps, "SYMBOL_INNEREDGE", 0 );
int symbolInnerEdgeInt = ALTIUM_PROPS_UTILS::ReadInt( aProps, "SYMBOL_INNEREDGE", 0 );
symbolInnerEdge = ASCH_PIN_SYMBOL::FromInt( symbolInnerEdgeInt );
electrical = ReadEnum<ASCH_PIN_ELECTRICAL>( aProps, "ELECTRICAL", 0, 7,
ASCH_PIN_ELECTRICAL::INPUT );
int pinconglomerate = ALTIUM_PARSER::ReadInt( aProps, "PINCONGLOMERATE", 0 );
int pinconglomerate = ALTIUM_PROPS_UTILS::ReadInt( aProps, "PINCONGLOMERATE", 0 );
orientation = static_cast<ASCH_RECORD_ORIENTATION>( pinconglomerate & 0x03 );
hidden = ( pinconglomerate & 0x04 ) != 0;
@@ -195,14 +231,14 @@ ASCH_PIN::ASCH_PIN( const std::map<wxString, wxString>& aProps ) :
locked = ( pinconglomerate & 0x40 ) != 0;
int x = ALTIUM_PARSER::ReadInt( aProps, "LOCATION.X", 0 );
int xfrac = ALTIUM_PARSER::ReadInt( aProps, "LOCATION.X_FRAC", 0 );
int y = ALTIUM_PARSER::ReadInt( aProps, "LOCATION.Y", 0 );
int yfrac = ALTIUM_PARSER::ReadInt( aProps, "LOCATION.Y_FRAC", 0 );
int x = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATION.X", 0 );
int xfrac = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATION.X_FRAC", 0 );
int y = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATION.Y", 0 );
int yfrac = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATION.Y_FRAC", 0 );
location = VECTOR2I( Altium2KiCadUnit( x, xfrac ), -Altium2KiCadUnit( y, yfrac ) );
int p = ALTIUM_PARSER::ReadInt( aProps, "PINLENGTH", 0 );
int pfrac = ALTIUM_PARSER::ReadInt( aProps, "PINLENGTH_FRAC", 0 );
int p = ALTIUM_PROPS_UTILS::ReadInt( aProps, "PINLENGTH", 0 );
int pfrac = ALTIUM_PROPS_UTILS::ReadInt( aProps, "PINLENGTH_FRAC", 0 );
pinlength = Altium2KiCadUnit( p, pfrac );
// this code calculates the location as required by KiCad without rounding error attached
@@ -256,17 +292,17 @@ ASCH_OWNER_INTERFACE::ASCH_OWNER_INTERFACE( const std::map<wxString, wxString>&
{
ownerindex = ReadOwnerIndex( aProps );
ownerpartid = ReadOwnerPartId( aProps );
ownerpartdisplaymode = ALTIUM_PARSER::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 );
indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 );
IsNotAccesible = ALTIUM_PARSER::ReadBool( aProps, "ISNOTACCESIBLE", false );
ownerpartdisplaymode = ALTIUM_PROPS_UTILS::ReadInt( aProps, "OWNERPARTDISPLAYMODE", 0 );
indexinsheet = ALTIUM_PROPS_UTILS::ReadInt( aProps, "INDEXINSHEET", 0 );
IsNotAccesible = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISNOTACCESIBLE", false );
}
ASCH_FILL_INTERFACE::ASCH_FILL_INTERFACE( const std::map<wxString, wxString>& aProps )
{
AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 );
IsSolid = ALTIUM_PARSER::ReadBool( aProps, "ISSOLID", false );
IsTransparent = ALTIUM_PARSER::ReadBool( aProps, "TRANSPARENT", false );
AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 );
IsSolid = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISSOLID", false );
IsTransparent = ALTIUM_PROPS_UTILS::ReadBool( aProps, "TRANSPARENT", false );
}
@@ -279,7 +315,7 @@ ASCH_BORDER_INTERFACE::ASCH_BORDER_INTERFACE( const std::map<wxString, wxString>
if( LineWidth == 0 )
LineWidth = schIUScale.MilsToIU( 1 );
Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
}
@@ -291,11 +327,11 @@ ASCH_LABEL::ASCH_LABEL( const std::map<wxString, wxString>& aProps ) :
location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" );
text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" );
textColor = 0;
fontId = ALTIUM_PARSER::ReadInt( aProps, "FONTID", 0 );
isMirrored = ALTIUM_PARSER::ReadBool( aProps, "ISMIRRORED", false );
fontId = ALTIUM_PROPS_UTILS::ReadInt( aProps, "FONTID", 0 );
isMirrored = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISMIRRORED", false );
justification = ReadEnum<ASCH_LABEL_JUSTIFICATION>( aProps, "JUSTIFICATION", 0, 8,
ASCH_LABEL_JUSTIFICATION::BOTTOM_LEFT );
@@ -321,20 +357,20 @@ ASCH_TEXT_FRAME::ASCH_TEXT_FRAME( const std::map<wxString, wxString>& aProps ) :
Size = VECTOR2I( ReadKiCadUnitFrac( aProps, "CORNER.X" ) - Location.x,
-ReadKiCadUnitFrac( aProps, "CORNER.Y" ) - Location.y );
Text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" );
Text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" );
Text.Replace( "~1", "\n", true );
FontID = ALTIUM_PARSER::ReadInt( aProps, "FONTID", 0 );
IsWordWrapped = ALTIUM_PARSER::ReadBool( aProps, "WORDWRAP", false );
ShowBorder = ALTIUM_PARSER::ReadBool( aProps, "SHOWBORDER", false );
FontID = ALTIUM_PROPS_UTILS::ReadInt( aProps, "FONTID", 0 );
IsWordWrapped = ALTIUM_PROPS_UTILS::ReadBool( aProps, "WORDWRAP", false );
ShowBorder = ALTIUM_PROPS_UTILS::ReadBool( aProps, "SHOWBORDER", false );
TextMargin = ReadKiCadUnitFrac( aProps, "TEXTMARGIN" );
AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 );
BorderColor = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
TextColor = ALTIUM_PARSER::ReadInt( aProps, "TEXTCOLOR", 0 );
AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 );
BorderColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
TextColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTCOLOR", 0 );
BorderWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
isSolid = ALTIUM_PARSER::ReadBool( aProps, "ISSOLID", false );
isSolid = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISSOLID", false );
Alignment = ReadEnum<ASCH_TEXT_FRAME_ALIGNMENT>( aProps, "ALIGNMENT", 1, 3,
ASCH_TEXT_FRAME_ALIGNMENT::LEFT );
@@ -346,7 +382,7 @@ ASCH_NOTE::ASCH_NOTE( const std::map<wxString, wxString>& aProperties ) :
{
wxASSERT( ReadRecord( aProperties ) == ALTIUM_SCH_RECORD::NOTE );
author = ALTIUM_PARSER::ReadString( aProperties, "AUTHOR", "" );
author = ALTIUM_PROPS_UTILS::ReadString( aProperties, "AUTHOR", "" );
}
@@ -356,7 +392,7 @@ ASCH_BEZIER::ASCH_BEZIER( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BEZIER );
int locationCount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
int locationCount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 );
for( int i = 1; i <= locationCount; i++ )
{
@@ -373,7 +409,7 @@ ASCH_POLYLINE::ASCH_POLYLINE( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::POLYLINE );
int locationCount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
int locationCount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 );
for( int i = 1; i <= locationCount; i++ )
{
@@ -394,7 +430,7 @@ ASCH_POLYGON::ASCH_POLYGON( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::POLYGON );
int locationCount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
int locationCount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 );
for( int i = 1; i <= locationCount; i++ )
{
@@ -437,8 +473,8 @@ ASCH_ARC::ASCH_ARC( const std::map<wxString, wxString>& aProps ) :
if( m_IsElliptical )
m_SecondaryRadius = ReadKiCadUnitFrac( aProps, "SECONDARYRADIUS" );
m_StartAngle = ALTIUM_PARSER::ReadDouble( aProps, "STARTANGLE", 0 );
m_EndAngle = ALTIUM_PARSER::ReadDouble( aProps, "ENDANGLE", 0 );
m_StartAngle = ALTIUM_PROPS_UTILS::ReadDouble( aProps, "STARTANGLE", 0 );
m_EndAngle = ALTIUM_PROPS_UTILS::ReadDouble( aProps, "ENDANGLE", 0 );
}
@@ -479,7 +515,7 @@ ASCH_SIGNAL_HARNESS::ASCH_SIGNAL_HARNESS( const std::map<wxString, wxString>& aP
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SIGNAL_HARNESS );
int locationCount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
int locationCount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 );
for( int i = 1; i <= locationCount; i++ )
{
@@ -488,7 +524,7 @@ ASCH_SIGNAL_HARNESS::ASCH_SIGNAL_HARNESS( const std::map<wxString, wxString>& aP
-ReadKiCadUnitFrac( aProps, "Y" + si ) );
}
Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
LineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
}
@@ -503,8 +539,8 @@ ASCH_HARNESS_CONNECTOR::ASCH_HARNESS_CONNECTOR( const std::map<wxString, wxStrin
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
Size = VECTOR2I( ReadKiCadUnitFrac( aProps, "XSIZE" ), ReadKiCadUnitFrac( aProps, "YSIZE" ) );
Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 );
Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 );
indexinsheet = 0;
LineWidth = 0;;
@@ -526,14 +562,14 @@ ASCH_HARNESS_ENTRY::ASCH_HARNESS_ENTRY( const std::map<wxString, wxString>& aPro
Side = ReadEnum<ASCH_SHEET_ENTRY_SIDE>( aProps, "SIDE", 0, 3, ASCH_SHEET_ENTRY_SIDE::LEFT );
Name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" );
Name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" );
OwnerIndexAdditionalList = ALTIUM_PARSER::ReadBool( aProps, "OWNERINDEXADDITIONALLIST", true );
OwnerIndexAdditionalList = ALTIUM_PROPS_UTILS::ReadBool( aProps, "OWNERINDEXADDITIONALLIST", true );
Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 );
TextColor = ALTIUM_PARSER::ReadInt( aProps, "TEXTCOLOR", 0 );
TextFontID = ALTIUM_PARSER::ReadInt( aProps, "TEXTFONTID", 0 );
Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 );
TextColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTCOLOR", 0 );
TextFontID = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTFONTID", 0 );
TextStyle = 0;
}
@@ -545,16 +581,16 @@ ASCH_HARNESS_TYPE::ASCH_HARNESS_TYPE( const std::map<wxString, wxString>& aProps
//ownerindex = ReadOwnerIndex( aProps ); // use SCH_IO_ALTIUM::m_harnessEntryParent instead!
Text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" );
Text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" );
Location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
IsHidden = ALTIUM_PARSER::ReadBool( aProps, "ISHIDDEN", false );
OwnerIndexAdditionalList = ALTIUM_PARSER::ReadBool( aProps, "OWNERINDEXADDITIONALLIST", true );
IsHidden = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISHIDDEN", false );
OwnerIndexAdditionalList = ALTIUM_PROPS_UTILS::ReadBool( aProps, "OWNERINDEXADDITIONALLIST", true );
Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
FontID = ALTIUM_PARSER::ReadInt( aProps, "TEXTFONTID", 0 );
Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
FontID = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTFONTID", 0 );
}
@@ -583,10 +619,10 @@ ASCH_SHEET_SYMBOL::ASCH_SHEET_SYMBOL( const std::map<wxString, wxString>& aProps
size = VECTOR2I( ReadKiCadUnitFrac( aProps, "XSIZE" ),
ReadKiCadUnitFrac( aProps, "YSIZE" ) );
isSolid = ALTIUM_PARSER::ReadBool( aProps, "ISSOLID", false );
isSolid = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISSOLID", false );
color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
areacolor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 );
color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
areacolor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 );
}
@@ -600,7 +636,7 @@ ASCH_SHEET_ENTRY::ASCH_SHEET_ENTRY( const std::map<wxString, wxString>& aProps )
side = ReadEnum<ASCH_SHEET_ENTRY_SIDE>( aProps, "SIDE", 0, 3, ASCH_SHEET_ENTRY_SIDE::LEFT );
name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" );
name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" );
iotype = ReadEnum<ASCH_PORT_IOTYPE>( aProps, "IOTYPE", 0, 3, ASCH_PORT_IOTYPE::UNSPECIFIED );
style = ReadEnum<ASCH_PORT_STYLE>( aProps, "STYLE", 0, 7, ASCH_PORT_STYLE::NONE_HORIZONTAL );
@@ -619,8 +655,8 @@ ASCH_POWER_PORT::ASCH_POWER_PORT( const std::map<wxString, wxString>& aProps ) :
orientation = ReadEnum<ASCH_RECORD_ORIENTATION>( aProps, "ORIENTATION", 0, 3,
ASCH_RECORD_ORIENTATION::RIGHTWARDS );
text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" );
showNetName = ALTIUM_PARSER::ReadBool( aProps, "SHOWNETNAME", true );
text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" );
showNetName = ALTIUM_PROPS_UTILS::ReadBool( aProps, "SHOWNETNAME", true );
style = ReadEnum<ASCH_POWER_PORT_STYLE>( aProps, "STYLE", 0, 10,
ASCH_POWER_PORT_STYLE::CIRCLE );
@@ -636,8 +672,8 @@ ASCH_PORT::ASCH_PORT( const std::map<wxString, wxString>& aProps ) :
Location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
Name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" );
HarnessType = ALTIUM_PARSER::ReadString( aProps, "HARNESSTYPE", "" );
Name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" );
HarnessType = ALTIUM_PROPS_UTILS::ReadString( aProps, "HARNESSTYPE", "" );
Width = ReadKiCadUnitFrac( aProps, "WIDTH" );
Height = ReadKiCadUnitFrac( aProps, "HEIGHT" );
@@ -645,10 +681,10 @@ ASCH_PORT::ASCH_PORT( const std::map<wxString, wxString>& aProps ) :
IOtype = ReadEnum<ASCH_PORT_IOTYPE>( aProps, "IOTYPE", 0, 3, ASCH_PORT_IOTYPE::UNSPECIFIED );
Style = ReadEnum<ASCH_PORT_STYLE>( aProps, "STYLE", 0, 7, ASCH_PORT_STYLE::NONE_HORIZONTAL );
AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 );
Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
FontID = ALTIUM_PARSER::ReadInt( aProps, "TEXTFONTID", 0 );
TextColor = ALTIUM_PARSER::ReadInt( aProps, "TEXTCOLOR", 0 );
AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR", 0 );
Color = ALTIUM_PROPS_UTILS::ReadInt( aProps, "COLOR", 0 );
FontID = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTFONTID", 0 );
TextColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "TEXTCOLOR", 0 );
Alignment = ReadEnum<ASCH_TEXT_FRAME_ALIGNMENT>( aProps, "ALIGNMENT", 1, 3,
ASCH_TEXT_FRAME_ALIGNMENT::LEFT );
@@ -662,8 +698,8 @@ ASCH_NO_ERC::ASCH_NO_ERC( const std::map<wxString, wxString>& aProps )
location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
isActive = ALTIUM_PARSER::ReadBool( aProps, "ISACTIVE", true );
suppressAll = ALTIUM_PARSER::ReadInt( aProps, "SUPPRESSALL", true );
isActive = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISACTIVE", true );
suppressAll = ALTIUM_PROPS_UTILS::ReadInt( aProps, "SUPPRESSALL", true );
}
@@ -672,7 +708,7 @@ ASCH_NET_LABEL::ASCH_NET_LABEL( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::NET_LABEL );
text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" );
text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" );
location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
@@ -690,7 +726,7 @@ ASCH_BUS::ASCH_BUS( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BUS );
int locationcount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
int locationcount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 );
for( int i = 1; i <= locationcount; i++ )
{
@@ -708,7 +744,7 @@ ASCH_WIRE::ASCH_WIRE( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::WIRE );
int locationcount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
int locationcount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "LOCATIONCOUNT", 0 );
for( int i = 1; i <= locationcount; i++ )
{
@@ -738,15 +774,15 @@ ASCH_IMAGE::ASCH_IMAGE( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::IMAGE );
filename = ALTIUM_PARSER::ReadString( aProps, "FILENAME", "" );
filename = ALTIUM_PROPS_UTILS::ReadString( aProps, "FILENAME", "" );
location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
corner = VECTOR2I( ReadKiCadUnitFrac( aProps, "CORNER.X" ),
-ReadKiCadUnitFrac( aProps, "CORNER.Y" ) );
embedimage = ALTIUM_PARSER::ReadBool( aProps, "EMBEDIMAGE", false );
keepaspect = ALTIUM_PARSER::ReadBool( aProps, "KEEPASPECT", false );
embedimage = ALTIUM_PROPS_UTILS::ReadBool( aProps, "EMBEDIMAGE", false );
keepaspect = ALTIUM_PROPS_UTILS::ReadBool( aProps, "KEEPASPECT", false );
}
@@ -757,16 +793,16 @@ ASCH_SHEET_FONT::ASCH_SHEET_FONT( const std::map<wxString, wxString>& aProps, in
const wxString sid = std::to_string( aId );
FontName = ALTIUM_PARSER::ReadString( aProps, "FONTNAME" + sid, "" );
FontName = ALTIUM_PROPS_UTILS::ReadString( aProps, "FONTNAME" + sid, "" );
Size = ReadKiCadUnitFrac( aProps, "SIZE" + sid );
Rotation = ALTIUM_PARSER::ReadInt( aProps, "ROTATION" + sid, 0 );
Rotation = ALTIUM_PROPS_UTILS::ReadInt( aProps, "ROTATION" + sid, 0 );
Italic = ALTIUM_PARSER::ReadBool( aProps, "ITALIC" + sid, false );
Bold = ALTIUM_PARSER::ReadBool( aProps, "BOLD" + sid, false );
Underline = ALTIUM_PARSER::ReadBool( aProps, "UNDERLINE" + sid, false );
Italic = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ITALIC" + sid, false );
Bold = ALTIUM_PROPS_UTILS::ReadBool( aProps, "BOLD" + sid, false );
Underline = ALTIUM_PROPS_UTILS::ReadBool( aProps, "UNDERLINE" + sid, false );
AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR" + sid, 0 );
AreaColor = ALTIUM_PROPS_UTILS::ReadInt( aProps, "AREACOLOR" + sid, 0 );
}
@@ -803,12 +839,12 @@ ASCH_SHEET::ASCH_SHEET( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET );
int fontidcount = ALTIUM_PARSER::ReadInt( aProps, "FONTIDCOUNT", 0 );
int fontidcount = ALTIUM_PROPS_UTILS::ReadInt( aProps, "FONTIDCOUNT", 0 );
for( int i = 1; i <= fontidcount; i++ )
fonts.emplace_back( aProps, i );
useCustomSheet = ALTIUM_PARSER::ReadBool( aProps, "USECUSTOMSHEET", false );
useCustomSheet = ALTIUM_PROPS_UTILS::ReadBool( aProps, "USECUSTOMSHEET", false );
customSize = VECTOR2I( ReadKiCadUnitFrac( aProps, "CUSTOMX" ),
ReadKiCadUnitFrac( aProps, "CUSTOMY" ) );
@@ -824,7 +860,7 @@ ASCH_SHEET_NAME::ASCH_SHEET_NAME( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::SHEET_NAME );
text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" );
text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" );
orientation = ReadEnum<ASCH_RECORD_ORIENTATION>( aProps, "ORIENTATION", 0, 3,
ASCH_RECORD_ORIENTATION::RIGHTWARDS );
@@ -832,7 +868,7 @@ ASCH_SHEET_NAME::ASCH_SHEET_NAME( const std::map<wxString, wxString>& aProps ) :
location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
isHidden = ALTIUM_PARSER::ReadBool( aProps, "ISHIDDEN", false );
isHidden = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISHIDDEN", false );
}
@@ -841,7 +877,7 @@ ASCH_FILE_NAME::ASCH_FILE_NAME( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::FILE_NAME );
text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" );
text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" );
orientation = ReadEnum<ASCH_RECORD_ORIENTATION>( aProps, "ORIENTATION", 0, 3,
ASCH_RECORD_ORIENTATION::RIGHTWARDS );
@@ -849,7 +885,7 @@ ASCH_FILE_NAME::ASCH_FILE_NAME( const std::map<wxString, wxString>& aProps ) :
location = VECTOR2I( ReadKiCadUnitFrac( aProps, "LOCATION.X" ),
-ReadKiCadUnitFrac( aProps, "LOCATION.Y" ) );
isHidden = ALTIUM_PARSER::ReadBool( aProps, "ISHIDDEN", false );
isHidden = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISHIDDEN", false );
}
@@ -858,9 +894,9 @@ ASCH_DESIGNATOR::ASCH_DESIGNATOR( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::DESIGNATOR );
name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" );
text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" );
fontId = ALTIUM_PARSER::ReadInt( aProps, "FONTID", 0 );
name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" );
text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" );
fontId = ALTIUM_PROPS_UTILS::ReadInt( aProps, "FONTID", 0 );
justification = ReadEnum<ASCH_LABEL_JUSTIFICATION>( aProps, "JUSTIFICATION", 0, 8,
ASCH_LABEL_JUSTIFICATION::BOTTOM_LEFT );
@@ -878,12 +914,12 @@ ASCH_IMPLEMENTATION::ASCH_IMPLEMENTATION( const std::map<wxString, wxString>& aP
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::IMPLEMENTATION );
ownerindex = ALTIUM_PARSER::ReadInt( aProps, "OWNERINDEX", ALTIUM_COMPONENT_NONE );
name = ALTIUM_PARSER::ReadString( aProps, "MODELNAME", "" );
type = ALTIUM_PARSER::ReadString( aProps, "MODELTYPE", "" );
libname = ALTIUM_PARSER::ReadString( aProps, "MODELDATAFILE0", "" );
description = ALTIUM_PARSER::ReadString( aProps, "DESCRIPTION", "" );
isCurrent = ALTIUM_PARSER::ReadBool( aProps, "ISCURRENT", false );
ownerindex = ALTIUM_PROPS_UTILS::ReadInt( aProps, "OWNERINDEX", ALTIUM_COMPONENT_NONE );
name = ALTIUM_PROPS_UTILS::ReadString( aProps, "MODELNAME", "" );
type = ALTIUM_PROPS_UTILS::ReadString( aProps, "MODELTYPE", "" );
libname = ALTIUM_PROPS_UTILS::ReadString( aProps, "MODELDATAFILE0", "" );
description = ALTIUM_PROPS_UTILS::ReadString( aProps, "DESCRIPTION", "" );
isCurrent = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISCURRENT", false );
}
@@ -920,14 +956,14 @@ ASCH_PARAMETER::ASCH_PARAMETER( const std::map<wxString, wxString>& aProps ) :
orientation = ReadEnum<ASCH_RECORD_ORIENTATION>( aProps, "ORIENTATION", 0, 3,
ASCH_RECORD_ORIENTATION::RIGHTWARDS );
name = ALTIUM_PARSER::ReadString( aProps, "NAME", "" );
text = ALTIUM_PARSER::ReadString( aProps, "TEXT", "" );
name = ALTIUM_PROPS_UTILS::ReadString( aProps, "NAME", "" );
text = ALTIUM_PROPS_UTILS::ReadString( aProps, "TEXT", "" );
isHidden = ALTIUM_PARSER::ReadBool( aProps, "ISHIDDEN", false );
isMirrored = ALTIUM_PARSER::ReadBool( aProps, "ISMIRRORED", false );
isShowName = ALTIUM_PARSER::ReadBool( aProps, "SHOWNAME", false );
isHidden = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISHIDDEN", false );
isMirrored = ALTIUM_PROPS_UTILS::ReadBool( aProps, "ISMIRRORED", false );
isShowName = ALTIUM_PROPS_UTILS::ReadBool( aProps, "SHOWNAME", false );
fontId = ALTIUM_PARSER::ReadInt( aProps, "FONTID", 0 );
fontId = ALTIUM_PROPS_UTILS::ReadInt( aProps, "FONTID", 0 );
}
@@ -936,5 +972,5 @@ ASCH_HYPERLINK::ASCH_HYPERLINK( const std::map<wxString, wxString>& aProps ) :
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::HYPERLINK );
url = ALTIUM_PARSER::ReadString( aProps, "URL", "" );
url = ALTIUM_PROPS_UTILS::ReadString( aProps, "URL", "" );
}
+4 -3
View File
@@ -36,14 +36,15 @@
// this constant specifies a item which is not inside an component
const int ALTIUM_COMPONENT_NONE = -1;
class ALTIUM_PARSER;
class ALTIUM_BINARY_PARSER;
struct ASCH_STORAGE_FILE
{
wxString filename;
std::vector<char> data;
explicit ASCH_STORAGE_FILE( ALTIUM_PARSER& aReader );
explicit ASCH_STORAGE_FILE( const std::map<wxString, wxString>& aProps );
explicit ASCH_STORAGE_FILE( ALTIUM_BINARY_PARSER& aReader );
};
struct ASCH_ADDITIONAL_FILE
@@ -51,7 +52,7 @@ struct ASCH_ADDITIONAL_FILE
wxString FileName;
std::vector<char> Data;
explicit ASCH_ADDITIONAL_FILE( ALTIUM_PARSER& aReader );
explicit ASCH_ADDITIONAL_FILE( ALTIUM_BINARY_PARSER& aReader );
};
enum class ALTIUM_SCH_RECORD
+382 -242
View File
@@ -27,7 +27,8 @@
#include "altium_parser_sch.h"
#include "sch_shape.h"
#include <io/io_utils.h>
#include <io/altium/altium_parser.h>
#include <io/altium/altium_binary_parser.h>
#include <io/altium/altium_ascii_parser.h>
#include <io/altium/altium_parser_utils.h>
#include <sch_io/altium/sch_io_altium.h>
@@ -65,6 +66,7 @@
#include <wx/zstream.h>
#include <wx/wfstream.h>
#include <magic_enum.hpp>
#include "sch_io_altium.h"
// Harness port object itself does not contain color information about itself
// It seems altium is drawing harness ports using these colors
@@ -242,13 +244,26 @@ int SCH_IO_ALTIUM::GetModifyHash() const
}
bool SCH_IO_ALTIUM::checkFileHeader( const wxString& aFileName )
bool SCH_IO_ALTIUM::isBinaryFile( const wxString& aFileName )
{
// Compound File Binary Format header
return IO_UTILS::fileStartsWithBinaryHeader( aFileName, IO_UTILS::COMPOUND_FILE_HEADER );
}
bool SCH_IO_ALTIUM::isASCIIFile( const wxString& aFileName )
{
// ASCII file format
return IO_UTILS::fileStartsWithPrefix( aFileName, wxS( "|HEADER=" ), false );
}
bool SCH_IO_ALTIUM::checkFileHeader( const wxString& aFileName )
{
return isBinaryFile( aFileName ) || isASCIIFile( aFileName );
}
bool SCH_IO_ALTIUM::CanReadSchematicFile( const wxString& aFileName ) const
{
if( !SCH_IO::CanReadSchematicFile( aFileName ) )
@@ -441,27 +456,34 @@ SCH_SHEET* SCH_IO_ALTIUM::getCurrentSheet()
void SCH_IO_ALTIUM::ParseAltiumSch( const wxString& aFileName )
{
ALTIUM_COMPOUND_FILE altiumSchFile( aFileName );
// Load path may be different from the project path.
wxFileName parentFileName = aFileName;
try
if( isBinaryFile( aFileName ) )
{
ParseStorage( altiumSchFile ); // we need this before parsing the FileHeader
ParseFileHeader( altiumSchFile );
ALTIUM_COMPOUND_FILE altiumSchFile( aFileName );
// Parse "Additional" because sheet is set up during "FileHeader" parsing.
ParseAdditional( altiumSchFile );
try
{
ParseStorage( altiumSchFile ); // we need this before parsing the FileHeader
ParseFileHeader( altiumSchFile );
// Parse "Additional" because sheet is set up during "FileHeader" parsing.
ParseAdditional( altiumSchFile );
}
catch( const CFB::CFBException& exception )
{
THROW_IO_ERROR( exception.what() );
}
catch( const std::exception& exc )
{
wxLogDebug( wxT( "Unhandled exception in Altium schematic parsers: %s." ), exc.what() );
throw;
}
}
catch( const CFB::CFBException& exception )
else // ASCII
{
THROW_IO_ERROR( exception.what() );
}
catch( const std::exception& exc )
{
wxLogDebug( wxT( "Unhandled exception in Altium schematic parsers: %s." ), exc.what() );
throw;
ParseASCIISchematic( aFileName );
}
SCH_SCREEN* currentScreen = getCurrentScreen();
@@ -550,11 +572,11 @@ void SCH_IO_ALTIUM::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile )
if( file == nullptr )
return;
ALTIUM_PARSER reader( aAltiumSchFile, file );
ALTIUM_BINARY_PARSER reader( aAltiumSchFile, file );
std::map<wxString, wxString> properties = reader.ReadProperties();
wxString header = ALTIUM_PARSER::ReadString( properties, "HEADER", "" );
int weight = ALTIUM_PARSER::ReadInt( properties, "WEIGHT", 0 );
wxString header = ALTIUM_PROPS_UTILS::ReadString( properties, "HEADER", "" );
int weight = ALTIUM_PROPS_UTILS::ReadInt( properties, "WEIGHT", 0 );
if( weight < 0 )
THROW_IO_ERROR( "Storage weight is negative!" );
@@ -579,13 +601,15 @@ void SCH_IO_ALTIUM::ParseStorage( const ALTIUM_COMPOUND_FILE& aAltiumSchFile )
void SCH_IO_ALTIUM::ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile )
{
const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "Additional" } );
wxString streamName = wxS( "Additional" );
const CFB::COMPOUND_FILE_ENTRY* file =
aAltiumSchFile.FindStream( { streamName.ToStdString() } );
if( file == nullptr )
return;
ALTIUM_PARSER reader( aAltiumSchFile, file );
ALTIUM_BINARY_PARSER reader( aAltiumSchFile, file );
if( reader.GetRemainingBytes() <= 0 )
{
@@ -595,7 +619,7 @@ void SCH_IO_ALTIUM::ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
{
std::map<wxString, wxString> properties = reader.ReadProperties();
int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 );
int recordId = ALTIUM_PROPS_UTILS::ReadInt( properties, "RECORD", 0 );
ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
if( record != ALTIUM_SCH_RECORD::HEADER )
@@ -606,39 +630,7 @@ void SCH_IO_ALTIUM::ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
{
std::map<wxString, wxString> properties = reader.ReadProperties();
int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 );
ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
// see: https://github.com/vadmium/python-altium/blob/master/format.md
switch( record )
{
case ALTIUM_SCH_RECORD::HARNESS_CONNECTOR:
ParseHarnessConnector( index, properties );
break;
case ALTIUM_SCH_RECORD::HARNESS_ENTRY:
ParseHarnessEntry( properties );
break;
case ALTIUM_SCH_RECORD::HARNESS_TYPE:
ParseHarnessType( properties );
break;
case ALTIUM_SCH_RECORD::SIGNAL_HARNESS:
ParseSignalHarness( properties );
break;
case ALTIUM_SCH_RECORD::BLANKET:
m_reporter->Report( _( "Blanket not currently supported." ), RPT_SEVERITY_ERROR );
break;
default:
m_reporter->Report( wxString::Format( _( "Unknown or unexpected record ID %d found "
"inside \"Additional\" section." ),
recordId ),
RPT_SEVERITY_ERROR );
break;
}
ParseRecord( index, properties, streamName );
}
// Handle harness Ports
@@ -657,12 +649,15 @@ void SCH_IO_ALTIUM::ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile )
{
const CFB::COMPOUND_FILE_ENTRY* file = aAltiumSchFile.FindStream( { "FileHeader" } );
wxString streamName = wxS( "FileHeader" );
const CFB::COMPOUND_FILE_ENTRY* file =
aAltiumSchFile.FindStream( { streamName.ToStdString() } );
if( file == nullptr )
THROW_IO_ERROR( "FileHeader not found" );
ALTIUM_PARSER reader( aAltiumSchFile, file );
ALTIUM_BINARY_PARSER reader( aAltiumSchFile, file );
if( reader.GetRemainingBytes() <= 0 )
{
@@ -672,7 +667,7 @@ void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
{
std::map<wxString, wxString> properties = reader.ReadProperties();
wxString libtype = ALTIUM_PARSER::ReadString( properties, "HEADER", "" );
wxString libtype = ALTIUM_PROPS_UTILS::ReadString( properties, "HEADER", "" );
if( libtype.CmpNoCase( "Protel for Windows - Schematic Capture Binary File Version 5.0" ) )
THROW_IO_ERROR( _( "Expected Altium Schematic file version 5.0" ) );
@@ -689,183 +684,7 @@ void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
{
std::map<wxString, wxString> properties = reader.ReadProperties();
int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", -1 );
ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
// see: https://github.com/vadmium/python-altium/blob/master/format.md
switch( record )
{
case ALTIUM_SCH_RECORD::HEADER:
THROW_IO_ERROR( "Header already parsed" );
case ALTIUM_SCH_RECORD::COMPONENT:
ParseComponent( index, properties );
break;
case ALTIUM_SCH_RECORD::PIN:
ParsePin( properties );
break;
case ALTIUM_SCH_RECORD::IEEE_SYMBOL:
m_reporter->Report( _( "Record 'IEEE_SYMBOL' not handled." ), RPT_SEVERITY_INFO );
break;
case ALTIUM_SCH_RECORD::LABEL:
ParseLabel( properties );
break;
case ALTIUM_SCH_RECORD::BEZIER:
ParseBezier( properties );
break;
case ALTIUM_SCH_RECORD::POLYLINE:
ParsePolyline( properties );
break;
case ALTIUM_SCH_RECORD::POLYGON:
ParsePolygon( properties );
break;
case ALTIUM_SCH_RECORD::ELLIPSE:
ParseEllipse( properties );
break;
case ALTIUM_SCH_RECORD::PIECHART:
m_reporter->Report( _( "Record 'PIECHART' not handled." ), RPT_SEVERITY_INFO );
break;
case ALTIUM_SCH_RECORD::ROUND_RECTANGLE:
ParseRoundRectangle( properties );
break;
case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC:
case ALTIUM_SCH_RECORD::ARC:
ParseArc( properties );
break;
case ALTIUM_SCH_RECORD::LINE:
ParseLine( properties );
break;
case ALTIUM_SCH_RECORD::RECTANGLE:
ParseRectangle( properties );
break;
case ALTIUM_SCH_RECORD::SHEET_SYMBOL:
ParseSheetSymbol( index, properties );
break;
case ALTIUM_SCH_RECORD::SHEET_ENTRY:
ParseSheetEntry( properties );
break;
case ALTIUM_SCH_RECORD::POWER_PORT:
ParsePowerPort( properties );
break;
case ALTIUM_SCH_RECORD::PORT:
// Ports are parsed after the sheet was parsed
// This is required because we need all electrical connection points before placing.
m_altiumPortsCurrentSheet.emplace_back( properties );
break;
case ALTIUM_SCH_RECORD::NO_ERC:
ParseNoERC( properties );
break;
case ALTIUM_SCH_RECORD::NET_LABEL:
ParseNetLabel( properties );
break;
case ALTIUM_SCH_RECORD::BUS:
ParseBus( properties );
break;
case ALTIUM_SCH_RECORD::WIRE:
ParseWire( properties );
break;
case ALTIUM_SCH_RECORD::TEXT_FRAME:
ParseTextFrame( properties );
break;
case ALTIUM_SCH_RECORD::JUNCTION:
ParseJunction( properties );
break;
case ALTIUM_SCH_RECORD::IMAGE:
ParseImage( properties );
break;
case ALTIUM_SCH_RECORD::SHEET:
ParseSheet( properties );
break;
case ALTIUM_SCH_RECORD::SHEET_NAME:
ParseSheetName( properties );
break;
case ALTIUM_SCH_RECORD::FILE_NAME:
ParseFileName( properties );
break;
case ALTIUM_SCH_RECORD::DESIGNATOR:
ParseDesignator( properties );
break;
case ALTIUM_SCH_RECORD::BUS_ENTRY:
ParseBusEntry( properties );
break;
case ALTIUM_SCH_RECORD::TEMPLATE:
ParseTemplate( index, properties );
break;
case ALTIUM_SCH_RECORD::PARAMETER:
ParseParameter( properties );
break;
case ALTIUM_SCH_RECORD::PARAMETER_SET:
m_reporter->Report( _( "Parameter Set not currently supported." ), RPT_SEVERITY_ERROR );
break;
case ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST:
ParseImplementationList( index, properties );
break;
case ALTIUM_SCH_RECORD::IMPLEMENTATION:
ParseImplementation( properties );
break;
case ALTIUM_SCH_RECORD::MAP_DEFINER_LIST:
break;
case ALTIUM_SCH_RECORD::MAP_DEFINER:
break;
case ALTIUM_SCH_RECORD::IMPL_PARAMS:
break;
case ALTIUM_SCH_RECORD::NOTE:
ParseNote( properties );
break;
case ALTIUM_SCH_RECORD::COMPILE_MASK:
m_reporter->Report( _( "Compile mask not currently supported." ), RPT_SEVERITY_ERROR );
break;
case ALTIUM_SCH_RECORD::HYPERLINK:
break;
default:
m_reporter->Report( wxString::Format( _( "Unknown or unexpected record id %d found "
"inside \"FileHeader\" section." ),
recordId ),
RPT_SEVERITY_ERROR );
break;
}
SCH_IO_ALTIUM::m_harnessOwnerIndexOffset = index;
ParseRecord( index, properties, streamName );
}
if( reader.HasParsingError() )
@@ -902,6 +721,8 @@ void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
m_altiumPortsCurrentSheet.clear();
m_altiumComponents.clear();
m_altiumTemplates.clear();
m_altiumImplementationList.clear();
m_symbols.clear();
m_libSymbols.clear();
@@ -914,6 +735,324 @@ void SCH_IO_ALTIUM::ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile
}
void SCH_IO_ALTIUM::ParseASCIISchematic( const wxString& aFileName )
{
// Read storage content first
{
ALTIUM_ASCII_PARSER storageReader( aFileName );
while( storageReader.CanRead() )
{
std::map<wxString, wxString> properties = storageReader.ReadProperties();
// Binary data
if( properties.find( wxS( "BINARY" ) ) != properties.end() )
m_altiumStorage.emplace_back( properties );
}
}
// Read other data
ALTIUM_ASCII_PARSER reader( aFileName );
if( !reader.CanRead() )
{
THROW_IO_ERROR( "FileHeader does not contain any data" );
}
else
{
std::map<wxString, wxString> properties = reader.ReadProperties();
wxString libtype = ALTIUM_PROPS_UTILS::ReadString( properties, "HEADER", "" );
if( libtype.CmpNoCase( "Protel for Windows - Schematic Capture Ascii File Version 5.0" ) )
THROW_IO_ERROR( _( "Expected Altium Schematic file version 5.0" ) );
}
// Prepare some local variables
wxCHECK( m_altiumPortsCurrentSheet.empty(), /* void */ );
wxCHECK( !m_currentTitleBlock, /* void */ );
m_currentTitleBlock = std::make_unique<TITLE_BLOCK>();
// index is required to resolve OWNERINDEX
int index = 0;
while( reader.CanRead() )
{
std::map<wxString, wxString> properties = reader.ReadProperties();
// Reset index at headers
if( properties.find( wxS( "HEADER" ) ) != properties.end() )
{
index = 0;
continue;
}
if( properties.find( wxS( "RECORD" ) ) != properties.end() )
ParseRecord( index, properties, aFileName );
index++;
}
if( reader.HasParsingError() )
THROW_IO_ERROR( "stream was not parsed correctly!" );
if( reader.CanRead() )
THROW_IO_ERROR( "stream is not fully parsed" );
// assign LIB_SYMBOL -> COMPONENT
for( std::pair<const int, SCH_SYMBOL*>& symbol : m_symbols )
{
auto libSymbolIt = m_libSymbols.find( symbol.first );
if( libSymbolIt == m_libSymbols.end() )
THROW_IO_ERROR( "every symbol should have a symbol attached" );
m_pi->SaveSymbol( getLibFileName().GetFullPath(),
new LIB_SYMBOL( *( libSymbolIt->second ) ), m_properties.get() );
symbol.second->SetLibSymbol( libSymbolIt->second );
}
SCH_SCREEN* screen = getCurrentScreen();
wxCHECK( screen, /* void */ );
// Handle title blocks
screen->SetTitleBlock( *m_currentTitleBlock );
m_currentTitleBlock.reset();
// Handle harness Ports
for( const ASCH_PORT& port : m_altiumHarnessPortsCurrentSheet )
ParseHarnessPort( port );
// Handle Ports
for( const ASCH_PORT& port : m_altiumPortsCurrentSheet )
ParsePort( port );
m_altiumPortsCurrentSheet.clear();
m_altiumComponents.clear();
m_altiumTemplates.clear();
m_altiumImplementationList.clear();
m_symbols.clear();
m_libSymbols.clear();
// Otherwise we cannot save the imported sheet?
SCH_SHEET* sheet = getCurrentSheet();
wxCHECK( sheet, /* void */ );
sheet->SetModified();
}
void SCH_IO_ALTIUM::ParseRecord( int index, std::map<wxString, wxString>& properties,
const wxString& aSectionName )
{
int recordId = ALTIUM_PROPS_UTILS::ReadInt( properties, "RECORD", -1 );
ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
// see: https://github.com/vadmium/python-altium/blob/master/format.md
switch( record )
{
// FileHeader section
case ALTIUM_SCH_RECORD::HEADER:
THROW_IO_ERROR( "Header already parsed" );
case ALTIUM_SCH_RECORD::COMPONENT:
ParseComponent( index, properties );
break;
case ALTIUM_SCH_RECORD::PIN:
ParsePin( properties );
break;
case ALTIUM_SCH_RECORD::IEEE_SYMBOL:
m_reporter->Report( _( "Record 'IEEE_SYMBOL' not handled." ), RPT_SEVERITY_INFO );
break;
case ALTIUM_SCH_RECORD::LABEL:
ParseLabel( properties );
break;
case ALTIUM_SCH_RECORD::BEZIER:
ParseBezier( properties );
break;
case ALTIUM_SCH_RECORD::POLYLINE:
ParsePolyline( properties );
break;
case ALTIUM_SCH_RECORD::POLYGON:
ParsePolygon( properties );
break;
case ALTIUM_SCH_RECORD::ELLIPSE:
ParseEllipse( properties );
break;
case ALTIUM_SCH_RECORD::PIECHART:
m_reporter->Report( _( "Record 'PIECHART' not handled." ), RPT_SEVERITY_INFO );
break;
case ALTIUM_SCH_RECORD::ROUND_RECTANGLE:
ParseRoundRectangle( properties );
break;
case ALTIUM_SCH_RECORD::ELLIPTICAL_ARC:
case ALTIUM_SCH_RECORD::ARC:
ParseArc( properties );
break;
case ALTIUM_SCH_RECORD::LINE:
ParseLine( properties );
break;
case ALTIUM_SCH_RECORD::RECTANGLE:
ParseRectangle( properties );
break;
case ALTIUM_SCH_RECORD::SHEET_SYMBOL:
ParseSheetSymbol( index, properties );
break;
case ALTIUM_SCH_RECORD::SHEET_ENTRY:
ParseSheetEntry( properties );
break;
case ALTIUM_SCH_RECORD::POWER_PORT:
ParsePowerPort( properties );
break;
case ALTIUM_SCH_RECORD::PORT:
// Ports are parsed after the sheet was parsed
// This is required because we need all electrical connection points before placing.
m_altiumPortsCurrentSheet.emplace_back( properties );
break;
case ALTIUM_SCH_RECORD::NO_ERC:
ParseNoERC( properties );
break;
case ALTIUM_SCH_RECORD::NET_LABEL:
ParseNetLabel( properties );
break;
case ALTIUM_SCH_RECORD::BUS:
ParseBus( properties );
break;
case ALTIUM_SCH_RECORD::WIRE:
ParseWire( properties );
break;
case ALTIUM_SCH_RECORD::TEXT_FRAME:
ParseTextFrame( properties );
break;
case ALTIUM_SCH_RECORD::JUNCTION:
ParseJunction( properties );
break;
case ALTIUM_SCH_RECORD::IMAGE:
ParseImage( properties );
break;
case ALTIUM_SCH_RECORD::SHEET:
ParseSheet( properties );
break;
case ALTIUM_SCH_RECORD::SHEET_NAME:
ParseSheetName( properties );
break;
case ALTIUM_SCH_RECORD::FILE_NAME:
ParseFileName( properties );
break;
case ALTIUM_SCH_RECORD::DESIGNATOR:
ParseDesignator( properties );
break;
case ALTIUM_SCH_RECORD::BUS_ENTRY:
ParseBusEntry( properties );
break;
case ALTIUM_SCH_RECORD::TEMPLATE:
ParseTemplate( index, properties );
break;
case ALTIUM_SCH_RECORD::PARAMETER:
ParseParameter( properties );
break;
case ALTIUM_SCH_RECORD::PARAMETER_SET:
m_reporter->Report( _( "Parameter Set not currently supported." ), RPT_SEVERITY_ERROR );
break;
case ALTIUM_SCH_RECORD::IMPLEMENTATION_LIST:
ParseImplementationList( index, properties );
break;
case ALTIUM_SCH_RECORD::IMPLEMENTATION:
ParseImplementation( properties );
break;
case ALTIUM_SCH_RECORD::MAP_DEFINER_LIST:
break;
case ALTIUM_SCH_RECORD::MAP_DEFINER:
break;
case ALTIUM_SCH_RECORD::IMPL_PARAMS:
break;
case ALTIUM_SCH_RECORD::NOTE:
ParseNote( properties );
break;
case ALTIUM_SCH_RECORD::COMPILE_MASK:
m_reporter->Report( _( "Compile mask not currently supported." ), RPT_SEVERITY_ERROR );
break;
case ALTIUM_SCH_RECORD::HYPERLINK:
break;
// Additional section
case ALTIUM_SCH_RECORD::HARNESS_CONNECTOR:
ParseHarnessConnector( index, properties );
break;
case ALTIUM_SCH_RECORD::HARNESS_ENTRY:
ParseHarnessEntry( properties );
break;
case ALTIUM_SCH_RECORD::HARNESS_TYPE:
ParseHarnessType( properties );
break;
case ALTIUM_SCH_RECORD::SIGNAL_HARNESS:
ParseSignalHarness( properties );
break;
case ALTIUM_SCH_RECORD::BLANKET:
m_reporter->Report( _( "Blanket not currently supported." ), RPT_SEVERITY_ERROR );
break;
default:
m_reporter->Report(
wxString::Format( _( "Unknown or unexpected record id %d found in %s." ), recordId,
aSectionName ),
RPT_SEVERITY_ERROR );
break;
}
SCH_IO_ALTIUM::m_harnessOwnerIndexOffset = index;
}
bool SCH_IO_ALTIUM::IsComponentPartVisible( const ASCH_OWNER_INTERFACE& aElem ) const
{
const auto& component = m_altiumComponents.find( aElem.ownerindex );
@@ -1001,6 +1140,7 @@ void SCH_IO_ALTIUM::ParseComponent( int aIndex, const std::map<wxString, wxStrin
// component->SetOrientation( elem.orientation );
symbol->SetLibId( libId );
symbol->SetUnit( std::max( 0, elem.currentpartid ) );
symbol->GetField( DESCRIPTION_FIELD )->SetText( elem.componentdescription );
SCH_SCREEN* screen = getCurrentScreen();
wxCHECK( screen, /* void */ );
@@ -3404,7 +3544,7 @@ void SCH_IO_ALTIUM::ParseWire( const std::map<wxString, wxString>& aProperties )
SCH_LINE* wire = new SCH_LINE( elem.points.at( i ) + m_sheetOffset,
SCH_LAYER_ID::LAYER_WIRE );
wire->SetEndPoint( elem.points.at( i + 1 ) + m_sheetOffset );
wire->SetLineWidth( elem.lineWidth );
// wire->SetLineWidth( elem.lineWidth );
wire->SetFlags( IS_NEW );
screen->Append( wire );
@@ -3978,7 +4118,7 @@ std::map<wxString,LIB_SYMBOL*> SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUN
for( auto& [name, entry] : syms )
{
ALTIUM_PARSER reader( aAltiumLibFile, entry );
ALTIUM_BINARY_PARSER reader( aAltiumLibFile, entry );
std::vector<LIB_SYMBOL*> symbols;
if( reader.GetRemainingBytes() <= 0 )
@@ -3988,7 +4128,7 @@ std::map<wxString,LIB_SYMBOL*> SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUN
{
std::map<wxString, wxString> properties = reader.ReadProperties();
int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 );
int recordId = ALTIUM_PROPS_UTILS::ReadInt( properties, "RECORD", 0 );
ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
if( record != ALTIUM_SCH_RECORD::COMPONENT )
@@ -4053,7 +4193,7 @@ std::map<wxString,LIB_SYMBOL*> SCH_IO_ALTIUM::ParseLibFile( const ALTIUM_COMPOUN
if( properties.empty() )
continue;
int recordId = ALTIUM_PARSER::ReadInt( properties, "RECORD", 0 );
int recordId = ALTIUM_PROPS_UTILS::ReadInt( properties, "RECORD", 0 );
ALTIUM_SCH_RECORD record = static_cast<ALTIUM_SCH_RECORD>( recordId );
switch( record )
@@ -4218,7 +4358,7 @@ void SCH_IO_ALTIUM::ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile,
if( file == nullptr )
THROW_IO_ERROR( "FileHeader not found" );
ALTIUM_PARSER reader( aAltiumSchFile, file );
ALTIUM_BINARY_PARSER reader( aAltiumSchFile, file );
if( reader.GetRemainingBytes() <= 0 )
{
@@ -4227,7 +4367,7 @@ void SCH_IO_ALTIUM::ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile,
std::map<wxString, wxString> properties = reader.ReadProperties();
wxString libtype = ALTIUM_PARSER::ReadString( properties, "HEADER", "" );
wxString libtype = ALTIUM_PROPS_UTILS::ReadString( properties, "HEADER", "" );
if( libtype.CmpNoCase( "Protel for Windows - Schematic Library Editor Binary File Version 5.0" ) )
THROW_IO_ERROR( _( "Expected Altium Schematic Library file version 5.0" ) );
+7
View File
@@ -116,6 +116,11 @@ public:
void ParseAdditional( const ALTIUM_COMPOUND_FILE& aAltiumSchFile );
void ParseFileHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile );
void ParseASCIISchematic( const wxString& aFileName );
void ParseRecord( int index, std::map<wxString, wxString>& properties,
const wxString& aSectionName );
private:
SCH_SCREEN* getCurrentScreen();
SCH_SHEET* getCurrentSheet();
@@ -212,6 +217,8 @@ private:
void ensureLoadedLibrary( const wxString& aLibraryPath, const STRING_UTF8_MAP* aProperties );
long long getLibraryTimestamp( const wxString& aLibraryPath ) const;
static bool isBinaryFile( const wxString& aFileName );
static bool isASCIIFile( const wxString& aFileName );
static bool checkFileHeader( const wxString& aFileName );
std::map<wxString, long long> m_timestamps;
+8 -8
View File
@@ -79,7 +79,7 @@ void SCH_IO_DATABASE::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
for( auto const& pair : m_nameToSymbolcache )
{
LIB_SYMBOL* symbol = pair.second;
LIB_SYMBOL* symbol = pair.second.get();
if( !powerSymbolsOnly || symbol->IsPower() )
aSymbolList.emplace_back( symbol );
@@ -151,7 +151,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::LoadSymbol( const wxString& aLibraryPath,
wxCHECK( foundTable, nullptr );
return loadSymbolFromRow( aAliasName, *foundTable, result );
return loadSymbolFromRow( aAliasName, *foundTable, result ).release();
}
@@ -236,10 +236,10 @@ void SCH_IO_DATABASE::cacheLib()
wxString name( fmt::format( "{}{}", prefix,
std::any_cast<std::string>( result[table.key_col] ) ) );
LIB_SYMBOL* symbol = loadSymbolFromRow( name, table, result );
std::unique_ptr<LIB_SYMBOL> symbol = loadSymbolFromRow( name, table, result );
if( symbol )
m_nameToSymbolcache.insert( { symbol->GetName(), symbol } );
m_nameToSymbolcache[symbol->GetName()] = std::move( symbol );
}
}
@@ -414,11 +414,11 @@ std::optional<bool> SCH_IO_DATABASE::boolFromAny( const std::any& aVal )
}
LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
std::unique_ptr<LIB_SYMBOL> SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
const DATABASE_LIB_TABLE& aTable,
const DATABASE_CONNECTION::ROW& aRow )
{
LIB_SYMBOL* symbol = nullptr;
std::unique_ptr<LIB_SYMBOL> symbol = nullptr;
if( aRow.count( aTable.symbols_col ) )
{
@@ -436,7 +436,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
{
wxLogTrace( traceDatabase, wxT( "loadSymbolFromRow: found original symbol '%s'" ),
symbolIdStr );
symbol = originalSymbol->Duplicate();
symbol.reset( originalSymbol->Duplicate() );
symbol->SetSourceLibId( symbolId );
}
else if( !symbolId.IsValid() )
@@ -455,7 +455,7 @@ LIB_SYMBOL* SCH_IO_DATABASE::loadSymbolFromRow( const wxString& aSymbolName,
{
// Actual symbol not found: return metadata only; error will be indicated in the
// symbol chooser
symbol = new LIB_SYMBOL( aSymbolName );
symbol.reset( new LIB_SYMBOL( aSymbolName ) );
}
else
{
+4 -4
View File
@@ -93,9 +93,9 @@ private:
void connect();
LIB_SYMBOL* loadSymbolFromRow( const wxString& aSymbolName,
const DATABASE_LIB_TABLE& aTable,
const DATABASE_CONNECTION::ROW& aRow );
std::unique_ptr<LIB_SYMBOL> loadSymbolFromRow( const wxString& aSymbolName,
const DATABASE_LIB_TABLE& aTable,
const DATABASE_CONNECTION::ROW& aRow );
static std::optional<bool> boolFromAny( const std::any& aVal );
@@ -110,7 +110,7 @@ private:
std::set<wxString> m_defaultShownFields;
std::map<wxString, LIB_SYMBOL*> m_nameToSymbolcache;
std::map<wxString, std::unique_ptr<LIB_SYMBOL>> m_nameToSymbolcache;
long long m_cacheTimestamp;
+53 -2
View File
@@ -445,11 +445,11 @@ void SCH_EASYEDA_PARSER::ParseSymbolShapes( LIB_SYMBOL* aSymbol
wxString fillColor = arr[5].Lower();
//bool locked = arr[7] != wxS( "0" );
std::vector<SHAPE_LINE_CHAIN> lineChains =
std::vector<SHAPE_LINE_CHAIN> lineChains =
ParseLineChains( pointsData, schIUScale.MilsToIU( 10 ), false );
for( SHAPE_LINE_CHAIN outline : lineChains )
{
{
std::unique_ptr<LIB_SHAPE> shape =
std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::POLY );
@@ -806,6 +806,55 @@ void SCH_EASYEDA_PARSER::ParseSymbolShapes( LIB_SYMBOL* aSymbol
int pinUnit = 0;
int kPinLen = ScaleSize( std::abs( pinLen ) );
if( segments.size() > 5 )
{
wxArrayString dotParts = wxSplit( segments[5], '~', '\0' );
wxArrayString clockParts = wxSplit( segments[6], '~', '\0' );
if( dotParts.size() == 3 && clockParts.size() == 2 )
{
if( dotParts[0] == wxS( "1" ) )
{
VECTOR2D dotPos( Convert( dotParts[1] ), Convert( dotParts[2] ) );
std::unique_ptr<LIB_SHAPE> circle =
std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::CIRCLE );
circle->SetCenter( RelPosSym( dotPos ) );
circle->SetEnd( RelPosSym(
pinPos + ( dotPos - pinPos ).Resize( std::abs( pinLen ) ) ) );
circle->SetUnit( 0 );
aSymbol->AddDrawItem( circle.release() );
}
if( clockParts[0] == wxS( "1" ) )
{
std::vector<SHAPE_LINE_CHAIN> lineChains =
ParseLineChains( clockParts[1], schIUScale.MilsToIU( 10 ), false );
for( SHAPE_LINE_CHAIN outline : lineChains )
{
std::unique_ptr<LIB_SHAPE> shape =
std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::POLY );
outline.Mirror( false, true );
if( outline.IsClosed() )
outline.Append( outline.CPoint( 0 ), true );
for( const VECTOR2I& pt : outline.CPoints() )
shape->AddPoint( pt );
shape->SetUnit( 0 );
aSymbol->AddDrawItem( shape.release() );
}
}
}
}
std::unique_ptr<LIB_PIN> pin = std::make_unique<LIB_PIN>( aSymbol );
pin->SetName( pinName );
@@ -837,6 +886,7 @@ void SCH_EASYEDA_PARSER::ParseSymbolShapes( LIB_SYMBOL* aSymbol
wxString fontSize = arr[7];
wxString baselineAlign = arr[10];
wxString textStr = arr[12];
bool visible = arr[13] != wxS( "0" );
textStr.Replace( wxS( "\\n" ), wxS( "\n" ) );
textStr = UnescapeHTML( textStr );
@@ -874,6 +924,7 @@ void SCH_EASYEDA_PARSER::ParseSymbolShapes( LIB_SYMBOL* aSymbol
textItem->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
textItem->SetFont( KIFONT::FONT::GetFont( fontname ) );
textItem->SetVisible( visible );
double ptSize = 7;
+53 -8
View File
@@ -30,6 +30,8 @@
#include <sch_screen.h>
#include <kiplatform/environment.h>
#include <project_sch.h>
#include <wildcards_and_files_ext.h>
#include <string_utils.h>
#include <wx/log.h>
#include <wx/stdstream.h>
@@ -496,17 +498,11 @@ static void LoadSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aRootSheet, const w
if( topDocType == EASYEDA::DOC_TYPE::SCHEMATIC_SHEET
|| topDocType == EASYEDA::DOC_TYPE::SCHEMATIC_LIST )
{
int pageNum = 1;
EASYEDA::DOCUMENT_SCHEMATICS schDoc = js.get<EASYEDA::DOCUMENT_SCHEMATICS>();
bool first = true;
for( const EASYEDA::DOCUMENT& subDoc : *schDoc.schematics )
{
if( first )
first = false; // TODO
else
break;
if( subDoc.docType )
{
if( *subDoc.docType != EASYEDA::DOC_TYPE::SCHEMATIC_SHEET )
@@ -520,7 +516,56 @@ static void LoadSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aRootSheet, const w
EASYEDA::DOCUMENT dataStrDoc = subDoc.dataStr->get<EASYEDA::DOCUMENT>();
parser.ParseSchematic( aSchematic, aRootSheet, aFileName, dataStrDoc.shape );
if( schDoc.schematics->size() > 1 )
{
wxString sheetTitle =
!subDoc.title.empty() ? subDoc.title : ( wxString() << pageNum );
wxString sheetBaseName = EscapeString( sheetTitle, CTX_FILENAME );
wxFileName sheetFname( aFileName );
sheetFname.SetFullName(
sheetBaseName + wxS( "." )
+ wxString::FromUTF8( FILEEXT::KiCadSchematicFileExtension ) );
wxFileName relSheetPath( sheetFname );
relSheetPath.MakeRelativeTo(
wxFileName( aRootSheet->GetFileName() ).GetPath() );
std::unique_ptr<SCH_SHEET> subSheet = std::make_unique<SCH_SHEET>( aSchematic );
subSheet->SetFileName( relSheetPath.GetFullPath() );
subSheet->SetName( sheetTitle );
SCH_SCREEN* screen = new SCH_SCREEN( aSchematic );
screen->SetFileName( sheetFname.GetFullPath() );
screen->SetPageNumber( wxString() << pageNum );
subSheet->SetScreen( screen );
VECTOR2I pos;
pos.x = schIUScale.MilsToIU( 200 );
pos.y = schIUScale.MilsToIU( 200 )
+ ( subSheet->GetSize().y + schIUScale.MilsToIU( 200 ) )
* ( pageNum - 1 );
subSheet->SetPosition( pos );
SCH_SHEET_PATH sheetPath;
sheetPath.push_back( aRootSheet );
sheetPath.push_back( subSheet.get() );
sheetPath.SetPageNumber( wxString() << pageNum );
aSchematic->SetCurrentSheet( sheetPath );
parser.ParseSchematic( aSchematic, subSheet.get(), aFileName,
dataStrDoc.shape );
aRootSheet->GetScreen()->Append( subSheet.release() );
}
else
{
parser.ParseSchematic( aSchematic, aRootSheet, aFileName, dataStrDoc.shape );
}
pageNum++;
}
}
}
@@ -532,14 +532,14 @@ EASYEDAPRO::SYM_INFO SCH_EASYEDAPRO_PARSER::ParseSymbol( const std::vector<nlohm
{
VECTOR2D start, size;
wxString mimeType, data;
double angle = 0;
//double angle = 0;
int upsideDown = 0;
if( line.at( 3 ).is_number() )
{
start = VECTOR2D( line.at( 3 ), line.at( 4 ) );
size = VECTOR2D( line.at( 5 ), line.at( 6 ) );
angle = line.at( 7 );
//angle = line.at( 7 );
upsideDown = line.at( 8 );
wxString imageUrl = line.at( 9 );
@@ -563,7 +563,7 @@ EASYEDAPRO::SYM_INFO SCH_EASYEDAPRO_PARSER::ParseSymbol( const std::vector<nlohm
start = VECTOR2D( line.at( 4 ), line.at( 5 ) );
size = VECTOR2D( line.at( 6 ), line.at( 7 ) );
angle = line.at( 8 );
//angle = line.at( 8 );
data = line.at( 9 ).get<wxString>();
}
@@ -469,7 +469,9 @@ SCH_SHEET* SCH_IO_EASYEDAPRO::LoadSchematicFile( const wxString& aFileName,
if( !m_projectData )
return nullptr;
auto cbs = [&]( const wxString& name, const wxString& symUuid, wxInputStream& zip ) -> bool
const int schSheetsCount = prjSchematicSheets.size();
auto cbs = [&]( const wxString& name, const wxString& baseName, wxInputStream& zip ) -> bool
{
if( !name.EndsWith( wxS( ".esch" ) ) )
EASY_IT_CONTINUE;
@@ -500,41 +502,52 @@ SCH_SHEET* SCH_IO_EASYEDAPRO::LoadSchematicFile( const wxString& aFileName,
if( prjSheetIt == prjSchematicSheets.end() )
EASY_IT_CONTINUE;
wxString sheetBaseName =
sheetId + wxS( "_" ) + EscapeString( prjSheetIt->name, CTX_FILENAME );
wxFileName sheetFname( aFileName );
sheetFname.SetFullName( sheetBaseName + wxS( "." )
+ wxString::FromUTF8( FILEEXT::KiCadSchematicFileExtension ) );
std::unique_ptr<SCH_SHEET> subSheet = std::make_unique<SCH_SHEET>( aSchematic );
subSheet->SetFileName( sheetFname.GetFullPath() );
subSheet->SetName( prjSheetIt->name );
SCH_SCREEN* screen = new SCH_SCREEN( aSchematic );
screen->SetFileName( sheetFname.GetFullPath() );
screen->SetPageNumber( sheetId );
subSheet->SetScreen( screen );
VECTOR2I pos;
pos.x = schIUScale.MilsToIU( 200 );
pos.y = schIUScale.MilsToIU( 200 )
+ ( subSheet->GetSize().y + schIUScale.MilsToIU( 200 ) ) * ( sheetId_i - 1 );
subSheet->SetPosition( pos );
std::vector<nlohmann::json> lines = EASYEDAPRO::ParseJsonLines( zip, name );
SCH_SHEET_PATH sheetPath;
sheetPath.push_back( rootSheet );
sheetPath.push_back( subSheet.get() );
sheetPath.SetPageNumber( sheetId );
aSchematic->SetCurrentSheet( sheetPath );
if( schSheetsCount > 1 )
{
wxString sheetBaseName =
sheetId + wxS( "_" ) + EscapeString( prjSheetIt->name, CTX_FILENAME );
parser.ParseSchematic( aSchematic, subSheet.get(), project, m_projectData->m_Symbols,
m_projectData->m_Blobs, lines, libName );
wxFileName sheetFname( aFileName );
sheetFname.SetFullName( sheetBaseName + wxS( "." )
+ wxString::FromUTF8( FILEEXT::KiCadSchematicFileExtension ) );
rootSheet->GetScreen()->Append( subSheet.release() );
wxFileName relSheetPath( sheetFname );
relSheetPath.MakeRelativeTo( rootFname.GetPath() );
std::unique_ptr<SCH_SHEET> subSheet = std::make_unique<SCH_SHEET>( aSchematic );
subSheet->SetFileName( relSheetPath.GetFullPath() );
subSheet->SetName( prjSheetIt->name );
SCH_SCREEN* screen = new SCH_SCREEN( aSchematic );
screen->SetFileName( sheetFname.GetFullPath() );
screen->SetPageNumber( sheetId );
subSheet->SetScreen( screen );
VECTOR2I pos;
pos.x = schIUScale.MilsToIU( 200 );
pos.y = schIUScale.MilsToIU( 200 )
+ ( subSheet->GetSize().y + schIUScale.MilsToIU( 200 ) ) * ( sheetId_i - 1 );
subSheet->SetPosition( pos );
SCH_SHEET_PATH sheetPath;
sheetPath.push_back( rootSheet );
sheetPath.push_back( subSheet.get() );
sheetPath.SetPageNumber( sheetId );
aSchematic->SetCurrentSheet( sheetPath );
parser.ParseSchematic( aSchematic, subSheet.get(), project, m_projectData->m_Symbols,
m_projectData->m_Blobs, lines, libName );
rootSheet->GetScreen()->Append( subSheet.release() );
}
else
{
parser.ParseSchematic( aSchematic, rootSheet, project, m_projectData->m_Symbols,
m_projectData->m_Blobs, lines, libName );
}
EASY_IT_CONTINUE;
};

Some files were not shown because too many files have changed in this diff Show More