Compare commits

..

189 Commits

Author SHA1 Message Date
Wayne Stambaugh c2a41bad09 Tag stable version 8.0.3. 2024-06-03 07:37:50 -04:00
charrasjp 1a13bed1c1 French translation update 2024-06-02 17:32:18 +02:00
Seth Hillbrand 7b9c775cbd Update translations 2024-05-31 17:41:24 -07:00
Mark Hämmerling e9bf1daa5f Translated using Weblate (German)
Currently translated at 99.8% (9169 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/de/
2024-06-01 02:40:50 +02:00
Nguyễn Ngọc Khánh d6727934a5 Translated using Weblate (Vietnamese)
Currently translated at 21.6% (1987 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/vi/
2024-06-01 02:40:50 +02:00
Wellington Terumi Uemura a8df90762d Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (9183 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pt_BR/
2024-06-01 02:40:50 +02:00
Nguyễn Ngọc Khánh 7b4bb28307 Translated using Weblate (Vietnamese)
Currently translated at 21.4% (1972 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/vi/
2024-06-01 02:40:50 +02:00
CloverGit ee8744770f Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (9182 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-06-01 02:40:50 +02:00
Henrik Kauhanen ace480d3f6 Translated using Weblate (Swedish)
Currently translated at 99.9% (9181 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sv/
2024-06-01 02:40:50 +02:00
Henrik Kauhanen 154795d32a Translated using Weblate (Finnish)
Currently translated at 99.9% (9180 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/fi/
2024-06-01 02:40:50 +02:00
Henrik Kauhanen ce20c6ec77 Translated using Weblate (Swedish)
Currently translated at 99.9% (9180 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sv/
2024-06-01 02:40:50 +02:00
dsa-t 6380f29214 Translated using Weblate (Russian)
Currently translated at 100.0% (9183 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ru/
2024-06-01 02:40:50 +02:00
Jan Straka 1aaf767c5d Translated using Weblate (Czech)
Currently translated at 81.0% (7441 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/cs/
2024-06-01 02:40:50 +02:00
Henrik Kauhanen bd4ffa493f Translated using Weblate (Swedish)
Currently translated at 99.9% (9178 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sv/
2024-06-01 02:40:50 +02:00
Wellington Terumi Uemura cf26b12478 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (9183 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pt_BR/
2024-06-01 02:40:49 +02:00
ZbeeGin cdb26a9c97 Translated using Weblate (Polish)
Currently translated at 99.9% (9181 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pl/
2024-06-01 02:40:49 +02:00
Laurens Holst b5687b87bd Translated using Weblate (Dutch)
Currently translated at 100.0% (9183 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/nl/
2024-06-01 02:40:49 +02:00
Henrik Kauhanen e581ba4c7b Translated using Weblate (Swedish)
Currently translated at 99.9% (9177 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sv/
2024-06-01 02:40:49 +02:00
Toni Laiho a2064f85b1 Translated using Weblate (Finnish)
Currently translated at 99.9% (9180 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/fi/
2024-06-01 02:40:49 +02:00
Pferd O 2dbe4485cc Translated using Weblate (German)
Currently translated at 99.8% (9167 of 9183 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/de/
2024-06-01 02:40:49 +02:00
Mark Roszko 6b7b6fa3e3 Revert "Don't reset the view controls state just because we are setting the already active tool state again"
This reverts commit e914c0c1a0
2024-05-30 12:30:40 +00:00
Wayne Stambaugh be71f776ce Tag stable version 8.0.3 release candidate 1. 2024-05-25 07:26:08 -04:00
Mark Roszko 51ba4763f0 Don't let CaptureCursor fight modal dialog
(cherry picked from commit e9fde0051f)

Co-authored-by: Marek Roszko <mark.roszko@gmail.com>
2024-05-25 01:17:17 +00:00
Alex Shvartzkop f9a9db6503 Fix very tall Plot dialog on GTK.
Some scrollable controls need wxFIXED_MINSIZE, on some platforms, apparently.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16926
2024-05-24 23:35:21 +03:00
Alex Shvartzkop 8d001a8031 Switch length tuner settings action scope to global to make the hotkey work. 2024-05-24 17:46:15 +03:00
jean-pierre charras 88115e1dd2 Gerbview: fix a minor issue.
When the option "always hide all layers but active" is set, the active layer
changed using hotkeys or Toolbar layer selector did not update the visible
selection.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18059
2024-05-24 08:29:49 +02:00
Mark Roszko e914c0c1a0 Don't reset the view controls state just because we are setting the already active tool state again
(cherry picked from commit 132ecee665)

Co-authored-by: Marek Roszko <mark.roszko@gmail.com>
2024-05-24 02:49:27 +00:00
Jon Evans a1cd73e730 Fix bad clearance logic in cecc1a2f 2024-05-23 11:21:18 -04:00
Jon Evans cecc1a2ff1 Use true arc collision for segment<>arc
Using an approximation here results in different collision
results for segment<>arc than point<>arc, which
can cause odd behavior in the router.


(cherry picked from commit 5b3b0ff836)

Co-authored-by: Jon Evans <jon@craftyjon.com>
2024-05-23 12:58:01 +00:00
John Beard dc08cf3252 Eeschema: Also make 'note' backgrounds translucent on selection
For the same reason as device backgrounds - it obscures everything
else while moving a filled shape.

(cherry pick of commit 0bcd5e5795)
2024-05-23 16:52:30 +08:00
John Beard e20a11cbb3 Eeschema: Fix selection of items inside filled shapes
The selection heuristic broke down when one item was a filled
shape. Because all hit tests would succeed with distance 0 for
these shapes, they would always be considered the closest item
to the exclusion of all else, which made it very hard to
click on a graphic inside a filled shape.

Now, recognise when an item would be "dominating" and
decline to promote it to the "closet" spot. It will still
be selectable if there are no other items nearby, or if
there are multiple shapes.

(cherry picked from commit fd4c15517f)
2024-05-23 15:41:28 +08:00
Seth Hillbrand c27ca33a2e Ensure that the copper conn check re-adds epsilon
When checking if the particular rule is what is being checked, we rely
on the value of the minimum width.  Since we modified that to allow
width checking, this re-adds it for the comparison

(cherry picked from commit f74d1060d4)
2024-05-22 16:31:52 -07:00
Seth Hillbrand 1073ca0760 Include DRC Epsilon in connection width checker
Avoids rounding errors flagging connections too small by nanometers

(cherry picked from commit bce560d05f)
2024-05-22 16:31:52 -07:00
Jeff Young 4440fe0935 Fix keep-upright algo for footprint text.
Also removes PCB_FIELDs from rotation centre calc in
footprint editor if there is other stuff selected.

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

(cherry picked from commit 25bb3f77fa)
2024-05-22 14:47:26 -07:00
Seth Hillbrand d1cd859765 Re-enable moving of all footprint text in board
Seems like a lot of people really like to be able to modify the text
positions/content of their footprints

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

(cherry picked from commit 47e4ebb32a)
2024-05-22 10:36:42 -07:00
John Beard 36119b869c Pcbnew: Fix context menu when moving
The EDIT_TOOL is actually 'co-operating' with the SELECTION_TOOL
by putting its tools into the SELECTION_TOOL's menu. This means
the EDIT_TOOL::m_menu is sad and empty inside, and if you show it,
it either doesn't show at all, or a tiny stub is shown.

(cherry picked from commit af74d2a746)
2024-05-22 11:24:47 +08:00
Roberto Fernandez Bautista 3e5ceaa319 kicad-cli sym export svg: Ensure bounding box is correctly calculated
Fixes https://gitlab.com/kicad/code/kicad/-/issues/18062
2024-05-21 21:59:38 +02:00
Seth Hillbrand 78cd01038f Update translations 2024-05-21 09:38:08 -07:00
Ivan Chuba 7b4952df11 Translated using Weblate (Ukrainian)
Currently translated at 87.5% (8031 of 9171 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/uk/
2024-05-21 18:35:36 +02:00
CloverGit 73acc80c1d Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (9171 of 9171 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
2024-05-21 18:35:36 +02:00
pominglee 8b41207351 Translated using Weblate (Chinese (Traditional))
Currently translated at 99.9% (9165 of 9171 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
2024-05-21 18:35:36 +02:00
pominglee 5dbc1c7b18 Translated using Weblate (Chinese (Traditional))
Currently translated at 99.9% (9165 of 9171 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
2024-05-21 18:35:36 +02:00
Toni Laiho 5780a15468 Translated using Weblate (Finnish)
Currently translated at 99.9% (9168 of 9171 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/fi/
2024-05-21 18:35:36 +02:00
Ulices 15f6d5ad73 Translated using Weblate (Spanish (Mexico))
Currently translated at 100.0% (9171 of 9171 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/es_MX/
2024-05-21 18:35:36 +02:00
Nguyễn Ngọc Khánh 421bc27181 Translated using Weblate (Vietnamese)
Currently translated at 21.1% (1937 of 9171 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/vi/
2024-05-21 18:35:36 +02:00
Tokita, Hiroshi afe41498c4 Translated using Weblate (Japanese)
Currently translated at 99.9% (9167 of 9171 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ja/
2024-05-21 18:35:36 +02:00
Tokita, Hiroshi 92c40f2761 Translated using Weblate (Japanese)
Currently translated at 99.9% (9167 of 9171 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/ja/
2024-05-21 18:35:36 +02:00
Toni Laiho bb82d99a76 Translated using Weblate (Finnish)
Currently translated at 99.9% (9168 of 9171 strings)

Translation: KiCad EDA/v8
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/fi/
2024-05-21 18:35:36 +02:00
Andrew 1d0e118294 Translated using Weblate (Chinese (Traditional))
Currently translated at 99.9% (9165 of 9171 strings)

Co-authored-by: Andrew <yenchang.lin@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
Translation: KiCad EDA/v8
2024-05-21 18:35:36 +02:00
pominglee d40b12301d Translated using Weblate (Chinese (Traditional))
Currently translated at 99.9% (9165 of 9171 strings)

Co-authored-by: pominglee <pominglee@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hant/
Translation: KiCad EDA/v8
2024-05-21 18:35:36 +02:00
Toni Laiho 138d22b26f Translated using Weblate (Finnish)
Currently translated at 99.9% (9165 of 9171 strings)

Co-authored-by: Toni Laiho <apelegeos@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/fi/
Translation: KiCad EDA/v8
2024-05-21 18:35:36 +02:00
zly20129 9c69ea9df3 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (9171 of 9171 strings)

Co-authored-by: zly20129 <zly20129@icloud.com>
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/zh_Hans/
Translation: KiCad EDA/v8
2024-05-21 18:35:35 +02:00
Laurens Holst 3395738e55 Translated using Weblate (Dutch)
Currently translated at 100.0% (9171 of 9171 strings)

Co-authored-by: Laurens Holst <laurens@grauw.nl>
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/nl/
Translation: KiCad EDA/v8
2024-05-21 18:35:35 +02:00
Henrik Kauhanen 6afc2e727b Translated using Weblate (Finnish)
Currently translated at 99.7% (9148 of 9171 strings)

Translated using Weblate (Finnish)

Currently translated at 99.7% (9148 of 9171 strings)

Translated using Weblate (Swedish)

Currently translated at 99.9% (9168 of 9171 strings)

Co-authored-by: Henrik Kauhanen <henrik@kauhanen.se>
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/fi/
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/sv/
Translation: KiCad EDA/v8
2024-05-21 18:35:35 +02:00
Wellington Terumi Uemura f10864b3a7 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (9171 of 9171 strings)

Co-authored-by: Wellington Terumi Uemura <wellingtonuemura@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pt_BR/
Translation: KiCad EDA/v8
2024-05-21 18:35:35 +02:00
ZbeeGin 892602c070 Translated using Weblate (Polish)
Currently translated at 99.9% (9169 of 9171 strings)

Co-authored-by: ZbeeGin <zbeegin@op.pl>
Translate-URL: https://hosted.weblate.org/projects/kicad/v8/pl/
Translation: KiCad EDA/v8
2024-05-21 18:35:35 +02:00
Jeff Young d8f2a455e0 Reset zone offsets when exporting footprints.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17794

(cherry picked from commit af5ed5a118)
2024-05-21 11:41:07 +01:00
Jeff Young 561b2d490d Handle font when reading render cache.
(Also fixes a bug where the cache's triangulation wasn't
cached.)

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

(cherry picked from commit e332320108)
2024-05-21 11:36:36 +01:00
jean-pierre charras 1869da0e7d Dialog Export step: fix an issue when exporting a modified board file.
the DIALOG_EXPORT_STEP uses a auto saved copy of the current board to
create the step file (using kicad_cli).
But this file is not associated to a corresponding .kicad_pro file, and
this can create some issues (like the KIPRJMOD not defined)
So create a copy of the current board prj to export associated prj file
to the auto saved board file.
From master branch

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16973
2024-05-21 11:06:02 +02:00
dsa-t be2f317f6d Vertically center the color swatch in grid layer selector.
(cherry picked from commit 5f153eef7f)

Co-authored-by: Alex Shvartzkop <dudesuchamazing@gmail.com>
2024-05-21 02:35:49 +00:00
Seth Hillbrand c248993a84 Avoid snapping to edge cuts when routing
Snapping happens to elements on copper layers but edge cuts is only
_virtually_ on copper layers.  We need to set its routable flag off to
ensure we don't force-snap to the snap points
2024-05-20 15:08:12 -07:00
Seth Hillbrand 0a227ea916 Avoid int overflow in collisions
When calculating arc collisions, avoid overflowing the integer distance,
which gives a false nearest point
2024-05-20 15:08:12 -07:00
Seth Hillbrand f75e6dae84 Reserve shift for grid modification 2024-05-20 15:08:12 -07:00
Seth Hillbrand 160a493885 Ensure that arc closest positions are matched
We switch from squared to absolute calcualtion when calling into the arc
collision so be sure to catch the new positions and distances
2024-05-20 15:08:12 -07:00
Seth Hillbrand 625d241adf Avoid case where whole line is new head
If the whole line shifts, we may have no points of the old tail in the
new line.  In this case, we may not only not find the split point but we
may also have fewer points in the new line than were in the old head.
Clamping to the maximum potential point count prevents creating invalid
lines

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

(cherry picked from commit 586fddeec1)
2024-05-20 15:08:12 -07:00
Alex Shvartzkop 1264230973 STEP export: reverse Wire when adding it to Face as a hole.
Better fix for https://gitlab.com/kicad/code/kicad/-/issues/17446
2024-05-19 03:51:53 +03:00
Alex Shvartzkop 6dfd417767 Make IBIS errors visible / more obvious.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/18041
2024-05-19 01:44:16 +03:00
Jon Evans 585f11a01d Clear undo/redo lists when removing board layers
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17613


(cherry picked from commit 90ee5e097a)

Co-authored-by: Jon Evans <jon@craftyjon.com>
2024-05-18 22:16:28 +00:00
Jon Evans d6a121d617 Don't drag multiple coincident vias
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17915


(cherry picked from commit 7a3db2d176)

Co-authored-by: Jon Evans <jon@craftyjon.com>
2024-05-18 21:51:09 +00:00
Alex Shvartzkop dfd8aa402d Fix an assert in isCopperOutside. 2024-05-18 22:50:13 +03:00
Alex Shvartzkop 5b1c84b5dd STEP export: allow closing (and constructing) the wire with 1nm edges.
This is ok (and required) because we don't mess with BRepBuilderAPI::Precision nowadays.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18030
2024-05-18 22:50:13 +03:00
Jon Evans 11586863cf Fix broken hit test for arcs in via placer
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17844


(cherry picked from commit aaf3142e9a)

Co-authored-by: Jon Evans <jon@craftyjon.com>
2024-05-18 17:12:34 +00:00
Jon Evans d52e50a97a Altium: avoid crash when imported zone has no fill
Fix https://gitlab.com/kicad/code/kicad/-/issues/18025


(cherry picked from commit 4f3117aea0)

Co-authored-by: Jon Evans <jon@craftyjon.com>
2024-05-18 00:16:22 +00:00
Jon Evans fee0028ee9 Support LIB_ID queries in searchFootprints too
Fixes https://gitlab.com/kicad/code/kicad/-/issues/18039
2024-05-17 13:57:17 -04:00
Jon Evans a762311733 The upcoming Fedora 41 will use python 3.13
The Fedora folks are currently working on updating python to version
3.13 in Fedora 41.


(cherry picked from commit f8c8dcde13)

Co-authored-by: Steven A. Falco <stevenfalco@gmail.com>
2024-05-17 14:50:03 +00:00
Jon Evans e0581370e1 Fix bogus value field in spice test source.
(cherry picked from commit a0a368f47b)

Co-authored-by: Jeff Young <jeff@rokeby.ie>
2024-05-17 14:30:23 +00:00
Jon Evans 2cd0139cbf Remove extra NeedRIGHT in textbox parser
Fixes https://gitlab.com/kicad/code/kicad/-/issues/18033
2024-05-17 09:01:59 -04:00
Jeff Young 28cd2a203e Fix compiler version issues. 2024-05-17 12:59:30 +01:00
Jeff Young 33715143e3 Honour LAYER, SHEETNAME and SHEETPATH variable overrides on CLI.
Also allows the LAYER variable to work automatically
if you're plotting/exporting a single layer.

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

(cherry picked from commit 3e0c598500)
2024-05-17 11:38:56 +01:00
Jeff Young ba6fd2716e Lazily re-evaluate worst-clearance cache.
This prevents crashes when trying to re-evaluate
during destruction, etc. and is a cleaner solution
than trying to keep a flag updated.

It should also be a performance win for very large
documents.

Also implements proper threadlocking for the cache.

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

(cherry picked from commit 498d2c9db1)
2024-05-17 11:37:04 +01:00
Jeff Young 882ff06e24 More PEGTL tomfoolery.
(cherry picked from commit 8aaca0509c)
2024-05-17 11:25:26 +01:00
Jeff Young f52a51dce3 Reimplement bracedExpr and token lists for CPL models only.
This prevents the incompatibility between token lists
and single-token param-value pairs.

(cherry picked from commit 086e609c3d)
2024-05-17 11:25:22 +01:00
Jeff Young a96e16b766 Tighter control over braced-expression list separators.
(cherry picked from commit 2921d47fb3)
2024-05-17 11:25:19 +01:00
Jeff Young 81e51b00ca Remove support for multiple token values for CPL models.
It breaks param lists which contain single-token params
(ie: those without the "=<value>" part).

(cherry picked from commit 8bb807f170)
2024-05-17 11:25:15 +01:00
Jeff Young c01681a32e Repair variable resolution recursion guard.
(cherry picked from commit c8d1c1f1a4)
2024-05-17 11:24:37 +01:00
Jeff Young eeb9133588 Support multiple brace-expressions for CPL model lines.
(Nested brace-expressions, on the other hand, are *not*
an ngspice thing.)

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

(cherry picked from commit 0008991f02)
2024-05-17 11:24:21 +01:00
Jeff Young d45769e508 Allow .ends to be preceeded by whitespace.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/16560

(cherry picked from commit b934914c59)
2024-05-17 11:21:47 +01:00
Jeff Young a499bc9f66 Contour cache must be sensitive to size.
(While we scale the contours afterwards, font hint
data is size-sensitive so the contours are already
size-specific.)

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

(cherry picked from commit 98f4e60b90)
2024-05-17 11:20:38 +01:00
Jeff Young 341f102d79 Fix PEGTL flagParam grammar.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/16393

(cherry picked from commit c5162f5483)
2024-05-17 11:20:26 +01:00
Jeff Young 3e50a03ce7 Expose violation severity for co-located holes.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/18028

(cherry picked from commit 26906f383c)
2024-05-17 11:20:21 +01:00
Jon Evans 1defa3872e Clear field listener when quitting
Fixes https://gitlab.com/kicad/code/kicad/-/issues/18016


(cherry picked from commit 2836025402)

Co-authored-by: Jon Evans <jon@craftyjon.com>
2024-05-17 00:50:48 +00:00
jean-pierre charras e66d25b6e8 Eeschema, Pin helpers: fix wrong label orientation if the symbol is rotated
From Master branch

Fixes https://gitlab.com/kicad/code/kicad/-/issues/18012
2024-05-16 19:53:23 +02:00
jean-pierre charras 76f38600af Fix a 100% CPU core usage is some editing cases.
In commit 7cb754dd a call to wxMilliSleep(50) was removed (because it created
lag in editing) but this removal created a 100% CPU core usage.
Using a much small sleep time (1ms) fixes these issues.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17979
2024-05-16 17:40:06 +02:00
John Beard 44b0ef64e8 No longer auto-set the Footprint field when setting the FPID
This avoids forcing the field to the footprint name in the
library editor, which gets in the way. This doesn't specifically
inhibit the use of the field, and doesn't interfere with fields
users may have set manually (it can be cleared manually if
wished).

Removing the footprint field entirely either from all footprints
or from footprints in fpedit is quite a bit more invasive to
existing designs.

Relates-To: https://gitlab.com/kicad/code/kicad/-/issues/17998
2024-05-16 21:42:18 +08:00
John Beard c3e7509823 Allow to set LIB_FIELD size through property manager
This can be useful when managing auxiliary fields.

This is only for the 8.0 branch, as LIB_FIELD is merged
with SCH_FIELD in 8.99, so this is already handled.
2024-05-16 20:45:26 +08:00
Jeff Young 3622a296be Use consistent sorting for footprint libs.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17731

(cherry picked from commit 02bc093b55)
2024-05-15 11:25:41 +01:00
Jeff Young 0b48913876 Add mirrored column to fields grid table.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17956

(cherry picked from commit 0f3d14df38)
2024-05-15 11:25:02 +01:00
Jeff Young 9000cfb9cd Use display titles for axes in CSV output.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17324

(cherry picked from commit d9a6b2aec2)
2024-05-15 11:23:52 +01:00
Jeff Young c748645334 Fix typo.
(cherry picked from commit 5ba4900170)
2024-05-15 11:23:07 +01:00
Jeff Young 79443b7e59 Update signals & measurements when netlist might have changed.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17616

(cherry picked from commit 55b2c4dbf4)
2024-05-15 11:22:08 +01:00
Mark Roszko 02925fdecc Update file doxygen.yml
(cherry picked from commit 3a2b960f62)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2024-05-12 02:53:57 +00:00
Mark Roszko ef1e054bb6 Use our docker runner for doxygen
docker tag for shared gitlab runners was removed by gitlab

(cherry picked from commit 03459723b3)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2024-05-12 01:09:42 +00:00
Mark Roszko bb13ab2963 Remove the kicad-vcpkg xz override
(cherry picked from commit 695493fc3d)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2024-05-10 01:44:39 +00:00
Jeff Young 9c7fb0697c Don't double up ac and ph params.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17970
2024-05-09 23:36:32 +01:00
Jeff Young c92b11900b Don't add duplicate SIM fields.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17970
2024-05-09 23:36:32 +01:00
Jeff Young cde18d7ae7 The user can cancel the opening of many editors.
Don't play dice with the devil.

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

(cherry picked from commit a99377c1ec)
2024-05-09 23:36:32 +01:00
Jeff Young 1a932cb13b Don't modify radius when editing center.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17192

(cherry picked from commit 1290228fbf)
2024-05-09 23:36:32 +01:00
Jeff Young cc75d8c0af Exercise more care when comparing doubles.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17249

(cherry picked from commit 62d4bd7c1d)
2024-05-09 23:36:32 +01:00
Wayne Stambaugh cb93d2940c Fix QA DRC regression test issue.
(cherry picked from commit f1e8495dc9)
2024-05-09 10:38:47 -04:00
Wayne Stambaugh 88e0d373d1 Do not test for effective annular width when it's already within limits.
(cherry picked from commit 0402c03468)
2024-05-09 10:38:32 -04:00
Wayne Stambaugh c2d59c6103 Fix false annular ring width DRC test failure.
The DRC annular ring width test failed to take into account that a pad
could be contained inside another pad having the same number (thermal
vias for example) which changes the effective annular width of the pad
contained within another pad.  A test was added to calculate the effective
annular ring width in this case.

Added some PNS log viewer helper and test code to the PNS playground QA
utility for testing the effective pad annular width code.

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

(cherry picked from commit a508f2e716)
2024-05-09 10:38:17 -04:00
Seth Hillbrand f8f48f922e Show disambiguated netname when needed
When using subsheets with nets that end in the same netname, it can be
confusing in pcbnew to know which net you are dealing with.  In these
cases, we show the full netname including path to assist when routing

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

(cherry picked from commit b346cde30b)
2024-05-09 02:57:48 +02:00
Alex Shvartzkop eb7e781bec Send project path to ngspice for code model input files.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/16527
2024-05-08 23:39:34 +03:00
Alex Shvartzkop 378300c733 Don't hide symbol/footprint preview widgets on scroll.
(cherry picked from commit dc8822b421)
2024-05-08 19:44:59 +03:00
Jon Evans ddd7c35586 DbLib: Prevent uncaught exception creating statement
Defer telling the statement about the connection until the
try block, because otherwise it can connect immediately and
potentially throw an exception if the connection fails.
2024-05-06 16:59:49 -04:00
Seth Hillbrand 6482a322da Optionally use electrical type when shown.
We also need to consider electrical type as an exact hit when we are
showing it.  Otherwise, we get the pin added to our consideration list
but not selected without hitting close neighbors

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

(cherry picked from commit 3620887a22)
2024-05-06 10:38:28 -07:00
Seth Hillbrand dc6d421fa2 Avoid arbitrary string limits
Placing a limit on the number of values that a field is allowed to hold
makes it blank when we set more than this number.  There's not a good
reason to limit the number of digits we allow at the field level (we
round to 4 decimal points in the backend)

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

(cherry picked from commit cb71f2f207)
2024-05-06 10:00:51 -07:00
Mike Williams 7b19fb0c8d Legacy Libraries: fix Description field clobbering user field
Fixes: https://gitlab.com/kicad/code/kicad/-/issues/17943
2024-05-06 12:15:14 -04:00
Mark Roszko f6480d67eb Fix help for kicad-cli pcb export pos --side
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15815


(cherry picked from commit 030a251090)

0b94c436 fix https://gitlab.com/kicad/code/kicad/-/issues/15815
8e6bb91b Update file command_pcb_export_pos.cpp

Co-authored-by: Stefan <2252537-stefan_test@users.noreply.gitlab.com>
2024-05-06 13:37:03 +00:00
Alex Shvartzkop 35c788a332 Fix polygon fill flag in pcbnew graphics (SVG) importer.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17957
2024-05-06 14:16:49 +03:00
Seth Hillbrand a0cba3a9af Re-initialize conversion settings on failure
When the conversion fails, it may be the result of the settings values,
so reset them to their original values afterward

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

(cherry picked from commit 4c0fd6e791)
2024-05-06 11:42:54 +01:00
Jeff Young af6835e766 Improve bounding hull error message.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17886

(cherry picked from commit 651cc5c838)
2024-05-06 11:42:34 +01:00
Mike Williams 1f88d33c81 BOM Export: remember filename per project
Fixes: https://gitlab.com/kicad/code/kicad/-/issues/17704
(cherry picked from commit 9c058503d9)
2024-05-06 11:38:15 +01:00
Jeff Young 6aee6f857e Don't leak output file path between projects.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17846

(cherry picked from commit 0e9b547f94)
2024-05-06 11:37:52 +01:00
jean-pierre charras 6d69fee097 PCB_IO_KICAD_SEXPR_PARSER::parseEDA_TEXT(): ensure texts are not mirrored
When not specified as mirrored, texts must be not mirrored.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17955
2024-05-06 11:17:17 +02:00
Alex Shvartzkop c7dd993439 Add OpenGL info to About.
(cherry picked from commit 5e14ae9698)
2024-05-05 21:58:10 +03:00
Jeff Young 7e5dd02ef1 Don't abort on failure to backup file if it was never saved.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17810

(cherry picked from commit 0e0432d194)
2024-05-05 14:59:07 +01:00
Jon Evans ca16ff05df Altium pcbimport: handle various dimension items, fix dimension_kind enum
(cherry picked from commit ce32dfd077)

e627d587 handle various dimension items, fix dimension_kind enum, this doesn't parse...
e89d1826 fix formating
07686833 change to Reporter for logging
a535d13d remove old comments
554c9565 Update file altium_pcb.cpp

Co-authored-by: Stefan <2252537-stefan_test@users.noreply.gitlab.com>
2024-05-04 16:38:32 +00:00
Jon Evans b8fa10ab2b Add optional reporting of non-KiCad design issues
Also add HTML reporter to PCB side to match schematic
2024-05-04 11:27:22 -04:00
Jon Evans 09736ebf2c Get rid of relative position in pad properties dialog
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17246
2024-05-03 23:31:36 -04:00
Jeff Young 897b9fe6a1 Restore accidentally deleted text size constraint algo.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17284

(cherry picked from commit c998234dec)
2024-05-03 22:16:16 +01:00
Jeff Young 48f14d6dea Handle orientation when pasting footprint items.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17518

(cherry picked from commit 94223ca794)
2024-05-03 22:15:53 +01:00
Jeff Young 1ef916086d pruneItemLayers() is not the right place to filter refdes & value.
(And we already filter all mandatory fields in
pasteFootprintItemsToFootprintEditor() anyway.)

Also, don't nuke a footprint which contains only fields
during a paste.

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

(cherry picked from commit eb13dec265)
2024-05-03 22:15:05 +01:00
Jeff Young 0b44ba61d8 Improve consistency in free-via ambiguity tests.
Also removes a magic number.

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

(cherry picked from commit 58ddffe3dd)
2024-05-03 22:15:05 +01:00
Jon Evans 3c99a3797e DbLib: Fill entire table if cache is empty when loading one part
The "already placed parts" feature causes a situation where many
single-part queries are placed before the cache is even filled.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17940
2024-05-03 17:03:55 -04:00
Seth Hillbrand 76c98859bf Fix renaming sheet check
If we are renaming a sheet that exists only once in the schematic, then
we don't need to warn about case sensitivity.  If the sheet exists
multiple times, we do.  We can't check this using SCREENS because the
screens don't maintain full state information about where they are used.

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

(cherry picked from commit ba4974749c)
2024-05-03 13:23:51 -07:00
Seth Hillbrand 57c8fbc9fe Special-case copy/paste of footprint fields on board
When editing the board, footprint fields _look_ like text items, so copy
and paste of these items should logically result in a text item, not a
footprint copy.

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

(cherry picked from commit 71b020eb14)
2024-05-03 11:00:19 -07:00
Seth Hillbrand bbac5430cf DRC: special case circles for annular width check
Circles only use one dimension and we tend to ignore the other in our UI
but it is kept and reflects the previous second dimensional value.  When
checking DRC, we should only be concerned with the single value used
unless the pad has two dimensions

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

(cherry picked from commit e3d2f338de)
2024-05-03 10:07:29 -07:00
Seth Hillbrand 279ef4210d Use StandardPrimitive library for vias
Some 2581 parsers don't like to consider UserPrimitive even though they
are essentially the same thing and required by the standard.  ¯\_(ツ)_/¯

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

(cherry picked from commit 13735050da)
2024-05-03 09:12:43 -07:00
Jon Evans 2ef18ad4ca Fix deduplication of already-placed symbols
The comparison function was failing to properly
de-duplicate by LIB_ID, especially for parts
from database libraries, causing the list to grow
with the size of the design.
2024-05-03 11:39:01 -04:00
Jon Evans 1a76fce255 Make sure database library has updated pointer to library table
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17903
2024-05-03 11:39:01 -04:00
Mark Roszko ee75a50d84 Update vcpkg wxpython
(cherry picked from commit 1a1be2d542)

Co-authored-by: Marek Roszko <mark.roszko@gmail.com>
2024-05-03 02:17:30 +00:00
Mark Roszko 99d8d0bc63 Use the new kmb toolchain file for vars
(cherry picked from commit f00a1ab517)

Co-authored-by: Mark Roszko <mark.roszko@gmail.com>
2024-05-03 02:15:52 +00:00
Mark Roszko f859fe37ca Add updated tooltips on update dialog
(cherry picked from commit cb81de5a74)

Co-authored-by: Marek Roszko <mark.roszko@gmail.com>
2024-05-03 01:39:50 +00:00
Alex Shvartzkop 451cb7a194 Fix warnings. 2024-05-03 00:09:24 +03:00
Alex Shvartzkop 17175fe71e EasyEDA Std/Pro: import (some) component metadata for symbols.
Also fixes Reference numbering.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17806
2024-05-03 00:05:39 +03:00
Seth Hillbrand f8b02f99dd Keep FP chooser on top of KiCad but not system
We don't need to float the window over other programs, so setting to
parental floating keeps it focused just the right amount

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

(cherry picked from commit 60f59ae851)
2024-05-02 13:12:21 -07:00
Seth Hillbrand 69fb86322c Re-allow moving footprint text
This is a temporary solution until we modify loading to convert existing
text to fields

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

(cherry picked from commit b649932dbf)
2024-05-02 13:00:37 -07:00
Seth Hillbrand 4d683232b7 Remove faulty tooltip
Copy-pasta error

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

(cherry picked from commit b211625e53)
2024-05-02 12:46:26 -07:00
Jon Evans cb7e0e4383 Altium: apply power filter to symbol libraries
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17922
2024-05-01 22:47:19 -04:00
Jon Evans 90b62762d3 Support ortho dragging labels off sheet pins 2024-05-01 22:10:18 -04:00
Jon Evans 787a9ae4e4 Pin helpers can help sheet pins also
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17923
2024-05-01 22:10:02 -04:00
Jon Evans 83be5ba63d Move ALTIUM_PCB to use REPORTER for logging
Change not-yet-supported messages to debug level

(cherry picked from commit e973c15087)
2024-05-01 19:17:09 -04:00
Jeff Young e1cad6189e Don't assume that a SMD pad has copper layers.
(cherry picked from commit 9a6efd43e1)
2024-05-01 18:29:36 +01:00
Mike Williams f29fc2a025 PCB Fields: fix v7 imported board hidden description field pos
Fixes: https://gitlab.com/kicad/code/kicad/-/issues/17684
2024-05-01 09:24:54 -04:00
Mark Roszko 43d4c8d801 Point BEGIN_EVENT_TABLE at the correct base class, fix current lang indication
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17825


(cherry picked from commit aaf776db9e)

Co-authored-by: Marek Roszko <mark.roszko@gmail.com>
2024-05-01 02:48:19 +00:00
Wayne Stambaugh c179f4d4f1 Use correct value field text when importing Eagle schematic symbols.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17130

(cherry picked from commit 865225fcca)
2024-04-30 13:02:29 -04:00
jean-pierre charras ac8b3989be DIALOG_EXPORT_2581:fix incorrect size of widgets when a very long field name exists
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17911
2024-04-30 18:22:22 +02:00
Mark Roszko 9a7b1a20dc Update sentry-native to 0.7.2
(cherry picked from commit 2f0ff4e557)

Co-authored-by: Marek Roszko <mark.roszko@gmail.com>
2024-04-30 11:39:47 +00:00
Alex Shvartzkop cff58bae7f Fix internal simulation errors when using some IBIS models.
Usage of GC_PWR0 looked like a copy/paste.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17701
2024-04-29 23:24:46 +03:00
Jeff Young 2ee2d7d5d9 Separate Compare Footprints from DRC.
(We want to ignore some of the flags for DRC.)

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

(cherry picked from commit 43e6006306)
2024-04-29 16:27:24 +01:00
Jeff Young 743759578d Use a lighter touch keeping internal data structures in sync.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17493

(cherry picked from commit d0df8df7c7)
2024-04-29 13:45:17 +01:00
Mark Roszko 9f1d1fc45e Delete m_locale in the pgm_base destructor instead of manual destroy method
We need the object in m_locale for a bit more things during program cleanup,
especially on macOS

The destructor of PGM_BASE is sufficient allowance of lifetime.

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


(cherry picked from commit 9ffa5db667)

Co-authored-by: Marek Roszko <mark.roszko@gmail.com>
2024-04-29 11:48:22 +00:00
Mark Roszko b4ea25dccb Bump kicad-vcpkg baseline 2024-04-29 11:10:29 +00:00
Alex Shvartzkop f15551a6b5 3D viewer: apply OCC colors in order: XCAFDoc_ColorSurf > XCAFDoc_ColorCurv > XCAFDoc_ColorGen
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14906
2024-04-29 01:25:31 +03:00
Jeff Young 5c0a654e1e Save project settings after Schematic Setup.
This prevents data from getting lost if we later crash.

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

(cherry picked from commit d8d816236c)
2024-04-28 21:54:16 +01:00
Jeff Young edace908fb Make sure color settings are saved when modified.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17864

(cherry picked from commit 3b3de58e5e)
2024-04-28 21:54:16 +01:00
Jeff Young ff966eaf62 Gracefully handle DNP & Excl-from-brd components in nets list.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17146

(cherry picked from commit 9be60cb45d)
2024-04-28 21:54:16 +01:00
Jeff Young a39b9b8890 Support legacy Length Tuning Settings workflow.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17748

(cherry picked from commit 978ef352d0)
2024-04-28 21:54:16 +01:00
Jeff Young 9f39420808 Layer column should be shown by default, not italic.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17758

(cherry picked from commit 9dab855f8d)
2024-04-28 21:54:16 +01:00
Jeff Young 67b5e86cc4 Default to target lib when no lib tree sel exists.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17808

(cherry picked from commit f51d227dc7)
2024-04-28 21:54:16 +01:00
Jeff Young baaa8b6537 Fix merge error. 2024-04-28 21:54:16 +01:00
Jeff Young 4f776050e6 Clean up selection logic.
Don't try to do too many things at once.  Separate
out fooptrint-children handling, visibility-handling,
and footprintEditor vs boardEditor differences.

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

(cherry picked from commit 3958d1bf14)
2024-04-28 21:54:16 +01:00
Jeff Young fa490644dd Allow selection promotion when editing wrong field type.
Also fixes a bug where a CHT_MODIFY on a parent symbol with a
selected child doesn't trigger a selection modified event.

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

(cherry picked from commit 1aa59b806c)
2024-04-28 21:54:16 +01:00
Jeff Young 0363806e7e Allow no-net teardrops on no-net pads with no-net tracks.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17566

(cherry picked from commit 50567764b5)
2024-04-28 21:54:16 +01:00
Jeff Young c0a608bfdd Keep internal data consistent when changing pad type.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17493

(cherry picked from commit 859f553c91)
2024-04-28 21:54:16 +01:00
Jeff Young fe26628113 Internationalise pin info when language changes.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17224

(cherry picked from commit c5c65f23a4)
2024-04-28 21:54:16 +01:00
Alex Shvartzkop c7ead70e0f Fix orientations of some footprint STEP models.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/17631

(cherry picked from commit 7d37cebfdf)
2024-04-28 23:19:34 +03:00
Wayne Stambaugh 31177be88f Property grid navigation improvements.
* Do not handle tab key event when committing property changes so the
  property grid tab navigation works correctly.
* Do not call commit property changes on tab key when no changes are
  pending.
* Skip event handling in the base object value change and changing event
  handlers in case they do not get overloaded in derived objects.
* Do not force focus to canvas on property change so arrow and tab key
  grid navigation work properly.  Forcing the user to click the property
  grid control to edit a single property doesn't make sense.
* Pass properties panel show event up the event stack.
* Do not set focus to canvas in tool dispatcher if it already has the
  focus.

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

manully cherry picked from commit 8a1347d2c8
2024-04-28 08:25:24 -04:00
Wayne Stambaugh 48fd6bab7b Symbol chooser dialog layout improvements.
(cherry picked from commit 33869dbb61)
2024-04-28 07:43:43 -04:00
Wayne Stambaugh 9fd2b32665 Do not show click to start wire cursor for hidden pins.
Selecting show hidden pins will allow users to connect to hidden pins.

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

(cherry picked from commit ca18dc8ec8)
2024-04-28 07:39:34 -04:00
Wayne Stambaugh 1ba05d4c9c Improve symbol instance data file save ordering.
Use the root schematic UUID to order projects and sort symbol instance
data by KIID_PATH.  This will ensure file changes to instance data are
more consistent by using a fixed ordering.

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

(cherry picked from commit a86a258f66)
2024-04-28 07:15:22 -04:00
Wayne Stambaugh bae3ccdfb5 Use correct project name when adding new symbol instances.
When adding a sheet using a schematic from another project, set the
project name for the new symbol instance data to the current project
rather than the project name from the copied instance data.

(cherry picked from commit 5d99aaf0a4)
2024-04-28 07:06:03 -04:00
Alex Shvartzkop dd2f15c96d QA: update Altium footprint library golden file. 2024-04-27 23:34:39 +03:00
Marek Roszko 7e04a1b8d3 Hackfix macOS to keep erc/drc on top
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14356
2024-04-27 13:38:41 -04:00
Mark Roszko aea70a14ff Fix win32 proxy parsing when the old IE options for scheme based configuration was set
If you uncheck in the old IE options "Use the same proxy server for all protocols", then it returns an annoying string
like http=blah:1232;https=blah:1232;ftp=blah:2321 which we have to parse.


(cherry picked from commit 60d5780c1c)

Co-authored-by: Marek Roszko <mark.roszko@gmail.com>
2024-04-27 17:30:03 +00:00
dsa-t 8edfc23679 Altium PCB import: pad thermal spoke angle is 90 deg by default.
(cherry picked from commit 11ba59b690)

Co-authored-by: Alex Shvartzkop <dudesuchamazing@gmail.com>
2024-04-27 17:27:07 +00:00
dsa-t 87f3d45109 Require Wayland 1.20 libraries.
KiCad doesn't build with older versions due to missing definitions.


(cherry picked from commit e26778c599)

Co-authored-by: Alex Shvartzkop <dudesuchamazing@gmail.com>
2024-04-27 17:26:57 +00:00
Wayne Stambaugh 2ca07b47af Begin version 8.0.3 development. 2024-04-27 13:10:22 -04:00
537 changed files with 91672 additions and 72064 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ build_doxygen_docker:
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_JOB_NAME == "doxygen"
tags:
- docker
- gitlab-org-docker
before_script:
- docker info
- docker login -u gitlab-ci-token -p "$CI_JOB_TOKEN" "$CI_REGISTRY"
+1 -19
View File
@@ -15,25 +15,7 @@ macos_build:
- cd build/macos
- cmake
-G Ninja
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DDEFAULT_INSTALL_PATH=/Library/Application\ Support /kicad
-DOCC_INCLUDE_DIR=/opt/homebrew/Cellar/opencascade/7.7.2_2/include/opencascade
-DOCC_LIBRARY_DIR=/opt/homebrew/Cellar/opencascade/7.7.2_2/Lib
-DCMAKE_INSTALL_PREFIX=/Users/ci/kicad-mac-builder/build/kicad-dest
-DCMAKE_C_COMPILER=/usr/bin/clang
-DCMAKE_CXX_COMPILER=/usr/bin/clang++
-DwxWidgets_CONFIG_EXECUTABLE=/Users/ci/kicad-mac-builder/build/wxwidgets-dest/bin/wx-config
-DKICAD_BUILD_I18N=ON
-DKICAD_SCRIPTING_WXPYTHON=ON
-DKICAD_BUILD_PNS_DEBUG_TOOL=ON
-DPYTHON_EXECUTABLE=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/bin/python3
-DPYTHON_INCLUDE_DIR=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/include/python3.9/
-DPYTHON_LIBRARY=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/lib/libpython3.9.dylib
-DPYTHON_SITE_PACKAGE_PATH=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework/Versions/Current/lib/python3.9/site-packages
-DPYTHON_FRAMEWORK=/Users/ci/kicad-mac-builder/build/python-dest/Library/Frameworks/Python.framework
-DNGSPICE_INCLUDE_DIR=/Users/ci/kicad-mac-builder/build/ngspice-dest/include
-DNGSPICE_LIBRARY=/Users/ci/kicad-mac-builder/build/ngspice-dest/lib/libngspice.dylib
-DKICAD_USE_3DCONNEXION=ON
-DCMAKE_TOOLCHAIN_FILE=/Users/ci/kicad-mac-builder/toolchain/kicad-mac-builder.cmake
../../
- cmake --build . 2>&1 | tee compilation_log.txt
- cd ../../
+2
View File
@@ -708,6 +708,8 @@ void BOARD_ADAPTER::SetLayerColors( const std::map<int, COLOR4D>& aColors )
for( const auto& [ layer, color ] : aColors )
settings->SetColor( layer, color );
Pgm().GetSettingsManager().SaveColorSettings( settings, "3d_viewer" );
}
+4
View File
@@ -33,6 +33,7 @@
#include <3d_rendering/opengl/render_3d_opengl.h>
#include <3d_viewer_id.h>
#include <advanced_config.h>
#include <build_version.h>
#include <board.h>
#include <reporter.h>
#include <gal/opengl/gl_context_mgr.h>
@@ -229,6 +230,9 @@ bool EDA_3D_CANVAS::initializeOpenGL()
From_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
}
SetOpenGLInfo( (const char*) glGetString( GL_VENDOR ), (const char*) glGetString( GL_RENDERER ),
(const char*) glGetString( GL_VERSION ) );
wxString version = From_UTF8( (char *) glGetString( GL_VERSION ) );
wxLogTrace( m_logTrace, wxT( "EDA_3D_CANVAS::%s OpenGL version string %s." ),
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2021 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
@@ -35,6 +35,7 @@
#include "../3d_cache/3d_cache.h"
#include <wx/dcclient.h>
#include <base_units.h>
#include <build_version.h>
#include <gal/opengl/gl_context_mgr.h>
#include <settings/common_settings.h>
#include <pgm_base.h>
@@ -200,6 +201,9 @@ void EDA_3D_MODEL_VIEWER::ogl_initialize()
From_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
}
SetOpenGLInfo( (const char*) glGetString( GL_VENDOR ), (const char*) glGetString( GL_RENDERER ),
(const char*) glGetString( GL_VERSION ) );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
+2 -1
View File
@@ -138,7 +138,7 @@ void IMAGE_SIZE::SetUnit( EDA_UNITS aUnit )
}
BEGIN_EVENT_TABLE( BITMAP2CMP_FRAME, EDA_BASE_FRAME )
BEGIN_EVENT_TABLE( BITMAP2CMP_FRAME, KIWAY_PLAYER )
EVT_MENU( wxID_CLOSE, BITMAP2CMP_FRAME::OnExit )
EVT_MENU( wxID_EXIT, BITMAP2CMP_FRAME::OnExit )
@@ -193,6 +193,7 @@ BITMAP2CMP_FRAME::BITMAP2CMP_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_toolManager->InitTools();
ReCreateMenuBar();
setupUIConditions();
GetSizer()->SetSizeHints( this );
+1 -1
View File
@@ -37,7 +37,7 @@ unset(_Python_NAMES)
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
set(_PYTHON3_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
set(_PYTHON3_VERSIONS 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
# Disabling the "search every possible place" code for now
# see https://gitlab.com/kicad/code/kicad/-/issues/8553
+1 -1
View File
@@ -44,7 +44,7 @@ cmake_find_frameworks(Python)
set(_PYTHON1_VERSIONS 1.6 1.5)
set(_PYTHON2_VERSIONS 2.7 2.6 2.5 2.4 2.3 2.2 2.1 2.0)
set(_PYTHON3_VERSIONS 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
set(_PYTHON3_VERSIONS 3.13 3.12 3.11 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 3.1 3.0)
if(PythonLibs_FIND_VERSION)
if(PythonLibs_FIND_VERSION MATCHES "^[0-9]+\\.[0-9]+(\\.[0-9]+.*)?$")
+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.2" )
set( KICAD_SEMANTIC_VERSION "8.0.3" )
# Default the version to the semantic version.
# This is overridden by the git repository tag though (if using git)
+19
View File
@@ -51,6 +51,19 @@ extern std::string GetCurlLibVersion();
#include <kicad_build_version.h>
#undef INCLUDE_KICAD_VERSION
// Remember OpenGL info
static wxString s_glVendor;
static wxString s_glRenderer;
static wxString s_glVersion;
void SetOpenGLInfo( const char* aVendor, const char* aRenderer, const char* aVersion )
{
s_glVendor = wxString::FromUTF8( aVendor );
s_glRenderer = wxString::FromUTF8( aRenderer );
s_glVersion = wxString::FromUTF8( aVersion );
}
wxString GetPlatformGetBitnessName()
{
wxPlatformInfo platform;
@@ -200,6 +213,12 @@ wxString GetVersionInfoData( const wxString& aTitle, bool aHtml, bool aBrief )
<< ", " << wxGetenv( "XDG_SESSION_TYPE" );
#endif
if( !s_glVendor.empty() || !s_glRenderer.empty() || !s_glVersion.empty() )
{
aMsg << eol;
aMsg << "OpenGL: " << s_glVendor << ", " << s_glRenderer << ", " << s_glVersion;
}
aMsg << eol << eol;
if( !aBrief )
+87 -51
View File
@@ -347,6 +347,24 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
return true;
}
}
else
{
wxLogTrace( traceDatabase, wxT( "SelectOne: table `%s` not in row cache; will SelectAll" ),
tableName, aWhere.second );
selectAllAndCache( tableName, aWhere.first );
if( m_cache->Get( tableName, cacheEntry ) )
{
if( cacheEntry.count( aWhere.second ) )
{
wxLogTrace( traceDatabase, wxT( "SelectOne: `%s` with parameter `%s` - cache hit" ),
tableName, aWhere.second );
aResult = cacheEntry.at( aWhere.second );
return true;
}
}
}
if( !m_columnCache.count( tableName ) )
{
@@ -372,15 +390,14 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
columnsFor( tableName ),
m_quoteChar, tableName, m_quoteChar,
m_quoteChar, columnName, m_quoteChar );
nanodbc::statement statement( *m_conn );
nanodbc::string query = fromUTF8( queryStr );
PROF_TIMER timer;
nanodbc::statement statement;
try
{
statement.prepare( query );
statement.prepare( *m_conn, query );
statement.bind( 0, aWhere.second.c_str() );
}
catch( nanodbc::database_error& e )
@@ -474,44 +491,14 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
}
bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::string& aKey,
std::vector<ROW>& aResults )
bool DATABASE_CONNECTION::selectAllAndCache( const std::string& aTable, const std::string& aKey )
{
if( !m_conn )
{
wxLogTrace( traceDatabase, wxT( "Called SelectAll without valid connection!" ) );
return false;
}
auto tableMapIter = m_tables.find( aTable );
if( tableMapIter == m_tables.end() )
{
wxLogTrace( traceDatabase, wxT( "SelectAll: requested table %s not found in cache" ),
aTable );
return false;
}
DB_CACHE_TYPE::CACHE_VALUE cacheEntry;
if( m_cache->Get( aTable, cacheEntry ) )
{
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - cache hit" ), aTable );
aResults.reserve( cacheEntry.size() );
for( auto &[ key, row ] : cacheEntry )
aResults.emplace_back( row );
return true;
}
nanodbc::statement statement( *m_conn );
nanodbc::string query = fromUTF8( fmt::format( "SELECT {} FROM {}{}{}", columnsFor( aTable ),
m_quoteChar, aTable, m_quoteChar ) );
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s`" ), toUTF8( query ) );
wxLogTrace( traceDatabase, wxT( "selectAllAndCache: `%s`" ), toUTF8( query ) );
PROF_TIMER timer;
@@ -522,7 +509,8 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
catch( nanodbc::database_error& e )
{
m_lastError = e.what();
wxLogTrace( traceDatabase, wxT( "Exception while preparing query for SelectAll: %s" ),
wxLogTrace( traceDatabase,
wxT( "Exception while preparing query for selectAllAndCache: %s" ),
m_lastError );
// Exception may be due to a connection error; nanodbc won't auto-reconnect
@@ -540,7 +528,8 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
catch( nanodbc::database_error& e )
{
m_lastError = e.what();
wxLogTrace( traceDatabase, wxT( "Exception while executing query for SelectAll: %s" ),
wxLogTrace( traceDatabase,
wxT( "Exception while executing query for selectAllAndCache: %s" ),
m_lastError );
// Exception may be due to a connection error; nanodbc won't auto-reconnect
@@ -551,15 +540,17 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
timer.Stop();
DB_CACHE_TYPE::CACHE_VALUE cacheEntry;
auto handleException =
[&]( std::runtime_error& aException, const std::string& aExtraContext = "" )
{
m_lastError = aException.what();
std::string extra = aExtraContext.empty() ? "" : ": " + aExtraContext;
wxLogTrace( traceDatabase,
wxT( "Exception while parsing result %d from SelectAll: %s%s" ),
aResults.size(), m_lastError, extra );
};
{
m_lastError = aException.what();
std::string extra = aExtraContext.empty() ? "" : ": " + aExtraContext;
wxLogTrace( traceDatabase,
wxT( "Exception while parsing result %d from selectAllAndCache: %s%s" ),
cacheEntry.size(), m_lastError, extra );
};
while( results.next() )
{
@@ -636,20 +627,65 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
}
}
aResults.emplace_back( std::move( result ) );
m_cache->Put( aTable, cacheEntry );
wxASSERT( result.count( aKey ) );
std::string keyStr = std::any_cast<std::string>( result.at( aKey ) );
cacheEntry[keyStr] = result;
}
wxLogTrace( traceDatabase, wxT( "SelectAll from %s completed in %0.1f ms" ), aTable,
wxLogTrace( traceDatabase, wxT( "selectAllAndCache from %s completed in %0.1f ms" ), aTable,
timer.msecs() );
for( const ROW& row : aResults )
m_cache->Put( aTable, cacheEntry );
return true;
}
bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::string& aKey,
std::vector<ROW>& aResults )
{
if( !m_conn )
{
wxASSERT( row.count( aKey ) );
std::string keyStr = std::any_cast<std::string>( row.at( aKey ) );
cacheEntry[keyStr] = row;
wxLogTrace( traceDatabase, wxT( "Called SelectAll without valid connection!" ) );
return false;
}
m_cache->Put( aTable, cacheEntry );
auto tableMapIter = m_tables.find( aTable );
if( tableMapIter == m_tables.end() )
{
wxLogTrace( traceDatabase, wxT( "SelectAll: requested table %s not found in cache" ),
aTable );
return false;
}
DB_CACHE_TYPE::CACHE_VALUE cacheEntry;
if( !m_cache->Get( aTable, cacheEntry ) )
{
if( !selectAllAndCache( aTable, aKey ) )
{
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` cache fill failed" ), aTable );
return false;
}
// Now it should be filled
m_cache->Get( aTable, cacheEntry );
}
if( !m_cache->Get( aTable, cacheEntry ) )
{
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` failed to get results from cache!" ),
aTable );
return false;
}
wxLogTrace( traceDatabase, wxT( "SelectAll: `%s` - returning cached results" ), aTable );
aResults.reserve( cacheEntry.size() );
for( auto &[ key, row ] : cacheEntry )
aResults.emplace_back( row );
return true;
}
+29
View File
@@ -681,6 +681,35 @@ void DS_DATA_ITEM_TEXT::SetConstrainedTextSize()
if( m_ConstrainedTextSize.y == 0 )
m_ConstrainedTextSize.y = DS_DATA_MODEL::GetTheInstance().m_DefaultTextSize.y;
if( m_BoundingBoxSize.x > 0 || m_BoundingBoxSize.y > 0 )
{
// to know the X and Y size of the line, we should use EDA_TEXT::GetTextBox()
// but this function uses integers
// So, to avoid truncations with our unit in mm, use microns.
VECTOR2I size_micron;
#define FSCALE 1000.0
int linewidth = 0;
size_micron.x = KiROUND( m_ConstrainedTextSize.x * FSCALE );
size_micron.y = KiROUND( m_ConstrainedTextSize.y * FSCALE );
DS_DRAW_ITEM_TEXT dummy( unityScale, this, 0, m_FullText, VECTOR2I( 0, 0 ), size_micron,
linewidth, m_Font, m_Italic, m_Bold, m_TextColor );
dummy.SetMultilineAllowed( true );
dummy.SetHorizJustify( m_Hjustify ) ;
dummy.SetVertJustify( m_Vjustify );
dummy.SetTextAngle( EDA_ANGLE( m_Orient, DEGREES_T ) );
BOX2I rect = dummy.GetTextBox();
VECTOR2D size;
size.x = KiROUND( (int) rect.GetWidth() / FSCALE );
size.y = KiROUND( (int) rect.GetHeight() / FSCALE );
if( m_BoundingBoxSize.x > 0 && size.x > m_BoundingBoxSize.x )
m_ConstrainedTextSize.x *= m_BoundingBoxSize.x / size.x;
if( m_BoundingBoxSize.y > 0 && size.y > m_BoundingBoxSize.y )
m_ConstrainedTextSize.y *= m_BoundingBoxSize.y / size.y;
}
}
+2 -2
View File
@@ -1991,13 +1991,13 @@ static struct EDA_SHAPE_DESC
.SetAvailableFunc( isNotPolygonOrCircle );
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, int>( _HKI( "Center X" ),
&EDA_SHAPE::SetStartX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_COORD,
&EDA_SHAPE::SetCenterX, &EDA_SHAPE::GetStartX, PROPERTY_DISPLAY::PT_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,
&EDA_SHAPE::SetCenterY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD,
ORIGIN_TRANSFORMS::ABS_Y_COORD ),
shapeProps )
.SetAvailableFunc( isCircle );
+5 -1
View File
@@ -528,10 +528,13 @@ EDA_TEXT::GetRenderCache( const KIFONT::FONT* aFont, const wxString& forResolved
}
void EDA_TEXT::SetupRenderCache( const wxString& aResolvedText, const EDA_ANGLE& aAngle )
void EDA_TEXT::SetupRenderCache( const wxString& aResolvedText, const KIFONT::FONT* aFont,
const EDA_ANGLE& aAngle, const VECTOR2I& aOffset )
{
m_render_cache_text = aResolvedText;
m_render_cache_font = aFont;
m_render_cache_angle = aAngle;
m_render_cache_offset = aOffset;
m_render_cache.clear();
}
@@ -539,6 +542,7 @@ void EDA_TEXT::SetupRenderCache( const wxString& aResolvedText, const EDA_ANGLE&
void EDA_TEXT::AddRenderCacheGlyph( const SHAPE_POLY_SET& aPoly )
{
m_render_cache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( aPoly ) );
static_cast<KIFONT::OUTLINE_GLYPH*>( m_render_cache.back().get() )->CacheTriangulation();
}
+4 -2
View File
@@ -259,6 +259,7 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphs( BOX2I* aBBox, std::vector<std::unique_pt
struct GLYPH_CACHE_KEY {
FT_Face face;
hb_codepoint_t codepoint;
double scaler;
bool fakeItalic;
bool fakeBold;
bool mirror;
@@ -266,7 +267,7 @@ struct GLYPH_CACHE_KEY {
bool operator==(const GLYPH_CACHE_KEY& rhs ) const
{
return face == rhs.face && codepoint == rhs.codepoint
return face == rhs.face && codepoint == rhs.codepoint && scaler == rhs.scaler
&& fakeItalic == rhs.fakeItalic && fakeBold == rhs.fakeBold
&& mirror == rhs.mirror && angle == rhs.angle;
}
@@ -280,6 +281,7 @@ namespace std
std::size_t operator()( const GLYPH_CACHE_KEY& k ) const
{
return hash<const void*>()( k.face ) ^ hash<unsigned>()( k.codepoint )
^ hash<double>()( k.scaler )
^ hash<int>()( k.fakeItalic ) ^ hash<int>()( k.fakeBold )
^ hash<int>()( k.mirror ) ^ hash<int>()( k.angle.AsTenthsOfADegree() );
}
@@ -339,7 +341,7 @@ VECTOR2I OUTLINE_FONT::getTextAsGlyphsUnlocked( BOX2I* aBBox,
if( aGlyphs )
{
GLYPH_CACHE_KEY key = { face, glyphInfo[i].codepoint, m_fakeItal, m_fakeBold,
GLYPH_CACHE_KEY key = { face, glyphInfo[i].codepoint, scaler, m_fakeItal, m_fakeBold,
aMirror, aAngle };
GLYPH_DATA& glyphData = s_glyphCache[ key ];
+5 -1
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
* Copyright (C) 2012-2023 Kicad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2012-2024 Kicad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013-2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@@ -33,6 +33,7 @@
#endif
#include <advanced_config.h>
#include <build_version.h>
#include <gal/opengl/opengl_gal.h>
#include <gal/opengl/utils.h>
#include <gal/definitions.h>
@@ -2678,6 +2679,9 @@ void OPENGL_GAL::init()
#endif // KICAD_USE_EGL
SetOpenGLInfo( (const char*) glGetString( GL_VENDOR ), (const char*) glGetString( GL_RENDERER ),
(const char*) glGetString( GL_VERSION ) );
if( GLEW_OK != err )
throw std::runtime_error( (const char*) glewGetErrorString( err ) );
+2 -2
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Alex Shvartzkop <dudesuchamazing@gmail.com>
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2023-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
@@ -246,7 +246,7 @@ EASYEDA_PARSER_BASE::ParseLineChains( const wxString& data, int aArcMinSegLen, b
arc.ConstructFromStartEndCenter( RelPos( start ), RelPos( end ), RelPos( arcCenter ),
!cw );
chain.Append( arc );
chain.Append( arc, aArcMinSegLen );
prevPt = end;
}
+11 -1
View File
@@ -24,6 +24,7 @@
*/
#include <wx/debug.h>
#include <wx/filename.h>
#include <set>
#include <common.h>
@@ -198,7 +199,16 @@ LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName, bool aCheckIfEnabl
do
{
std::shared_lock<std::shared_mutex> lock( cur->m_mutex );
try
{
std::shared_lock<std::shared_mutex> lock( cur->m_mutex );
}
catch( std::system_error& e )
{
wxASSERT_MSG( false, wxString::Format( wxS( "Failed to lock lib table mutex: %s" ),
e.what() ) );
continue;
}
if( cur->m_rowsMap.count( aNickName ) )
row = &*cur->m_rowsMap.at( aNickName );
+3 -4
View File
@@ -153,6 +153,9 @@ PGM_BASE::~PGM_BASE()
}
delete[] m_argvUtf8;
delete m_locale;
m_locale = nullptr;
}
@@ -164,10 +167,6 @@ void PGM_BASE::Destroy()
sentry_close();
#endif
// unlike a normal destructor, this is designed to be called more than once safely:
delete m_locale;
m_locale = nullptr;
m_pgm_checker.reset();
}
+3
View File
@@ -160,6 +160,9 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
m_params.emplace_back( new PARAM<int>( "system.last_imperial_units",
&m_System.last_imperial_units, static_cast<int>( EDA_UNITS::MILS ) ) );
m_params.emplace_back( new PARAM<bool>( "system.show_import_issues",
&m_System.show_import_issues, true ) );
m_params.emplace_back( new PARAM<wxString>( "appearance.color_theme",
&m_ColorTheme, COLOR_SETTINGS::COLOR_BUILTIN_DEFAULT ) );
+1 -1
View File
@@ -36,7 +36,7 @@ const wxString COLOR_SETTINGS::COLOR_BUILTIN_CLASSIC = "_builtin_classic";
COLOR_SETTINGS::COLOR_SETTINGS( const wxString& aFilename, bool aAbsolutePath ) :
JSON_SETTINGS( std::move( aFilename ), SETTINGS_LOC::COLORS, colorsSchemaVersion ),
JSON_SETTINGS( aFilename, SETTINGS_LOC::COLORS, colorsSchemaVersion ),
m_overrideSchItemColors( false )
{
if( aAbsolutePath )
+4 -1
View File
@@ -455,8 +455,11 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
if( isMouseClick( type ) )
{
if( m_toolMgr->GetToolHolder() && m_toolMgr->GetToolHolder()->GetToolCanvas() )
if( m_toolMgr->GetToolHolder() && m_toolMgr->GetToolHolder()->GetToolCanvas() &&
!m_toolMgr->GetToolHolder()->GetToolCanvas()->HasFocus() )
{
m_toolMgr->GetToolHolder()->GetToolCanvas()->SetFocus();
}
}
// Mouse handling
+5 -1
View File
@@ -362,7 +362,11 @@ bool TOOL_MANAGER::doRunAction( const TOOL_ACTION& aAction, bool aNow, const std
while( synchronousControl == STS_RUNNING )
{
wxYield();
wxYield(); // Needed to honor mouse (and other) events during editing
wxMilliSleep( 1 ); // Needed to avoid 100% use of one cpu core.
// The sleeping time must be must be small to avoid
// noticeable lag in mouse and editing events
// (1 to 5 ms is a good value)
}
retVal = synchronousControl != STS_CANCELLED;
+6 -2
View File
@@ -45,7 +45,7 @@
#include <wx/log.h>
#ifdef __WXMSW__
#define USE_MOUSE_CAPTURE
#define USE_MOUSE_CAPTURE
#endif
using namespace KIGFX;
@@ -694,7 +694,11 @@ void WX_VIEW_CONTROLS::CaptureCursor( bool aEnabled )
// Note: for some reason, m_parentPanel->HasCapture() can be false even if CaptureMouse()
// was called (i.e. mouse was captured, so when need to test m_MouseCapturedLost to be
// sure a wxEVT_MOUSE_CAPTURE_LOST event was fired before. Otherwise wxMSW complains
if( aEnabled && !m_parentPanel->HasCapture() && m_parentPanel->m_MouseCapturedLost )
// The IsModalDialogFocused is checked because it's possible to start a capture
// due to event ordering while a modal dialog was just opened, the mouse capture steels focus
// from the modal and causes odd behavior
if( aEnabled && !m_parentPanel->HasCapture() && m_parentPanel->m_MouseCapturedLost
&& !KIUI::IsModalDialogFocused() )
{
m_parentPanel->CaptureMouse();
+23 -13
View File
@@ -213,13 +213,15 @@ protected:
if( rawValue.IsEmpty() )
rawValue = m_preselect;
wxString symbolId = escapeLibId( rawValue );
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_SYMBOL_CHOOSER, true, m_dlg );
wxString symbolId = escapeLibId( rawValue );
if( frame->ShowModal( &symbolId, m_dlg ) )
SetValue( UnescapeString( symbolId ) );
if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_SYMBOL_CHOOSER, true, m_dlg ) )
{
if( frame->ShowModal( &symbolId, m_dlg ) )
SetValue( UnescapeString( symbolId ) );
frame->Destroy();
frame->Destroy();
}
}
DIALOG_SHIM* m_dlg;
@@ -267,18 +269,26 @@ protected:
if( fpid.IsEmpty() )
fpid = m_preselect;
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg );
// Disable the button until we have finished processing it. Normally this is not an issue
// but if the footprint chooser is loading for the first time, it can be slow enough that
// multiple clicks will cause multiple instances of the footprint loader process to start
Disable();
if( !m_symbolNetlist.empty() )
if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg ) )
{
KIWAY_EXPRESS event( FRAME_FOOTPRINT_CHOOSER, MAIL_SYMBOL_NETLIST, m_symbolNetlist );
frame->KiwayMailIn( event );
if( !m_symbolNetlist.empty() )
{
KIWAY_EXPRESS event( FRAME_FOOTPRINT_CHOOSER, MAIL_SYMBOL_NETLIST, m_symbolNetlist );
frame->KiwayMailIn( event );
}
if( frame->ShowModal( &fpid, m_dlg ) )
SetValue( fpid );
frame->Destroy();
}
if( frame->ShowModal( &fpid, m_dlg ) )
SetValue( fpid );
frame->Destroy();
Enable();
}
protected:
-12
View File
@@ -725,18 +725,6 @@ void LIB_TREE::onIdle( wxIdleEvent& aEvent )
if( m_previewItem.IsOk() )
{
// Scroll checker
if( m_tree_ctrl->GetItemRect( m_previewItem ) != m_previewItemRect )
{
hidePreview();
m_hoverPos = clientPos;
m_hoverItem = item;
m_hoverItemRect = m_tree_ctrl->GetItemRect( m_hoverItem );
m_hoverTimer.StartOnce( HOVER_TIMER_MILLIS );
return;
}
if( item != m_previewItem )
{
#ifdef __WXGTK__
+6 -1
View File
@@ -406,14 +406,19 @@ void PROPERTIES_PANEL::onShow( wxShowEvent& aEvent )
{
if( aEvent.IsShown() )
UpdateData();
aEvent.Skip();
}
void PROPERTIES_PANEL::onCharHook( wxKeyEvent& aEvent )
{
if( aEvent.GetKeyCode() == WXK_TAB && !aEvent.ShiftDown() )
if( aEvent.GetKeyCode() == WXK_TAB && !aEvent.ShiftDown() && m_grid->IsAnyModified() )
{
m_grid->CommitChangesFromEditor();
// Pass the tab key on so the default property grid tab behavior is honored.
aEvent.Skip();
return;
}
+2 -2
View File
@@ -87,8 +87,8 @@ protected:
virtual wxPGProperty* createPGProperty( const PROPERTY_BASE* aProperty ) const = 0;
// Event handlers
virtual void valueChanging( wxPropertyGridEvent& aEvent ) {}
virtual void valueChanged( wxPropertyGridEvent& aEvent ) {}
virtual void valueChanging( wxPropertyGridEvent& aEvent ) { aEvent.Skip(); }
virtual void valueChanged( wxPropertyGridEvent& aEvent ) { aEvent.Skip(); }
void onCharHook( wxKeyEvent& aEvent );
void onShow( wxShowEvent& aEvent );
+13 -2
View File
@@ -991,8 +991,19 @@ void CVPCB_MAINFRAME::BuildLibrariesList()
COMMON_SETTINGS* cfg = Pgm().GetCommonSettings();
PROJECT_FILE& project = Kiway().Prj().GetProjectFile();
FP_LIB_TABLE* tbl = PROJECT_PCB::PcbFootprintLibs( &Prj() );
std::set<wxString> pinnedMatches;
std::set<wxString> otherMatches;
// Use same sorting algorithm as LIB_TREE_NODE::AssignIntrinsicRanks
struct library_sort
{
bool operator()( const wxString& lhs, const wxString& rhs ) const
{
return StrNumCmp( lhs, rhs, true ) < 0;
}
};
std::set<wxString, library_sort> pinnedMatches;
std::set<wxString, library_sort> otherMatches;
m_librariesListBox->ClearList();
auto process =
+3 -3
View File
@@ -176,11 +176,11 @@ int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
fpframe = (DISPLAY_FOOTPRINTS_FRAME*) m_frame->Kiway().Player( FRAME_CVPCB_DISPLAY, true,
m_frame );
// If Kiway() cannot create the eeschema frame, it shows a error message, and
// frame is null
if( !fpframe )
{
wxMessageBox( _( "Unable to create the footprint viewer frame" ) );
return 0;
}
fpframe->Show( true );
}
+1
View File
@@ -397,6 +397,7 @@ set( EESCHEMA_SRCS
symbol_tree_model_adapter.cpp
symbol_tree_synchronizing_adapter.cpp
symbol_viewer_frame.cpp
symb_transforms_utils.cpp
toolbars_sch_editor.cpp
toolbars_symbol_viewer.cpp
+16 -14
View File
@@ -248,15 +248,16 @@ void DIALOG_CHANGE_SYMBOLS::launchMatchIdSymbolBrowser( wxCommandEvent& aEvent )
{
wxString newName = getLibIdValue( m_specifiedId );
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SYMBOL_CHOOSER, true, this );
if( frame->ShowModal( &newName, this ) )
if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_SYMBOL_CHOOSER, true, this ) )
{
m_specifiedId->SetValue( UnescapeString( newName ) );
updateFieldsList();
}
if( frame->ShowModal( &newName, this ) )
{
m_specifiedId->SetValue( UnescapeString( newName ) );
updateFieldsList();
}
frame->Destroy();
frame->Destroy();
}
}
@@ -264,15 +265,16 @@ void DIALOG_CHANGE_SYMBOLS::launchNewIdSymbolBrowser( wxCommandEvent& aEvent )
{
wxString newName = getLibIdValue( m_newId );
KIWAY_PLAYER* frame = Kiway().Player( FRAME_SYMBOL_CHOOSER, true, this );
if( frame->ShowModal( &newName, this ) )
if( KIWAY_PLAYER* frame = Kiway().Player( FRAME_SYMBOL_CHOOSER, true, this ) )
{
m_newId->SetValue( UnescapeString( newName ) );
updateFieldsList();
}
if( frame->ShowModal( &newName, this ) )
{
m_newId->SetValue( UnescapeString( newName ) );
updateFieldsList();
}
frame->Destroy();
frame->Destroy();
}
}
+3
View File
@@ -79,6 +79,7 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
m_currentSchematic = &parent->Schematic();
SetName( DIALOG_ERC_WINDOW_NAME ); // Set a window name to be able to find it
KIPLATFORM::UI::SetFloatLevel( this );
EESCHEMA_SETTINGS* settings = dynamic_cast<EESCHEMA_SETTINGS*>( Kiface().KifaceSettings() );
m_severities = settings->m_Appearance.erc_severities;
@@ -466,6 +467,8 @@ void DIALOG_ERC::OnRunERCClick( wxCommandEvent& event )
m_ercRun = true;
redrawDrawPanel();
updateDisplayedCounts();
// set float level again, it can be lost due to window events during test run
KIPLATFORM::UI::SetFloatLevel( this );
}
+3 -3
View File
@@ -501,7 +501,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
if( m_sheet->GetScreen() == nullptr ) // New just created sheet.
{
if( !m_frame->AllowCaseSensitiveFileNameClashes( newAbsoluteFilename ) )
if( !m_frame->AllowCaseSensitiveFileNameClashes( m_sheet->GetFileName(), newAbsoluteFilename ) )
return false;
if( useScreen || loadFromFile ) // Load from existing file.
@@ -526,7 +526,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
{
isExistingSheet = true;
if( !m_frame->AllowCaseSensitiveFileNameClashes( newAbsoluteFilename ) )
if( !m_frame->AllowCaseSensitiveFileNameClashes( m_sheet->GetFileName(), newAbsoluteFilename ) )
return false;
// We are always using here a case insensitive comparison to avoid issues
@@ -640,7 +640,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
SCH_SHEET_LIST sheetHierarchy( m_sheet ); // The hierarchy of the loaded file.
sheetHierarchy.AddNewSymbolInstances( currentSheet );
sheetHierarchy.AddNewSymbolInstances( currentSheet, m_frame->Prj().GetProjectName() );
sheetHierarchy.AddNewSheetInstances( currentSheet,
fullHierarchy.GetLastVirtualPageNumber() );
}
@@ -109,14 +109,15 @@ protected:
if( event.GetId() == MYID_SELECT_FOOTPRINT )
{
// pick a footprint using the footprint picker.
wxString fpid = m_grid->GetCellValue( m_grid->GetGridCursorRow(),
FOOTPRINT_FIELD );
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg );
wxString fpid = m_grid->GetCellValue( m_grid->GetGridCursorRow(), FOOTPRINT_FIELD );
if( frame->ShowModal( &fpid, m_dlg ) )
m_grid->SetCellValue( m_grid->GetGridCursorRow(), FOOTPRINT_FIELD, fpid );
if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg ) )
{
if( frame->ShowModal( &fpid, m_dlg ) )
m_grid->SetCellValue( m_grid->GetGridCursorRow(), FOOTPRINT_FIELD, fpid );
frame->Destroy();
frame->Destroy();
}
}
else if (event.GetId() == MYID_SHOW_DATASHEET )
{
@@ -305,7 +306,7 @@ DIALOG_SYMBOL_FIELDS_TABLE::DIALOG_SYMBOL_FIELDS_TABLE( SCH_EDIT_FRAME* parent )
case SCOPE::SCOPE_SHEET_RECURSIVE: m_radioRecursive->SetValue( true ); break;
}
m_outputFileName->SetValue( cfg->m_FieldEditorPanel.export_filename );
m_outputFileName->SetValue( m_schSettings.m_BomExportFileName );
Center();
@@ -1338,12 +1339,13 @@ void DIALOG_SYMBOL_FIELDS_TABLE::OnClose( wxCloseEvent& aEvent )
// Save all our settings since we're really closing
savePresetsToSchematic();
m_schSettings.m_BomExportFileName = m_outputFileName->GetValue();
EESCHEMA_SETTINGS* cfg = m_parent->eeconfig();
cfg->m_FieldEditorPanel.width = GetSize().x;
cfg->m_FieldEditorPanel.height = GetSize().y;
cfg->m_FieldEditorPanel.page = m_nbPages->GetSelection();
cfg->m_FieldEditorPanel.export_filename = m_outputFileName->GetValue();
if( m_radioHighlight->GetValue() )
cfg->m_FieldEditorPanel.selection_mode = 0;
+1
View File
@@ -102,6 +102,7 @@ void SCH_EDIT_FRAME::ShowSchematicSetupDialog( const wxString& aInitialPage )
Prj().IncrementTextVarsTicker();
Prj().IncrementNetclassesTicker();
Pgm().GetSettingsManager().SaveProject();
GetRenderSettings()->SetDefaultPenWidth( Schematic().Settings().m_DefaultLineWidth );
GetRenderSettings()->m_LabelSizeRatio = Schematic().Settings().m_LabelSizeRatio;
+2 -2
View File
@@ -740,7 +740,7 @@ int EESCHEMA_JOBS_HANDLER::doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob,
}
// Get the symbol bounding box to fit the plot page to it
BOX2I symbolBB = symbol->Flatten()->GetUnitBoundingBox( unit, bodyStyle, false );
BOX2I symbolBB = symbol->Flatten()->GetUnitBoundingBox( unit, bodyStyle, !aSvgJob->m_includeHiddenFields );
PAGE_INFO pageInfo( PAGE_INFO::Custom );
pageInfo.SetHeightMils( schIUScale.IUToMils( symbolBB.GetHeight() * 1.2 ) );
pageInfo.SetWidthMils( schIUScale.IUToMils( symbolBB.GetWidth() * 1.2 ) );
@@ -750,7 +750,7 @@ int EESCHEMA_JOBS_HANDLER::doSymExportSvg( JOB_SYM_EXPORT_SVG* aSvgJob,
plotter->SetPageSettings( pageInfo );
plotter->SetColorMode( !aSvgJob->m_blackAndWhite );
VECTOR2I plot_offset;
VECTOR2I plot_offset = symbolBB.GetCenter();
const double scale = 1.0;
// Currently, plot units are in decimal
+7 -5
View File
@@ -946,13 +946,15 @@ void FIELDS_GRID_TRICKS::doPopupSelection( wxCommandEvent& event )
if( event.GetId() == MYID_SELECT_FOOTPRINT )
{
// pick a footprint using the footprint picker.
wxString fpid = m_grid->GetCellValue( FOOTPRINT_FIELD, FDC_VALUE );
KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg );
wxString fpid = m_grid->GetCellValue( FOOTPRINT_FIELD, FDC_VALUE );
if( frame->ShowModal( &fpid, m_dlg ) )
m_grid->SetCellValue( FOOTPRINT_FIELD, FDC_VALUE, fpid );
if( KIWAY_PLAYER* frame = m_dlg->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_dlg ) )
{
if( frame->ShowModal( &fpid, m_dlg ) )
m_grid->SetCellValue( FOOTPRINT_FIELD, FDC_VALUE, fpid );
frame->Destroy();
frame->Destroy();
}
}
else if (event.GetId() == MYID_SHOW_DATASHEET )
{
+13 -2
View File
@@ -61,6 +61,7 @@
#include <tools/sch_editor_control.h>
#include <tools/sch_navigate_tool.h>
#include <trace_helpers.h>
#include <widgets/filedlg_import_non_kicad.h>
#include <widgets/wx_infobar.h>
#include <wildcards_and_files_ext.h>
#include <drawing_sheet/ds_data_model.h>
@@ -730,9 +731,14 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
wxFileDialog dlg( this, _( "Import Schematic" ), path, wxEmptyString, fileFiltersStr,
wxFD_OPEN | wxFD_FILE_MUST_EXIST ); // TODO
FILEDLG_IMPORT_NON_KICAD importOptions( eeconfig()->m_System.show_import_issues );
dlg.SetCustomizeHook( importOptions );
if( dlg.ShowModal() == wxID_CANCEL )
return;
eeconfig()->m_System.show_import_issues = importOptions.GetShowIssues();
// Don't leave dangling pointers to previously-opened document.
m_toolManager->GetTool<EE_SELECTION_TOOL>()->ClearSelection();
ClearUndoRedoList();
@@ -1383,7 +1389,11 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType,
std::placeholders::_1 ) );
}
pi->SetReporter( errorReporter.m_Reporter );
if( eeconfig()->m_System.show_import_issues )
pi->SetReporter( errorReporter.m_Reporter );
else
pi->SetReporter( &NULL_REPORTER::GetInstance() );
pi->SetProgressReporter( &progressReporter );
SCH_SHEET* loadedSheet =
@@ -1650,7 +1660,8 @@ void SCH_EDIT_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
}
// Attempt to back up the last schematic file before overwriting it with the auto
// save file.
else if( !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
else if( recoveredFn.Exists()
&& !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
{
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
}
+5
View File
@@ -664,6 +664,11 @@ static struct LIB_FIELD_DESC
propMgr.Mask( TYPE_HASH( LIB_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
propMgr.Mask( TYPE_HASH( LIB_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
propMgr.AddProperty( new PROPERTY<LIB_FIELD, int>(
_HKI( "Text Size" ), &LIB_FIELD::SetLibTextSize,
&LIB_FIELD::GetLibTextSize, PROPERTY_DISPLAY::PT_SIZE ),
_HKI( "Text Properties" ) );
propMgr.Mask( TYPE_HASH( LIB_FIELD ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
}
} _LIB_FIELD_DESC;
+3
View File
@@ -161,6 +161,9 @@ public:
wxString GetShownText( bool aAllowExtraText, int aDepth = 0 ) const override;
int GetLibTextSize() const { return GetTextWidth(); }
void SetLibTextSize( int aSize ) { SetTextSize( VECTOR2I( aSize, aSize ) ); }
SCH_LAYER_ID GetDefaultLayer() const;
void BeginEdit( const VECTOR2I& aStartPoint ) override;
+1
View File
@@ -159,6 +159,7 @@ public:
virtual void SetName( const wxString& aName );
wxString GetName() const override { return m_name; }
const LIB_ID& LibId() const { return m_libId; }
LIB_ID& LibId() { return m_libId; }
LIB_ID GetLibId() const override { return m_libId; }
void SetLibId( const LIB_ID& aLibId ) { m_libId = aLibId; }
@@ -479,7 +479,8 @@ void NETLIST_EXPORTER_SPICE::readModel( SCH_SHEET_PATH& aSheet, SCH_SYMBOL& aSym
auto spiceGenerator = static_cast<const SPICE_GENERATOR_KIBIS&>( kibisModel->SpiceGenerator() );
std::string modelData = spiceGenerator.IbisDevice(
aItem, m_schematic->Prj(), cacheFn.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR ) );
aItem, m_schematic->Prj(),
cacheFn.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR ), aReporter );
cacheFile.Write( wxString( modelData ) );
m_rawIncludes.insert( cacheFn.GetFullPath() );
+89 -82
View File
@@ -23,7 +23,6 @@
#include <bitmaps.h>
#include <cstddef>
#include <core/arraydim.h>
#include <magic_enum.hpp>
#include <lib_pin.h>
#include "pgm_base.h"
@@ -47,56 +46,18 @@ struct pinTypeStruct
BITMAPS bitmap;
};
std::map<ELECTRICAL_PINTYPE, struct pinTypeStruct> g_pinTypes = {
{ ELECTRICAL_PINTYPE::PT_INPUT, { _( "Input" ), BITMAPS::pintype_input } },
{ ELECTRICAL_PINTYPE::PT_OUTPUT, { _( "Output" ), BITMAPS::pintype_output } },
{ ELECTRICAL_PINTYPE::PT_BIDI, { _( "Bidirectional" ), BITMAPS::pintype_bidi } },
{ ELECTRICAL_PINTYPE::PT_TRISTATE, { _( "Tri-state" ), BITMAPS::pintype_3states } },
{ ELECTRICAL_PINTYPE::PT_PASSIVE, { _( "Passive" ), BITMAPS::pintype_passive } },
{ ELECTRICAL_PINTYPE::PT_NIC, { _( "Free" ), BITMAPS::pintype_nic } },
{ ELECTRICAL_PINTYPE::PT_UNSPECIFIED, { _( "Unspecified" ), BITMAPS::pintype_notspecif } },
{ ELECTRICAL_PINTYPE::PT_POWER_IN, { _( "Power input" ), BITMAPS::pintype_powerinput } },
{ ELECTRICAL_PINTYPE::PT_POWER_OUT, { _( "Power output" ), BITMAPS::pintype_poweroutput } },
{ ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR,{ _( "Open collector" ), BITMAPS::pintype_opencoll } },
{ ELECTRICAL_PINTYPE::PT_OPENEMITTER, { _( "Open emitter" ), BITMAPS::pintype_openemit } },
{ ELECTRICAL_PINTYPE::PT_NC, { _( "Unconnected" ), BITMAPS::pintype_noconnect } },
};
int g_pinTypesLanguage = wxLANGUAGE_UNKNOWN;
struct pinShapeStruct
{
wxString name;
BITMAPS bitmap;
};
// clang-format off
const std::map<GRAPHIC_PINSHAPE, struct pinShapeStruct> pinShapes = {
{ GRAPHIC_PINSHAPE::LINE, { _( "Line" ), BITMAPS::pinshape_normal } },
{ GRAPHIC_PINSHAPE::INVERTED, { _( "Inverted" ), BITMAPS::pinshape_invert } },
{ GRAPHIC_PINSHAPE::CLOCK, { _( "Clock" ), BITMAPS::pinshape_clock_normal } },
{ GRAPHIC_PINSHAPE::INVERTED_CLOCK, { _( "Inverted clock" ), BITMAPS::pinshape_clock_invert } },
{ GRAPHIC_PINSHAPE::INPUT_LOW, { _( "Input low" ), BITMAPS::pinshape_active_low_input } },
{ GRAPHIC_PINSHAPE::CLOCK_LOW, { _( "Clock low" ), BITMAPS::pinshape_clock_active_low } },
{ GRAPHIC_PINSHAPE::OUTPUT_LOW, { _( "Output low" ), BITMAPS::pinshape_active_low_output } },
{ GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK, { _( "Falling edge clock" ), BITMAPS::pinshape_clock_fall } },
{ GRAPHIC_PINSHAPE::NONLOGIC, { _( "NonLogic" ), BITMAPS::pinshape_nonlogic } },
};
// clang-format on
static std::map<ELECTRICAL_PINTYPE, struct pinTypeStruct> g_pinElectricalTypes;
static std::map<GRAPHIC_PINSHAPE, struct pinShapeStruct> g_pinShapes;
static std::map<PIN_ORIENTATION, struct pinShapeStruct> g_pinOrientations;
// clang-format off
std::map<PIN_ORIENTATION, struct pinShapeStruct> pinOrientations = {
{ PIN_ORIENTATION::PIN_RIGHT, { _( "Right" ), BITMAPS::pinorient_right } },
{ PIN_ORIENTATION::PIN_LEFT, { _( "Left" ), BITMAPS::pinorient_left } },
{ PIN_ORIENTATION::PIN_UP, { _( "Up" ), BITMAPS::pinorient_up } },
{ PIN_ORIENTATION::PIN_DOWN, { _( "Down" ), BITMAPS::pinorient_down } },
};
// clang-format on
static int g_language = wxLANGUAGE_UNKNOWN;
PIN_ORIENTATION PinOrientationCode( size_t index )
@@ -119,18 +80,65 @@ int PinOrientationIndex( PIN_ORIENTATION code )
void InitTables()
{
// clang-format off
g_pinElectricalTypes = {
{ ELECTRICAL_PINTYPE::PT_INPUT, { _( "Input" ), BITMAPS::pintype_input } },
{ ELECTRICAL_PINTYPE::PT_OUTPUT, { _( "Output" ), BITMAPS::pintype_output } },
{ ELECTRICAL_PINTYPE::PT_BIDI, { _( "Bidirectional" ), BITMAPS::pintype_bidi } },
{ ELECTRICAL_PINTYPE::PT_TRISTATE, { _( "Tri-state" ), BITMAPS::pintype_3states } },
{ ELECTRICAL_PINTYPE::PT_PASSIVE, { _( "Passive" ), BITMAPS::pintype_passive } },
{ ELECTRICAL_PINTYPE::PT_NIC, { _( "Free" ), BITMAPS::pintype_nic } },
{ ELECTRICAL_PINTYPE::PT_UNSPECIFIED, { _( "Unspecified" ), BITMAPS::pintype_notspecif } },
{ ELECTRICAL_PINTYPE::PT_POWER_IN, { _( "Power input" ), BITMAPS::pintype_powerinput } },
{ ELECTRICAL_PINTYPE::PT_POWER_OUT, { _( "Power output" ), BITMAPS::pintype_poweroutput } },
{ ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR, { _( "Open collector" ), BITMAPS::pintype_opencoll } },
{ ELECTRICAL_PINTYPE::PT_OPENEMITTER, { _( "Open emitter" ), BITMAPS::pintype_openemit } },
{ ELECTRICAL_PINTYPE::PT_NC, { _( "Unconnected" ), BITMAPS::pintype_noconnect } },
};
g_pinShapes = {
{ GRAPHIC_PINSHAPE::LINE, { _( "Line" ), BITMAPS::pinshape_normal } },
{ GRAPHIC_PINSHAPE::INVERTED, { _( "Inverted" ), BITMAPS::pinshape_invert } },
{ GRAPHIC_PINSHAPE::CLOCK, { _( "Clock" ), BITMAPS::pinshape_clock_normal } },
{ GRAPHIC_PINSHAPE::INVERTED_CLOCK, { _( "Inverted clock" ), BITMAPS::pinshape_clock_invert } },
{ GRAPHIC_PINSHAPE::INPUT_LOW, { _( "Input low" ), BITMAPS::pinshape_active_low_input } },
{ GRAPHIC_PINSHAPE::CLOCK_LOW, { _( "Clock low" ), BITMAPS::pinshape_clock_active_low } },
{ GRAPHIC_PINSHAPE::OUTPUT_LOW, { _( "Output low" ), BITMAPS::pinshape_active_low_output } },
{ GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK, { _( "Falling edge clock" ), BITMAPS::pinshape_clock_fall } },
{ GRAPHIC_PINSHAPE::NONLOGIC, { _( "NonLogic" ), BITMAPS::pinshape_nonlogic } },
};
g_pinOrientations = {
{ PIN_ORIENTATION::PIN_RIGHT, { _( "Right" ), BITMAPS::pinorient_right } },
{ PIN_ORIENTATION::PIN_LEFT, { _( "Left" ), BITMAPS::pinorient_left } },
{ PIN_ORIENTATION::PIN_UP, { _( "Up" ), BITMAPS::pinorient_up } },
{ PIN_ORIENTATION::PIN_DOWN, { _( "Down" ), BITMAPS::pinorient_down } },
};
// clang-format on
g_language = Pgm().GetSelectedLanguageIdentifier();
g_typeIcons.clear();
g_typeNames.clear();
for( unsigned i = 0; i < ELECTRICAL_PINTYPES_TOTAL; ++i )
{
g_typeIcons.push_back( ElectricalPinTypeGetBitmap( static_cast<ELECTRICAL_PINTYPE>( i ) ) );
g_typeNames.push_back( ElectricalPinTypeGetText( static_cast<ELECTRICAL_PINTYPE>( i ) ) );
}
g_shapeIcons.clear();
g_shapeNames.clear();
for( unsigned i = 0; i < GRAPHIC_PINSHAPES_TOTAL; ++i )
{
g_shapeIcons.push_back( PinShapeGetBitmap( static_cast<GRAPHIC_PINSHAPE>( i ) ) );
g_shapeNames.push_back( PinShapeGetText( static_cast<GRAPHIC_PINSHAPE>( i ) ) );
}
g_orientationIcons.clear();
g_orientationNames.clear();
for( PIN_ORIENTATION orientation : magic_enum::enum_values<PIN_ORIENTATION>() )
{
g_orientationIcons.push_back( PinOrientationGetBitmap( orientation ) );
@@ -141,7 +149,7 @@ void InitTables()
const wxArrayString& PinTypeNames()
{
if( g_typeNames.empty() )
if( g_typeNames.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
InitTables();
return g_typeNames;
@@ -159,7 +167,7 @@ const std::vector<BITMAPS>& PinTypeIcons()
const wxArrayString& PinShapeNames()
{
if( g_shapeNames.empty() )
if( g_shapeNames.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
InitTables();
return g_shapeNames;
@@ -177,7 +185,7 @@ const std::vector<BITMAPS>& PinShapeIcons()
const wxArrayString& PinOrientationNames()
{
if( g_orientationNames.empty() )
if( g_orientationNames.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
InitTables();
return g_orientationNames;
@@ -195,78 +203,77 @@ const std::vector<BITMAPS>& PinOrientationIcons()
wxString ElectricalPinTypeGetText( ELECTRICAL_PINTYPE aType )
{
if( g_pinTypesLanguage != Pgm().GetSelectedLanguageIdentifier() )
{
g_pinTypes[ELECTRICAL_PINTYPE::PT_INPUT].name = _( "Input" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_OUTPUT].name = _( "Output" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_BIDI].name = _( "Bidirectional" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_TRISTATE].name = _( "Tri-state" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_PASSIVE].name = _( "Passive" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_NIC].name = _( "Free" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_UNSPECIFIED].name = _( "Unspecified" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_POWER_IN].name = _( "Power input" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_POWER_OUT].name = _( "Power output" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR].name = _( "Open collector" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_OPENEMITTER].name = _( "Open emitter" );
g_pinTypes[ELECTRICAL_PINTYPE::PT_NC].name = _( "Unconnected" );
if( g_pinElectricalTypes.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
InitTables();
g_pinTypesLanguage = Pgm().GetSelectedLanguageIdentifier();
}
auto it = g_pinElectricalTypes.find( aType );
auto findIt = g_pinTypes.find( aType );
wxCHECK_MSG( it != g_pinElectricalTypes.end(), wxT( "???" ), wxT( "Pin type not found!" ) );
wxCHECK_MSG( findIt != g_pinTypes.end(), wxT( "???" ), wxT( "Pin type not found!" ) );
return findIt->second.name;
return it->second.name;
}
BITMAPS ElectricalPinTypeGetBitmap( ELECTRICAL_PINTYPE aType )
{
auto findIt = g_pinTypes.find( aType );
if( g_pinElectricalTypes.empty() )
InitTables();
wxCHECK_MSG( findIt != g_pinTypes.end(), BITMAPS::INVALID_BITMAP, wxT( "Pin type not found!" ) );
auto it = g_pinElectricalTypes.find( aType );
return findIt->second.bitmap;
wxCHECK_MSG( it != g_pinElectricalTypes.end(), BITMAPS::INVALID_BITMAP, wxT( "Pin type not found!" ) );
return it->second.bitmap;
}
wxString PinShapeGetText( GRAPHIC_PINSHAPE aShape )
{
auto findIt = pinShapes.find( aShape );
if( g_pinShapes.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
InitTables();
wxCHECK_MSG( findIt != pinShapes.end(), wxT( "?" ), wxT( "Pin type not found!" ) );
auto it = g_pinShapes.find( aShape );
return findIt->second.name;
wxCHECK_MSG( it != g_pinShapes.end(), wxT( "?" ), wxT( "Pin type not found!" ) );
return it->second.name;
}
BITMAPS PinShapeGetBitmap( GRAPHIC_PINSHAPE aShape )
{
auto findIt = pinShapes.find( aShape );
if( g_pinShapes.empty() )
InitTables();
wxCHECK_MSG( findIt != pinShapes.end(), BITMAPS::INVALID_BITMAP, wxT( "Pin type not found!" ) );
auto it = g_pinShapes.find( aShape );
return findIt->second.bitmap;
wxCHECK_MSG( it != g_pinShapes.end(), BITMAPS::INVALID_BITMAP, wxT( "Pin type not found!" ) );
return it->second.bitmap;
}
wxString PinOrientationName( PIN_ORIENTATION aOrientation )
{
auto findIt = pinOrientations.find( aOrientation );
if( g_pinOrientations.empty() || g_language != Pgm().GetSelectedLanguageIdentifier() )
InitTables();
wxCHECK_MSG( findIt != pinOrientations.end(), wxT( "?" ), wxT( "Pin orientation not found!" ) );
auto it = g_pinOrientations.find( aOrientation );
return findIt->second.name;
wxCHECK_MSG( it != g_pinOrientations.end(), wxT( "?" ), wxT( "Pin orientation not found!" ) );
return it->second.name;
}
BITMAPS PinOrientationGetBitmap( PIN_ORIENTATION aOrientation )
{
auto findIt = pinOrientations.find( aOrientation );
if( g_pinOrientations.empty() )
InitTables();
wxCHECK_MSG( findIt != pinOrientations.end(), BITMAPS::INVALID_BITMAP,
wxT( "Pin orientation not found!" ) );
auto it = g_pinOrientations.find( aOrientation );
return findIt->second.bitmap;
wxCHECK_MSG( it != g_pinOrientations.end(), BITMAPS::INVALID_BITMAP, wxT( "Pin orientation not found!" ) );
return it->second.bitmap;
}
+12 -1
View File
@@ -209,9 +209,20 @@ void SCH_COMMIT::pushSchEdit( const wxString& aMessage, int aCommitFlags )
schematic = schItem->Schematic();
if( schItem->IsSelected() )
{
selectedModified = true;
}
else
{
schItem->RunOnChildren(
[&selectedModified]( SCH_ITEM* aChild )
{
if( aChild->IsSelected() )
selectedModified = true;
} );
}
auto updateConnectivityFlag = [&, this]()
auto updateConnectivityFlag = [&]()
{
if( schItem->IsConnectable() )
{
+1 -1
View File
@@ -545,7 +545,7 @@ public:
* @param aSchematicFileName is the absolute path and file name of the file to test.
* @return true if the user accepts the potential file name clash risk.
*/
bool AllowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName );
bool AllowCaseSensitiveFileNameClashes( const wxString& aOldName, const wxString& aSchematicFileName );
/**
* Edit an existing sheet or add a new sheet to the schematic.
+31 -14
View File
@@ -4396,20 +4396,40 @@ void SCH_IO_ALTIUM::ParseLibHeader( const ALTIUM_COMPOUND_FILE& aAltiumSchFile,
}
void SCH_IO_ALTIUM::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties )
void SCH_IO_ALTIUM::doEnumerateSymbolLib( const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties,
std::function<void(const wxString&, LIB_SYMBOL*)> aInserter )
{
ensureLoadedLibrary( aLibraryPath, aProperties );
bool powerSymbolsOnly = ( aProperties &&
aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly )
!= aProperties->end() );
auto it = m_libCache.find( aLibraryPath );
if( it != m_libCache.end() )
{
for( auto& [libnameStr, libSymbol] : it->second )
aSymbolNameList.Add( libnameStr );
}
{
if( powerSymbolsOnly && !libSymbol->IsPower() )
continue;
aInserter( libnameStr, libSymbol );
}
}
}
void SCH_IO_ALTIUM::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties )
{
doEnumerateSymbolLib( aLibraryPath, aProperties,
[&]( const wxString& aStr, LIB_SYMBOL* )
{
aSymbolNameList.Add( aStr );
} );
}
@@ -4417,17 +4437,14 @@ void SCH_IO_ALTIUM::EnumerateSymbolLib( std::vector<LIB_SYMBOL*>& aSymbolList,
const wxString& aLibraryPath,
const STRING_UTF8_MAP* aProperties )
{
ensureLoadedLibrary( aLibraryPath, aProperties );
auto it = m_libCache.find( aLibraryPath );
if( it != m_libCache.end() )
{
for( auto& [libnameStr, libSymbol] : it->second )
aSymbolList.push_back( libSymbol );
}
doEnumerateSymbolLib( aLibraryPath, aProperties,
[&]( const wxString&, LIB_SYMBOL* aSymbol )
{
aSymbolList.emplace_back( aSymbol );
} );
}
LIB_SYMBOL* SCH_IO_ALTIUM::LoadSymbol( const wxString& aLibraryPath,
const wxString& aAliasName,
const STRING_UTF8_MAP* aProperties )
+3
View File
@@ -178,6 +178,9 @@ private:
std::map<wxString,LIB_SYMBOL*> ParseLibFile( const ALTIUM_COMPOUND_FILE& aAltiumSchFile );
std::vector<LIB_SYMBOL*> ParseLibComponent( const std::map<wxString, wxString>& aProperties );
void doEnumerateSymbolLib( const wxString& aLibraryPath, const STRING_UTF8_MAP* aProperties,
std::function<void(const wxString&, LIB_SYMBOL*)> aInserter );
private:
SCH_SHEET* m_rootSheet; // The root sheet of the schematic being loaded..
SCH_SHEET_PATH m_sheetPath;
+2 -1
View File
@@ -1839,9 +1839,10 @@ void SCH_IO_EAGLE::loadInstance( wxXmlNode* aInstanceNode )
SCH_FIELD* valueField = symbol->GetField( VALUE_FIELD );
bool userValue = m_userValue.at( libIdSymbolName );
valueField->SetVisible( part->GetFieldById( VALUE_FIELD )->IsVisible() );
if( userValue && epart->value )
if( !userValue && epart->value )
{
valueField->SetText( *epart->value );
}
+97 -95
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Alex Shvartzkop <dudesuchamazing@gmail.com>
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2023-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
@@ -43,12 +43,27 @@
#include <wx/base64.h>
#include <wx/url.h>
#include <wx/mstream.h>
#include <core/map_helpers.h>
#include <gfx_import_utils.h>
#include <import_gfx/svg_import_plugin.h>
#include <import_gfx/graphics_importer_lib_symbol.h>
#include <import_gfx/graphics_importer_sch.h>
// clang-format off
static const std::vector<wxString> c_attributesWhitelist = { "Datasheet",
"Manufacturer Part",
"Manufacturer",
"BOM_Manufacturer Part",
"BOM_Manufacturer",
"Supplier Part",
"Supplier",
"BOM_Supplier Part",
"BOM_Supplier",
"LCSC Part Name" };
// clang-format on
SCH_EASYEDA_PARSER::SCH_EASYEDA_PARSER( SCHEMATIC* aSchematic,
PROGRESS_REPORTER* aProgressReporter )
{
@@ -561,97 +576,61 @@ void SCH_EASYEDA_PARSER::ParseSymbolShapes( LIB_SYMBOL* aSymbol
wxString fillColor = arr[6].Lower();
//bool locked = arr[8] != wxS( "0" );
VECTOR2D start, end;
VECTOR2D rad( 10, 10 );
bool isFar = false;
bool cw = false;
std::vector<SHAPE_LINE_CHAIN> chains =
ParseLineChains( data, schIUScale.MilsToIU( 10 ), false );
size_t pos = 0;
auto readNumber = [&]( wxString& aOut )
auto transform = []( VECTOR2I aVec )
{
wxUniChar ch = data[pos];
while( ch == ' ' || ch == ',' )
ch = data[++pos];
while( isdigit( ch ) || ch == '.' || ch == '-' )
{
aOut += ch;
pos++;
if( pos == data.size() )
break;
ch = data[pos];
}
return VECTOR2I( aVec.x, -aVec.y );
};
do
for( const SHAPE_LINE_CHAIN& chain : chains )
{
wxUniChar sym = data[pos++];
if( sym == 'M' )
for( int i = 0; i <= chain.PointCount() && i != -1; i = chain.NextShape( i ) )
{
wxString xStr, yStr;
readNumber( xStr );
readNumber( yStr );
if( chain.IsArcStart( i ) )
{
SHAPE_ARC arc = chain.Arc( chain.ArcIndex( i ) );
start = VECTOR2D( Convert( xStr ), Convert( yStr ) );
std::unique_ptr<LIB_SHAPE> shape =
std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::ARC );
shape->SetArcGeometry( transform( arc.GetP0() ),
transform( arc.GetArcMid() ),
transform( arc.GetP1() ) );
shape->SetUnit( 0 );
shape->SetStroke( STROKE_PARAMS( ScaleSize( lineWidth ), strokeStyle ) );
if( fillColor != wxS( "none" ) )
{
shape->SetFilled( true );
if( fillColor == strokeColor )
shape->SetFillMode( FILL_T::FILLED_SHAPE );
else
shape->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
}
aSymbol->AddDrawItem( shape.release() );
}
else
{
SEG seg = chain.CSegment( i );
std::unique_ptr<LIB_SHAPE> shape =
std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::POLY );
shape->AddPoint( transform( seg.A ) );
shape->AddPoint( transform( seg.B ) );
shape->SetUnit( 0 );
shape->SetStroke( STROKE_PARAMS( ScaleSize( lineWidth ), strokeStyle ) );
aSymbol->AddDrawItem( shape.release() );
}
}
else if( sym == 'A' )
{
wxString radX, radY, unknown, farFlag, cwFlag, endX, endY;
readNumber( radX );
readNumber( radY );
readNumber( unknown );
readNumber( farFlag );
readNumber( cwFlag );
readNumber( endX );
readNumber( endY );
isFar = farFlag == wxS( "1" );
cw = cwFlag == wxS( "1" );
rad = VECTOR2D( Convert( radX ), Convert( radY ) );
end = VECTOR2D( Convert( endX ), Convert( endY ) );
}
} while( pos < data.size() );
VECTOR2D delta = end - start;
double avgRad = ( rad.x + rad.y ) / 2;
double d = delta.EuclideanNorm();
double h = sqrt( std::max( 0.0, avgRad * avgRad - d * d / 4 ) );
//( !far && cw ) => h
//( far && cw ) => -h
//( !far && !cw ) => -h
//( far && !cw ) => h
VECTOR2D arcCenter =
start + delta / 2 + delta.Perpendicular().Resize( ( isFar ^ cw ) ? h : -h );
if( cw )
std::swap( start, end );
std::unique_ptr<LIB_SHAPE> shape = std::make_unique<LIB_SHAPE>( aSymbol, SHAPE_T::ARC );
shape->SetStart( RelPosSym( start ) );
shape->SetEnd( RelPosSym( end ) );
shape->SetCenter( RelPosSym( arcCenter ) );
shape->SetUnit( 0 );
shape->SetStroke( STROKE_PARAMS( ScaleSize( lineWidth ), strokeStyle ) );
if( fillColor != wxS( "none" ) )
{
shape->SetFilled( true );
if( fillColor == strokeColor )
shape->SetFillMode( FILL_T::FILLED_SHAPE );
else
shape->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
}
aSymbol->AddDrawItem( shape.release() );
}
else if( elType == wxS( "R" ) )
{
@@ -962,22 +941,20 @@ LIB_SYMBOL* SCH_EASYEDA_PARSER::ParseSymbol( const VECTOR2D& aOrigi
m_relOrigin = aOrigin;
wxString symbolName = wxS( "Unknown" );
std::optional<wxString> valOpt;
wxString symbolName = wxS( "Unknown" );
if( aParams.find( wxS( "name" ) ) != aParams.end() )
symbolName = aParams.at( wxS( "name" ) );
else if( aParams.find( wxS( "spiceSymbolName" ) ) != aParams.end() )
symbolName = aParams.at( wxS( "spiceSymbolName" ) );
if( valOpt = get_opt( aParams, wxS( "name" ) ) )
symbolName = *valOpt;
else if( valOpt = get_opt( aParams, wxS( "spiceSymbolName" ) ) )
symbolName = *valOpt;
wxString symbolPrefix;
if( aParams.find( wxS( "pre" ) ) != aParams.end() )
symbolPrefix = aParams.at( wxS( "pre" ) );
else if( aParams.find( wxS( "spicePre" ) ) != aParams.end() )
symbolPrefix = aParams.at( wxS( "spicePre" ) );
if( !symbolPrefix.EndsWith( wxS( "?" ) ) )
symbolPrefix += wxS( "?" );
if( valOpt = get_opt( aParams, wxS( "pre" ) ) )
symbolPrefix = *valOpt;
else if( valOpt = get_opt( aParams, wxS( "spicePre" ) ) )
symbolPrefix = *valOpt;
LIB_ID libId = EasyEdaToKiCadLibID( wxEmptyString, symbolName );
@@ -987,6 +964,31 @@ LIB_SYMBOL* SCH_EASYEDA_PARSER::ParseSymbol( const VECTOR2D& aOrigi
ksymbol->GetReferenceField().SetText( symbolPrefix );
ksymbol->GetValueField().SetText( symbolName );
for( wxString attrName : c_attributesWhitelist )
{
wxString srcName = attrName;
if( srcName == wxS( "Datasheet" ) )
srcName = wxS( "link" );
if( valOpt = get_opt( aParams, srcName ) )
{
if( valOpt->empty() )
continue;
LIB_FIELD* fd = ksymbol->FindField( attrName, true );
if( !fd )
{
fd = new LIB_FIELD( ksymbol->GetNextAvailableFieldId(), attrName );
ksymbol->AddField( fd );
}
fd->SetText( *valOpt );
fd->SetVisible( false );
}
}
ParseSymbolShapes( ksymbol.get(), aParams, aShapes );
return ksymbol.release();
+26 -2
View File
@@ -225,7 +225,19 @@ LIB_SYMBOL* loadSymbol( const wxString& aLibraryPath, nlohmann::json aFileData,
{
parts.RemoveAt( 0 );
return parser.ParseSymbol( origin, paramMap, parts );
LIB_SYMBOL* ksymbol = parser.ParseSymbol( origin, paramMap, parts );
// Clear reference numbers
LIB_FIELD& refField = ksymbol->GetReferenceField();
wxString origRef = refField.GetText();
wxString reference;
for( size_t i = 0; i < origRef.size() && !wxIsdigit( origRef[i] ); i++ )
reference << origRef[i];
refField.SetText( reference );
return ksymbol;
}
}
}
@@ -261,7 +273,19 @@ LIB_SYMBOL* loadSymbol( const wxString& aLibraryPath, nlohmann::json aFileData,
VECTOR2D origin( topDoc.head.x, topDoc.head.y );
return parser.ParseSymbol( origin, *c_para, topDoc.shape );
LIB_SYMBOL* ksymbol = parser.ParseSymbol( origin, *c_para, topDoc.shape );
// Clear reference numbers
LIB_FIELD& refField = ksymbol->GetReferenceField();
wxString origRef = refField.GetText();
wxString reference;
for( size_t i = 0; i < origRef.size() && !wxIsdigit( origRef[i] ); i++ )
reference << origRef[i];
refField.SetText( reference );
return ksymbol;
}
}
catch( nlohmann::json::exception& e )
@@ -1,8 +1,8 @@
/*
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Alex Shvartzkop <dudesuchamazing@gmail.com>
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2023-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
@@ -52,6 +52,21 @@
#include <import_gfx/graphics_importer_sch.h>
// clang-format off
static const std::vector<wxString> c_attributesWhitelist = { "Value",
"Datasheet",
"Manufacturer Part",
"Manufacturer",
"BOM_Manufacturer Part",
"BOM_Manufacturer",
"Supplier Part",
"Supplier",
"BOM_Supplier Part",
"BOM_Supplier",
"LCSC Part Name" };
// clang-format on
SCH_EASYEDAPRO_PARSER::SCH_EASYEDAPRO_PARSER( SCHEMATIC* aSchematic,
PROGRESS_REPORTER* aProgressReporter )
{
@@ -383,7 +398,9 @@ void SCH_EASYEDAPRO_PARSER::ApplyAttrToField( const std::map<wxString, nlohmann:
}
EASYEDAPRO::SYM_INFO SCH_EASYEDAPRO_PARSER::ParseSymbol( const std::vector<nlohmann::json>& aLines )
EASYEDAPRO::SYM_INFO
SCH_EASYEDAPRO_PARSER::ParseSymbol( const std::vector<nlohmann::json>& aLines,
const std::map<wxString, wxString>& aDeviceAttributes )
{
EASYEDAPRO::SYM_INFO symInfo;
@@ -686,11 +703,35 @@ EASYEDAPRO::SYM_INFO SCH_EASYEDAPRO_PARSER::ParseSymbol( const std::vector<nlohm
{
wxString symbolPrefix = designatorAttr->value;
if( !symbolPrefix.EndsWith( wxS( "?" ) ) )
symbolPrefix += wxS( "?" );
if( symbolPrefix.EndsWith( wxS( "?" ) ) )
symbolPrefix.RemoveLast();
ksymbol->GetReferenceField().SetText( symbolPrefix );
}
for( const wxString& attrName : c_attributesWhitelist )
{
if( auto valOpt = get_opt( aDeviceAttributes, attrName ) )
{
if( valOpt->empty() )
continue;
LIB_FIELD* fd = ksymbol->FindField( attrName, true );
if( !fd )
{
fd = new LIB_FIELD( ksymbol->GetNextAvailableFieldId(), attrName );
ksymbol->AddField( fd );
}
wxString value = *valOpt;
value.Replace( wxS( "\u2103" ), wxS( "\u00B0C" ), true ); // ℃ -> °C
fd->SetText( value );
fd->SetVisible( false );
}
}
}
for( auto& [unitId, parentedLines] : unitParentedLines )
@@ -1107,7 +1148,7 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
if( !deviceAttr )
continue;
nlohmann::json compAttrs =
std::map<wxString, wxString> compAttrs =
aProject.at( "devices" ).at( deviceAttr->value ).at( "attributes" );
wxString symbolId;
@@ -1115,7 +1156,7 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
if( symbolAttr && !symbolAttr->value.IsEmpty() )
symbolId = symbolAttr->value;
else
symbolId = compAttrs.at( "Symbol" ).get<wxString>();
symbolId = compAttrs.at( "Symbol" );
auto it = aSymbolMap.find( symbolId );
if( it == aSymbolMap.end() )
@@ -1217,6 +1258,30 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
}
else
{
for( const wxString& attrKey : c_attributesWhitelist )
{
if( auto valOpt = get_opt( compAttrs, attrKey ) )
{
if( valOpt->empty() )
continue;
SCH_FIELD* text = schSym->FindField( attrKey, true );
if( !text )
{
text = schSym->AddField(
SCH_FIELD( schSym.get(), schSym->GetFieldCount(), attrKey ) );
}
wxString value = *valOpt;
value.Replace( wxS( "\u2103" ), wxS( "\u00B0C" ), true ); // ℃ -> °C
text->SetText( value );
text->SetVisible( false );
}
}
auto nameAttr = get_opt( attributes, "Name" );
auto valueAttr = get_opt( attributes, "Value" );
@@ -1265,15 +1330,18 @@ void SCH_EASYEDAPRO_PARSER::ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aR
if( attr.value.IsEmpty() )
continue;
SCH_FIELD* text =
new SCH_FIELD( schSym.get(), schSym->GetFieldCount(), attrKey );
SCH_FIELD* text = schSym->FindField( attrKey, true );
if( !text )
{
text = schSym->AddField(
SCH_FIELD( schSym.get(), schSym->GetFieldCount(), attrKey ) );
}
text->SetPosition( schSym->GetPosition() );
ApplyAttrToField( fontStyles, text, attr, false, true, compAttrs,
schSym.get() );
schSym->AddField( *text );
}
}
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Alex Shvartzkop <dudesuchamazing@gmail.com>
* Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2023-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
@@ -101,7 +101,8 @@ public:
double SizeToKi( wxString units );
EASYEDAPRO::SYM_INFO ParseSymbol( const std::vector<nlohmann::json>& aLines );
EASYEDAPRO::SYM_INFO ParseSymbol( const std::vector<nlohmann::json>& aLines,
const std::map<wxString, wxString>& aDeviceAttributes );
void ParseSchematic( SCHEMATIC* aSchematic, SCH_SHEET* aRootSheet,
const nlohmann::json& aProject,
@@ -1,4 +1,4 @@
/*
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2023 Alex Shvartzkop <dudesuchamazing@gmail.com>
@@ -156,7 +156,11 @@ static LIB_SYMBOL* loadSymbol( nlohmann::json project, const wxString& aLibraryP
return nullptr;
wxString prjSymUuid = prjSymIt->first;
wxString fpTitle;
wxString description;
wxString customTags;
std::map<wxString, wxString> deviceAttributes;
wxString fpTitle;
for( auto& [key, device] : prjDevices )
{
@@ -164,6 +168,12 @@ static LIB_SYMBOL* loadSymbol( nlohmann::json project, const wxString& aLibraryP
if( val && *val == prjSymUuid )
{
description = device.description;
deviceAttributes = device.attributes;
if( device.custom_tags.is_string() )
customTags = device.custom_tags.get<wxString>();
if( auto fpUuid = get_opt( device.attributes, "Footprint" ) )
{
if( auto prjFp = get_opt( prjFootprints, *fpUuid ) )
@@ -192,7 +202,7 @@ static LIB_SYMBOL* loadSymbol( nlohmann::json project, const wxString& aLibraryP
lines.emplace_back( js );
}
EASYEDAPRO::SYM_INFO symInfo = parser.ParseSymbol( lines );
EASYEDAPRO::SYM_INFO symInfo = parser.ParseSymbol( lines, deviceAttributes );
if( !symInfo.libSymbol )
EASY_IT_CONTINUE;
@@ -202,6 +212,15 @@ static LIB_SYMBOL* loadSymbol( nlohmann::json project, const wxString& aLibraryP
symInfo.libSymbol->SetName( aAliasName );
symInfo.libSymbol->GetFootprintField().SetText( symLibName + wxS( ":" ) + fpTitle );
wxString keywords = customTags;
keywords.Replace( wxS( ":" ), wxS( " " ), true );
symInfo.libSymbol->SetKeyWords( keywords );
description.Replace( wxS( "\u2103" ), wxS( "\u00B0C" ), true ); // ℃ -> °C
symInfo.libSymbol->SetDescription( description );
symbol = symInfo.libSymbol.release();
EASY_IT_BREAK;
@@ -314,13 +333,10 @@ void SCH_IO_EASYEDAPRO::LoadAllDataFromProject( const wxString& aProjectPath )
if( name.EndsWith( wxS( ".esym" ) ) )
{
EASYEDAPRO::PRJ_SYMBOL symData = prjSymbols.at( baseName );
EASYEDAPRO::SYM_INFO symInfo = parser.ParseSymbol( lines );
if( !symInfo.libSymbol )
EASY_IT_CONTINUE;
wxString fpTitle;
wxString description;
wxString customTags;
std::map<wxString, wxString> deviceAttributes;
wxString fpTitle;
for( auto& [key, device] : prjDevices )
{
@@ -328,6 +344,12 @@ void SCH_IO_EASYEDAPRO::LoadAllDataFromProject( const wxString& aProjectPath )
if( val && *val == baseName )
{
description = device.description;
deviceAttributes = device.attributes;
if( device.custom_tags.is_string() )
customTags = device.custom_tags.get<wxString>();
if( auto fpUuid = get_opt( device.attributes, "Footprint" ) )
{
if( auto prjFp = get_opt( prjFootprints, *fpUuid ) )
@@ -339,11 +361,26 @@ void SCH_IO_EASYEDAPRO::LoadAllDataFromProject( const wxString& aProjectPath )
}
}
EASYEDAPRO::PRJ_SYMBOL symData = prjSymbols.at( baseName );
EASYEDAPRO::SYM_INFO symInfo = parser.ParseSymbol( lines, deviceAttributes );
if( !symInfo.libSymbol )
EASY_IT_CONTINUE;
LIB_ID libID = EASYEDAPRO::ToKiCadLibID( symLibName, symData.title );
symInfo.libSymbol->SetLibId( libID );
symInfo.libSymbol->SetName( symData.title );
symInfo.libSymbol->GetFootprintField().SetText( symLibName + wxS( ":" ) + fpTitle );
wxString keywords = customTags;
keywords.Replace( wxS( ":" ), wxS( " " ), true );
symInfo.libSymbol->SetKeyWords( keywords );
description.Replace( wxS( "\u2103" ), wxS( "\u00B0C" ), true ); // ℃ -> °C
symInfo.libSymbol->SetDescription( description );
m_projectData->m_Symbols.emplace( baseName, std::move( symInfo ) );
}
else if( name.EndsWith( wxS( ".eblob" ) ) )
@@ -539,7 +539,9 @@ void SCH_IO_KICAD_LEGACY_LIB_CACHE::loadField( std::unique_ptr<LIB_SYMBOL>& aSym
LIB_FIELD* field;
if( id >= 0 && id < MANDATORY_FIELDS )
// Description was not mandatory until v8.0, so any fields with an index
// past this point should be user fields
if( id >= 0 && id < DESCRIPTION_FIELD )
{
field = aSymbol->GetFieldById( id );
@@ -550,6 +552,7 @@ void SCH_IO_KICAD_LEGACY_LIB_CACHE::loadField( std::unique_ptr<LIB_SYMBOL>& aSym
}
else
{
id = aSymbol->GetNextAvailableFieldId();
field = new LIB_FIELD( aSymbol.get(), id );
aSymbol->AddDrawItem( field, false );
}
@@ -783,75 +783,79 @@ void SCH_IO_KICAD_SEXPR::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSche
if( !aSymbol->GetInstances().empty() )
{
std::map<KIID, std::vector<SCH_SYMBOL_INSTANCE>> projectInstances;
m_out->Print( aNestLevel + 1, "(instances\n" );
wxString projectName;
KIID lastProjectUuid;
KIID rootSheetUuid = aSchematic.Root().m_Uuid;
SCH_SHEET_LIST fullHierarchy = aSchematic.GetSheets();
bool project_open = false;
for( size_t i = 0; i < aSymbol->GetInstances().size(); i++ )
for( const SCH_SYMBOL_INSTANCE& inst : aSymbol->GetInstances() )
{
// Zero length KIID_PATH objects are not valid and will cause a crash below.
wxCHECK2( aSymbol->GetInstances()[i].m_Path.size(), continue );
wxCHECK2( inst.m_Path.size(), continue );
// If the instance data is part of this design but no longer has an associated sheet
// path, don't save it. This prevents large amounts of orphaned instance data for the
// current project from accumulating in the schematic files.
//
// Keep all instance data when copying to the clipboard. It may be needed on paste.
if( !aForClipboard
&& ( aSymbol->GetInstances()[i].m_Path[0] == rootSheetUuid )
&& !fullHierarchy.GetSheetPathByKIIDPath( aSymbol->GetInstances()[i].m_Path ) )
{
if( project_open && ( ( i + 1 == aSymbol->GetInstances().size() )
|| lastProjectUuid != aSymbol->GetInstances()[i+1].m_Path[0] ) )
{
m_out->Print( aNestLevel + 2, ")\n" ); // Closes `project`.
project_open = false;
}
bool isOrphaned = ( inst.m_Path[0] == rootSheetUuid )
&& !fullHierarchy.GetSheetPathByKIIDPath( inst.m_Path );
// Keep all instance data when copying to the clipboard. They may be needed on paste.
if( !aForClipboard && isOrphaned )
continue;
}
if( lastProjectUuid != aSymbol->GetInstances()[i].m_Path[0] )
auto it = projectInstances.find( inst.m_Path[0] );
if( it == projectInstances.end() )
{
wxString projectName;
if( aSymbol->GetInstances()[i].m_Path[0] == rootSheetUuid )
projectName = aSchematic.Prj().GetProjectName();
else
projectName = aSymbol->GetInstances()[i].m_ProjectName;
lastProjectUuid = aSymbol->GetInstances()[i].m_Path[0];
m_out->Print( aNestLevel + 2, "(project %s\n",
m_out->Quotew( projectName ).c_str() );
project_open = true;
projectInstances[ inst.m_Path[0] ] = { inst };
}
wxString path;
KIID_PATH tmp = aSymbol->GetInstances()[i].m_Path;
if( aForClipboard && aRelativePath )
tmp.MakeRelativeTo( aRelativePath->Path() );
path = tmp.AsString();
m_out->Print( aNestLevel + 3, "(path %s\n",
m_out->Quotew( path ).c_str() );
m_out->Print( aNestLevel + 4, "(reference %s) (unit %d)\n",
m_out->Quotew( aSymbol->GetInstances()[i].m_Reference ).c_str(),
aSymbol->GetInstances()[i].m_Unit );
m_out->Print( aNestLevel + 3, ")\n" );
if( project_open && ( ( i + 1 == aSymbol->GetInstances().size() )
|| lastProjectUuid != aSymbol->GetInstances()[i+1].m_Path[0] ) )
else
{
m_out->Print( aNestLevel + 2, ")\n" ); // Closes `project`.
project_open = false;
it->second.emplace_back( inst );
}
}
for( auto& [uuid, instances] : projectInstances )
{
wxCHECK2( instances.size(), continue );
// Sort project instances by KIID_PATH.
std::sort( instances.begin(), instances.end(),
[]( SCH_SYMBOL_INSTANCE& aLhs, SCH_SYMBOL_INSTANCE& aRhs )
{
return aLhs.m_Path < aRhs.m_Path;
} );
projectName = instances[0].m_ProjectName;
m_out->Print( aNestLevel + 2, "(project %s\n",
m_out->Quotew( projectName ).c_str() );
for( const SCH_SYMBOL_INSTANCE& instance : instances )
{
wxString path;
KIID_PATH tmp = instance.m_Path;
if( aForClipboard && aRelativePath )
tmp.MakeRelativeTo( aRelativePath->Path() );
path = tmp.AsString();
m_out->Print( aNestLevel + 3, "(path %s\n",
m_out->Quotew( path ).c_str() );
m_out->Print( aNestLevel + 4, "(reference %s) (unit %d)\n",
m_out->Quotew( instance.m_Reference ).c_str(),
instance.m_Unit );
m_out->Print( aNestLevel + 3, ")\n" );
}
m_out->Print( aNestLevel + 2, ")\n" ); // Closes `project`.
}
m_out->Print( aNestLevel + 1, ")\n" ); // Closes `instances`.
}
+1 -1
View File
@@ -892,7 +892,7 @@ wxString SCH_LABEL_BASE::GetShownText( const SCH_SHEET_PATH* aPath, bool aAllowE
std::function<bool( wxString* )> textResolver =
[&]( wxString* token ) -> bool
{
return ResolveTextVar( aPath, token, aDepth );
return ResolveTextVar( aPath, token, aDepth + 1 );
};
wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
+6 -53
View File
@@ -68,6 +68,8 @@
#include "sch_shape.h"
#include "common.h"
#include "symb_transforms_utils.h"
namespace KIGFX
{
@@ -491,8 +493,9 @@ COLOR4D SCH_PAINTER::getRenderColor( const EDA_ITEM* aItem, int aLayer, bool aDr
if( aDrawingShadows )
color = m_schSettings.GetLayerColor( LAYER_SELECTION_SHADOWS );
}
else if( aItem->IsSelected()
&& ( aLayer == LAYER_DEVICE_BACKGROUND || aLayer == LAYER_SHEET_BACKGROUND ) )
else if( aItem->IsSelected() && ( aLayer == LAYER_DEVICE_BACKGROUND
|| aLayer == LAYER_SHEET_BACKGROUND
|| aLayer == LAYER_NOTES_BACKGROUND ) )
{
// Selected items will be painted over all other items, so make backgrounds translucent so
// that non-selected overlapping objects are visible
@@ -2429,56 +2432,6 @@ void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer )
}
static void orientSymbol( LIB_SYMBOL* symbol, int orientation )
{
struct ORIENT
{
int flag;
int n_rots;
int mirror_x;
int mirror_y;
}
orientations[] =
{
{ SYM_ORIENT_0, 0, 0, 0 },
{ SYM_ORIENT_90, 1, 0, 0 },
{ SYM_ORIENT_180, 2, 0, 0 },
{ SYM_ORIENT_270, 3, 0, 0 },
{ SYM_MIRROR_X + SYM_ORIENT_0, 0, 1, 0 },
{ SYM_MIRROR_X + SYM_ORIENT_90, 1, 1, 0 },
{ SYM_MIRROR_Y, 0, 0, 1 },
{ SYM_MIRROR_X + SYM_ORIENT_270, 3, 1, 0 },
{ SYM_MIRROR_Y + SYM_ORIENT_0, 0, 0, 1 },
{ SYM_MIRROR_Y + SYM_ORIENT_90, 1, 0, 1 },
{ SYM_MIRROR_Y + SYM_ORIENT_180, 2, 0, 1 },
{ SYM_MIRROR_Y + SYM_ORIENT_270, 3, 0, 1 }
};
ORIENT o = orientations[ 0 ];
for( ORIENT& i : orientations )
{
if( i.flag == orientation )
{
o = i;
break;
}
}
for( LIB_ITEM& item : symbol->GetDrawItems() )
{
for( int i = 0; i < o.n_rots; i++ )
item.Rotate( VECTOR2I(0, 0 ), true );
if( o.mirror_x )
item.MirrorVertical( VECTOR2I( 0, 0 ) );
if( o.mirror_y )
item.MirrorHorizontal( VECTOR2I( 0, 0 ) );
}
}
wxString SCH_PAINTER::expandLibItemTextVars( const wxString& aSourceText,
const SCH_SYMBOL* aSymbolContext )
{
@@ -2530,7 +2483,7 @@ void SCH_PAINTER::draw( const SCH_SYMBOL* aSymbol, int aLayer )
tempSymbol.SetFlags( aSymbol->GetFlags() );
orientSymbol( &tempSymbol, aSymbol->GetOrientation() );
OrientAndMirrorSymbolItems( &tempSymbol, aSymbol->GetOrientation() );
for( LIB_ITEM& tempItem : tempSymbol.GetDrawItems() )
{
-27
View File
@@ -2081,33 +2081,6 @@ bool SCH_SCREENS::HasSchematic( const wxString& aSchematicFileName )
}
bool SCH_SCREENS::CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const
{
wxString lhsLower;
wxString rhsLower;
wxFileName lhs;
wxFileName rhs = aSchematicFileName;
wxCHECK( rhs.IsAbsolute(), false );
for( const SCH_SCREEN* screen : m_screens )
{
lhs = screen->GetFileName();
if( lhs.GetPath() != rhs.GetPath() )
continue;
lhsLower = lhs.GetFullName().Lower();
rhsLower = rhs.GetFullName().Lower();
if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
return true;
}
return false;
}
void SCH_SCREENS::BuildClientSheetPathList()
{
SCH_SCREEN* first = GetFirst();
-13
View File
@@ -812,19 +812,6 @@ public:
*/
void BuildClientSheetPathList();
/**
* Check \a aSchematicFileName for a potential file name case sensitivity issue.
*
* On platforms where file names are case sensitive, it is possible to schematic sheet
* file names that would cause issues on platforms where file name are case insensitive.
* File names foo.sch and Foo.sch are unique files on Linux and MacOS but on Windows
* this would result in a broken schematic.
*
* @param[in] aSchematicFileName is the absolute path and file name of the file to test.
* @return true if \a aSchematicFileName would cause an issue.
*/
bool CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const;
/**
* Update the symbol value and footprint instance data for legacy designs.
*/
+13 -3
View File
@@ -562,8 +562,11 @@ void SCH_SHEET_PATH::SetPageNumber( const wxString& aPageNumber )
}
void SCH_SHEET_PATH::AddNewSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath )
void SCH_SHEET_PATH::AddNewSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath,
const wxString& aProjectName )
{
wxCHECK( !aProjectName.IsEmpty(), /* void */ );
SCH_SHEET_PATH newSheetPath( aPrefixSheetPath );
SCH_SHEET_PATH currentSheetPath( *this );
@@ -580,12 +583,16 @@ void SCH_SHEET_PATH::AddNewSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPa
if( symbol->GetInstance( newSymbolInstance, Path(), true ) )
{
newSymbolInstance.m_ProjectName = aProjectName;
// Use an existing symbol instance for this path if it exists.
newSymbolInstance.m_Path = newSheetPath.Path();
symbol->AddHierarchicalReference( newSymbolInstance );
}
else if( !symbol->GetInstances().empty() )
{
newSymbolInstance.m_ProjectName = aProjectName;
// Use the first symbol instance if any symbol instance data exists.
newSymbolInstance = symbol->GetInstances()[0];
newSymbolInstance.m_Path = newSheetPath.Path();
@@ -593,6 +600,8 @@ void SCH_SHEET_PATH::AddNewSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPa
}
else
{
newSymbolInstance.m_ProjectName = aProjectName;
// Fall back to the last saved symbol field and unit settings if there is no
// instance data.
newSymbolInstance.m_Path = newSheetPath.Path();
@@ -1237,10 +1246,11 @@ void SCH_SHEET_LIST::SetInitialPageNumbers()
}
void SCH_SHEET_LIST::AddNewSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath )
void SCH_SHEET_LIST::AddNewSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath,
const wxString& aProjectName )
{
for( SCH_SHEET_PATH& sheetPath : *this )
sheetPath.AddNewSymbolInstances( aPrefixSheetPath );
sheetPath.AddNewSymbolInstances( aPrefixSheetPath, aProjectName );
}
+9 -2
View File
@@ -395,8 +395,13 @@ public:
* from the library symbol.
* - If all else fails, set the reference to "U?", the unit to 1, and everything else to
* an empty string.
*
* @param aPrefixSheetPath is the sheet path to prefix to this sheet path for the new symbol
* instance.
* @param aProjectName is the name of the project for the new symbol instance data.
*/
void AddNewSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath );
void AddNewSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath,
const wxString& aProjectName );
void RemoveSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath );
@@ -669,8 +674,10 @@ public:
* with \a aPrefixSheetPath.
*
* @param aPrefixSheetPath is the sheet path to append the new symbol instances to.
* @param aProjectName is the name of the project for the new symbol instance data.
*/
void AddNewSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath );
void AddNewSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath,
const wxString& aProjectName );
void AddNewSheetInstances( const SCH_SHEET_PATH& aPrefixSheetPath,
int aLastVirtualPageNumber );
+23
View File
@@ -1146,6 +1146,29 @@ SCH_PIN* SCH_SYMBOL::GetPin( const wxString& aNumber ) const
}
const SCH_PIN* SCH_SYMBOL::GetPin( const VECTOR2I& aPos ) const
{
for( const std::unique_ptr<SCH_PIN>& pin : m_pins )
{
int pin_unit = pin->GetLibPin() ? pin->GetLibPin()->GetUnit()
: GetUnit();
int pin_bodyStyle = pin->GetLibPin() ? pin->GetLibPin()->GetBodyStyle()
: GetBodyStyle();
if( pin_unit > 0 && pin_unit != GetUnit() )
continue;
if( pin_bodyStyle > 0 && pin_bodyStyle != GetBodyStyle() )
continue;
if( pin->IsPointClickableAnchor( aPos ) )
return pin.get();
}
return nullptr;
}
void SCH_SYMBOL::GetLibPins( std::vector<LIB_PIN*>& aPinsList ) const
{
if( m_part )
+9
View File
@@ -635,6 +635,15 @@ public:
*/
SCH_PIN* GetPin( LIB_PIN* aLibPin ) const;
/**
* Return the #SCH_PIN object found at \a aPosition.
*
* @param aPosition is the position of the pin to fetch.
*
* @return the #SCH_PIN object found at \a aPosition or nullptr.
*/
const SCH_PIN* GetPin( const VECTOR2I& aPosition ) const;
/**
* Retrieve a list of the SCH_PINs for the given sheet path.
*
+2
View File
@@ -120,6 +120,8 @@ SCHEMATIC::SCHEMATIC( PROJECT* aPrj ) :
SCHEMATIC::~SCHEMATIC()
{
PROPERTY_MANAGER::Instance().UnregisterListeners( TYPE_HASH( SCH_FIELD ) );
delete m_currentSheet;
delete m_connectionGraph;
}
+3
View File
@@ -196,6 +196,9 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin
m_TemplateFieldNames.AddTemplateFieldNames( cfg->m_Drawing.field_names );
}, {} ) );
m_params.emplace_back( new PARAM<wxString>( "bom_export_filename",
&m_BomExportFileName, "" ) );
m_params.emplace_back( new PARAM<BOM_PRESET>( "bom_settings",
&m_BomSettings, BOM_PRESET::GroupedByValue() ) );
m_params.emplace_back( new PARAM_LIST<BOM_PRESET>( "bom_presets",
+2
View File
@@ -105,6 +105,8 @@ public:
TEMPLATES m_TemplateFieldNames;
wxString m_BomExportFileName;
/// List of stored BOM presets
BOM_PRESET m_BomSettings;
std::vector<BOM_PRESET> m_BomPresets;
+39 -6
View File
@@ -570,7 +570,7 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aCurr
newScreen->MigrateSimModels();
// Attempt to create new symbol instances using the instance data loaded above.
sheetHierarchy.AddNewSymbolInstances( *aCurrentSheet );
sheetHierarchy.AddNewSymbolInstances( *aCurrentSheet, Prj().GetProjectName() );
// Add new sheet instance data.
sheetHierarchy.AddNewSheetInstances( *aCurrentSheet, hierarchy.GetLastVirtualPageNumber() );
@@ -688,16 +688,49 @@ void SCH_EDIT_FRAME::DrawCurrentSheetToClipboard()
}
bool SCH_EDIT_FRAME::AllowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName )
bool SCH_EDIT_FRAME::AllowCaseSensitiveFileNameClashes( const wxString& aOldName, const wxString& aSchematicFileName )
{
wxString msg;
SCH_SCREENS screens( Schematic().Root() );
SCH_SHEET_LIST sheets( &Schematic().Root() );
wxFileName fn = aSchematicFileName;
wxCHECK( fn.IsAbsolute(), false );
if( eeconfig()->m_Appearance.show_sheet_filename_case_sensitivity_dialog
&& screens.CanCauseCaseSensitivityIssue( aSchematicFileName ) )
auto can_cause_issues = [&]() -> bool
{
wxFileName lhs;
wxFileName rhs = aSchematicFileName;
wxFileName old = aOldName;
wxString oldLower = old.GetFullName().Lower();
wxString rhsLower = rhs.GetFullName().Lower();
wxString lhsLower;
size_t count = 0;
wxCHECK( rhs.IsAbsolute(), false );
for( SCH_SHEET_PATH& sheet : sheets )
{
lhs = sheet.LastScreen()->GetFileName();
if( lhs.GetPath() != rhs.GetPath() )
continue;
lhsLower = lhs.GetFullName().Lower();
if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
count++;
}
// If we are renaming a sheet that is only used once, then we are not going to cause
// a case sensitivity issue.
if( oldLower == rhsLower )
return count > 1;
return count > 0;
};
if( eeconfig()->m_Appearance.show_sheet_filename_case_sensitivity_dialog && can_cause_issues() )
{
msg.Printf( _( "The file name '%s' can cause issues with an existing file name\n"
"already defined in the schematic on systems that support case\n"
@@ -710,7 +743,7 @@ bool SCH_EDIT_FRAME::AllowCaseSensitiveFileNameClashes( const wxString& aSchemat
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
dlg.ShowCheckBox( _( "Do not show this message again." ) );
dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Create New Sheet" ) ),
wxMessageDialog::ButtonLabel( _( "Discard New Sheet" ) ) );
wxMessageDialog::ButtonLabel( _( "Cancel" ) ) );
if( dlg.ShowModal() == wxID_NO )
return false;
+3 -3
View File
@@ -867,7 +867,7 @@ void KIBIS_PIN::getKuKdOneWaveform( KIBIS_MODEL& aMod
simul += "VmeasPD 0 x1.PD_GND0 0\n";
simul += "VmeasPU x1.PU_PWR0 3 0\n";
simul += "VmeasPC x1.PC_PWR0 3 0\n";
simul += "VmeasGC 0 x1.GC_PWR0 0\n";
simul += "VmeasGC 0 x1.GC_GND0 0\n";
if( aModel.HasPullup() && aModel.HasPulldown() )
{
@@ -1039,7 +1039,7 @@ void KIBIS_PIN::getKuKdTwoWaveforms( KIBIS_MODEL& aMo
simul += "VmeasPD0 0 x1.PD_GND0 0\n";
simul += "VmeasPU0 x1.PU_PWR0 3 0\n";
simul += "VmeasPC0 x1.PC_PWR0 3 0\n";
simul += "VmeasGC0 0 x1.GC_PWR0 0\n";
simul += "VmeasGC0 0 x1.GC_GND0 0\n";
simul += "\n x2 3 0 7 DRIVER1 \n";
@@ -1060,7 +1060,7 @@ void KIBIS_PIN::getKuKdTwoWaveforms( KIBIS_MODEL& aMo
simul += "VmeasPD1 0 x2.PD_GND0 0\n";
simul += "VmeasPU1 x2.PU_PWR0 3 0\n";
simul += "VmeasPC1 x2.PC_PWR0 3 0\n";
simul += "VmeasGC1 0 x2.GC_PWR0 0\n";
simul += "VmeasGC1 0 x2.GC_GND0 0\n";
if( aModel.HasPullup() && aModel.HasPulldown() )
{
+21 -4
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016-2022 CERN
* Copyright (C) 2018-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2018-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
@@ -59,6 +59,7 @@ NGSPICE::NGSPICE() :
m_ngSpice_Circ( nullptr ),
m_ngSpice_Command( nullptr ),
m_ngGet_Vec_Info( nullptr ),
m_ngCM_Input_Path( nullptr ),
m_ngSpice_CurPlot( nullptr ),
m_ngSpice_AllPlots( nullptr ),
m_ngSpice_AllVecs( nullptr ),
@@ -274,21 +275,23 @@ std::vector<double> NGSPICE::GetPhaseVector( const std::string& aName, int aMaxL
bool NGSPICE::Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel, const wxString& aSimCommand,
unsigned aSimOptions, REPORTER& aReporter )
unsigned aSimOptions, const wxString& aInputPath, REPORTER& aReporter )
{
SPICE_CIRCUIT_MODEL* model = dynamic_cast<SPICE_CIRCUIT_MODEL*>( aModel.get() );
STRING_FORMATTER formatter;
setCodemodelsInputPath( aInputPath.ToStdString() );
if( model && model->GetNetlist( aSimCommand, aSimOptions, &formatter, aReporter ) )
{
SIMULATOR::Attach( aModel, aSimCommand, aSimOptions, aReporter );
SIMULATOR::Attach( aModel, aSimCommand, aSimOptions, aInputPath, aReporter );
updateNgspiceSettings();
LoadNetlist( formatter.GetString() );
return true;
}
else
{
SIMULATOR::Attach( nullptr, wxEmptyString, 0, aReporter );
SIMULATOR::Attach( nullptr, wxEmptyString, 0, wxEmptyString, aReporter );
return false;
}
}
@@ -494,6 +497,7 @@ void NGSPICE::init_dll()
m_ngSpice_Circ = (ngSpice_Circ) m_dll.GetSymbol( "ngSpice_Circ" );
m_ngSpice_Command = (ngSpice_Command) m_dll.GetSymbol( "ngSpice_Command" );
m_ngGet_Vec_Info = (ngGet_Vec_Info) m_dll.GetSymbol( "ngGet_Vec_Info" );
m_ngCM_Input_Path = (ngCM_Input_Path) m_dll.GetSymbol( "ngCM_Input_Path" );
m_ngSpice_CurPlot = (ngSpice_CurPlot) m_dll.GetSymbol( "ngSpice_CurPlot" );
m_ngSpice_AllPlots = (ngSpice_AllPlots) m_dll.GetSymbol( "ngSpice_AllPlots" );
m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll.GetSymbol( "ngSpice_AllVecs" );
@@ -634,6 +638,19 @@ std::string NGSPICE::findCmPath() const
}
bool NGSPICE::setCodemodelsInputPath( const std::string& aPath )
{
if( !m_ngCM_Input_Path )
return false;
LOCALE_IO c_locale; // ngspice works correctly only with C locale
m_ngCM_Input_Path( aPath.c_str() );
return true;
}
bool NGSPICE::loadCodemodels( const std::string& aPath )
{
wxArrayString cmFiles;
+17 -10
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016-2022 CERN
* Copyright (C) 2021-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2021-2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
@@ -60,7 +60,8 @@ public:
///< @copydoc SPICE_SIMULATOR::Attach()
bool Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel, const wxString& aSimCommand,
unsigned aSimOptions, REPORTER& aReporter ) override final;
unsigned aSimOptions, const wxString& aInputPath,
REPORTER& aReporter ) override final;
///< Load a netlist for the simulation
bool LoadNetlist( const std::string& aNetlist ) override final;
@@ -116,21 +117,24 @@ private:
// ngspice library functions
typedef void ( *ngSpice_Init )( SendChar*, SendStat*, ControlledExit*, SendData*, SendInitData*,
BGThreadRunning*, void* );
typedef int ( *ngSpice_Circ )( char** circarray );
typedef int ( *ngSpice_Command )( char* command );
typedef int ( *ngSpice_Circ )( char** circarray );
typedef int ( *ngSpice_Command )( char* command );
typedef pvector_info ( *ngGet_Vec_Info )( char* vecname );
typedef char* ( *ngSpice_CurPlot )( void );
typedef char** ( *ngSpice_AllPlots )( void );
typedef char** ( *ngSpice_AllVecs )( char* plotname );
typedef bool ( *ngSpice_Running )( void );
typedef int ( *ngSpice_LockRealloc )( void );
typedef int ( *ngSpice_UnlockRealloc )( void );
typedef char* ( *ngCM_Input_Path )( const char* path );
typedef char* ( *ngSpice_CurPlot )( void );
typedef char** ( *ngSpice_AllPlots )( void );
typedef char** ( *ngSpice_AllVecs )( char* plotname );
typedef bool ( *ngSpice_Running )( void );
typedef int ( *ngSpice_LockRealloc )( void );
typedef int ( *ngSpice_UnlockRealloc )( void );
///< Handle to DLL functions
ngSpice_Init m_ngSpice_Init;
ngSpice_Circ m_ngSpice_Circ;
ngSpice_Command m_ngSpice_Command;
ngGet_Vec_Info m_ngGet_Vec_Info;
ngCM_Input_Path m_ngCM_Input_Path;
ngSpice_CurPlot m_ngSpice_CurPlot;
ngSpice_AllPlots m_ngSpice_AllPlots;
ngSpice_AllVecs m_ngSpice_AllVecs;
@@ -168,6 +172,9 @@ private:
///< Check a few different locations for codemodel files and returns one if it exists.
std::string findCmPath() const;
///< Send additional search path for codemodels to ngspice.
bool setCodemodelsInputPath( const std::string& aPath );
///< Load codemodel files from a directory.
bool loadCodemodels( const std::string& aPath );
+17 -11
View File
@@ -215,6 +215,19 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, S
}
}
auto getOrCreateField =
[&aSymbol, &fields]( const wxString& name ) -> SCH_FIELD*
{
for( SCH_FIELD& field : fields )
{
if( field.GetName().IsSameAs( name ) )
return &field;
}
fields.emplace_back( &aSymbol, -1, name );
return &fields.back();
};
wxString deviceType;
wxString modelType;
wxString modelParams;
@@ -225,20 +238,13 @@ SIM_LIBRARY::MODEL SIM_LIB_MGR::CreateModel( const SCH_SHEET_PATH* aSheetPath, S
if( SIM_MODEL::InferSimModel( aSymbol, &fields, true, SIM_VALUE_GRAMMAR::NOTATION::SI,
&deviceType, &modelType, &modelParams, &pinMap ) )
{
fields.emplace_back( &aSymbol, -1, SIM_DEVICE_FIELD );
fields.back().SetText( deviceType );
getOrCreateField( SIM_DEVICE_FIELD )->SetText( deviceType );
if( !modelType.IsEmpty() )
{
fields.emplace_back( &aSymbol, -1, SIM_DEVICE_SUBTYPE_FIELD );
fields.back().SetText( modelType );
}
getOrCreateField( SIM_DEVICE_SUBTYPE_FIELD )->SetText( modelType );
fields.emplace_back( &aSymbol, -1, SIM_PARAMS_FIELD );
fields.back().SetText( modelParams );
fields.emplace_back( &aSymbol, -1, SIM_PINS_FIELD );
fields.back().SetText( pinMap );
getOrCreateField( SIM_PARAMS_FIELD )->SetText( modelParams );
getOrCreateField( SIM_PINS_FIELD )->SetText( pinMap );
storeInValue = true;
}
+2
View File
@@ -1602,6 +1602,8 @@ void SIM_MODEL::MigrateSimModel( T_symbol& aSymbol, const PROJECT* aProject )
}
}
// Up until 8.0.3 we
return;
}
+5 -3
View File
@@ -59,7 +59,8 @@ std::vector<std::string> SPICE_GENERATOR_KIBIS::CurrentNames( const SPICE_ITEM&
std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const PROJECT& aProject,
const wxString& aCacheDir ) const
const wxString& aCacheDir,
REPORTER& aReporter ) const
{
std::string ibisLibFilename = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY::LIBRARY_FIELD );
std::string ibisCompName = SIM_MODEL::GetFieldValue( &aItem.fields, SIM_LIBRARY::NAME_FIELD );
@@ -71,6 +72,7 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const PR
KIBIS kibis( std::string( path.c_str() ) );
kibis.m_cacheDir = std::string( aCacheDir.c_str() );
kibis.m_reporter = &aReporter;
if( !kibis.m_valid )
THROW_IO_ERROR( wxString::Format( _( "Invalid IBIS file '%s'" ), ibisLibFilename ) );
@@ -167,10 +169,10 @@ std::string SPICE_GENERATOR_KIBIS::IbisDevice( const SPICE_ITEM& aItem, const PR
KIBIS_WAVEFORM_RECTANGULAR* waveform = new KIBIS_WAVEFORM_RECTANGULAR( &kibis );
if( const SIM_MODEL::PARAM* ton = m_model.FindParam( "ton" ) )
waveform->m_ton = SIM_VALUE::ToDouble( ton->value, 1 );
waveform->m_ton = SIM_VALUE::ToDouble( ton->value, 0 );
if( const SIM_MODEL::PARAM* toff = m_model.FindParam( "toff" ) )
waveform->m_toff = SIM_VALUE::ToDouble( toff->value, 1 );
waveform->m_toff = SIM_VALUE::ToDouble( toff->value, 0 );
if( const SIM_MODEL::PARAM* td = m_model.FindParam( "td" ) )
waveform->m_delay = SIM_VALUE::ToDouble( td->value, 0 );
+2 -1
View File
@@ -30,6 +30,7 @@
#include <project.h>
class SIM_LIBRARY_KIBIS;
class REPORTER;
class SPICE_GENERATOR_KIBIS : public SPICE_GENERATOR
@@ -42,7 +43,7 @@ public:
std::vector<std::string> CurrentNames( const SPICE_ITEM& aItem ) const override;
std::string IbisDevice( const SPICE_ITEM& aItem, const PROJECT& aProject,
const wxString& aCacheDir ) const;
const wxString& aCacheDir, REPORTER& aReporter ) const;
protected:
std::vector<std::reference_wrapper<const SIM_MODEL::PARAM>> GetInstanceParams() const override;
+3 -3
View File
@@ -62,9 +62,9 @@ namespace SIM_MODEL_SERIALIZER_GRAMMAR
quotedStringContent,
one<'"'>> {};
struct flagParam : sor<TAO_PEGTL_ISTRING( "off" ), // VDMOS
TAO_PEGTL_ISTRING( "thermal" ), // VDMOS
TAO_PEGTL_ISTRING( "xpart" )> {}; // BSIM1
struct flagParam : sor<seq<TAO_PEGTL_ISTRING( "off" ), not_at<alnum>>, // VDMOS
seq<TAO_PEGTL_ISTRING( "thermal" ), not_at<alnum>>, // VDMOS
seq<TAO_PEGTL_ISTRING( "xpart" ), not_at<alnum>>> {}; // BSIM1
struct fieldParamValuePair : sor<flagParam,
if_must<param,
+3
View File
@@ -177,6 +177,9 @@ std::string SPICE_GENERATOR_SOURCE::ItemLine( const SPICE_ITEM& aItem ) const
default:
for( const SIM_MODEL::PARAM& param : m_model.GetParams() )
{
if( ac != "" && ( param.Matches( "ac" ) || param.Matches( "ph" ) ) )
continue;
std::string argStr = SIM_VALUE::ToSpice( param.value );
if( argStr != "" )
+5 -4
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Sylwester Kocjan <s.kocjan@o2.pl>
* Copyright (C) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2022-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
@@ -59,7 +59,8 @@ public:
* @return True in case of success, false otherwise.
*/
virtual bool Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel,
const wxString& aSimCommand, unsigned aSimOptions, REPORTER& aReporter )
const wxString& aSimCommand, unsigned aSimOptions,
const wxString& aInputPath, REPORTER& aReporter )
{
m_simModel = aModel;
return true;
@@ -87,8 +88,8 @@ public:
virtual bool IsRunning() = 0;
/**
* Cleans simulation data (i.e. all vectors)
*
* Cleans simulation data (i.e. all vectors)
*
*/
virtual void Clean() = 0;
+22 -15
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016-2023 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>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@@ -61,6 +61,11 @@
#include <memory>
// Reporter is stored by pointer in KIBIS, so keep this here to avoid crashes
static wxString s_errors;
static WX_STRING_REPORTER s_reporter( &s_errors );
class SIM_THREAD_REPORTER : public SIMULATOR_REPORTER
{
public:
@@ -194,7 +199,7 @@ SIMULATOR_FRAME::~SIMULATOR_FRAME()
{
NULL_REPORTER devnull;
m_simulator->Attach( nullptr, wxEmptyString, 0, devnull );
m_simulator->Attach( nullptr, wxEmptyString, 0, wxEmptyString, devnull );
m_simulator->SetReporter( nullptr );
delete m_reporter;
}
@@ -338,8 +343,7 @@ void SIMULATOR_FRAME::UpdateTitle()
bool SIMULATOR_FRAME::LoadSimulator( const wxString& aSimCommand, unsigned aSimOptions )
{
wxString errors;
WX_STRING_REPORTER reporter( &errors );
s_errors.clear();
if( !m_schematicFrame->ReadyToNetlist( _( "Simulator requires a fully annotated schematic." ) ) )
return false;
@@ -348,9 +352,10 @@ bool SIMULATOR_FRAME::LoadSimulator( const wxString& aSimCommand, unsigned aSimO
if( ADVANCED_CFG::GetCfg().m_IncrementalConnectivity )
m_schematicFrame->RecalculateConnections( nullptr, GLOBAL_CLEANUP );
if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, reporter ) )
if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, Prj().GetProjectPath(),
s_reporter ) )
{
DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + errors );
DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + s_errors );
return false;
}
@@ -360,12 +365,10 @@ bool SIMULATOR_FRAME::LoadSimulator( const wxString& aSimCommand, unsigned aSimO
void SIMULATOR_FRAME::ReloadSimulator( const wxString& aSimCommand, unsigned aSimOptions )
{
wxString errors;
WX_STRING_REPORTER reporter( &errors );
if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, reporter ) )
if( !m_simulator->Attach( m_circuitModel, aSimCommand, aSimOptions, Prj().GetProjectPath(),
s_reporter ) )
{
DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + errors );
DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" ) + s_errors );
}
}
@@ -438,6 +441,10 @@ void SIMULATOR_FRAME::StartSimulation()
{
m_ui->OnSimUpdate();
m_simulator->Run();
// Netlist from schematic may have changed; update signals list, measurements list,
// etc.
m_ui->OnPlotSettingsChanged();
}
else
{
@@ -544,17 +551,17 @@ bool SIMULATOR_FRAME::EditAnalysis()
{
SIM_TAB* simTab = m_ui->GetCurrentSimTab();
DIALOG_SIM_COMMAND dlg( this, m_circuitModel, m_simulator->Settings() );
wxString errors;
WX_STRING_REPORTER reporter( &errors );
s_errors.clear();
if( !simTab )
return false;
if( !m_circuitModel->ReadSchematicAndLibraries( NETLIST_EXPORTER_SPICE::OPTION_DEFAULT_FLAGS,
reporter ) )
s_reporter ) )
{
DisplayErrorMessage( this, _( "Errors during netlist generation.\n\n" )
+ errors );
+ s_errors );
}
dlg.SetSimCommand( simTab->GetSimCommand() );
+28 -6
View File
@@ -104,8 +104,7 @@ namespace SPICE_GRAMMAR
one<']'>> {};
struct bracedExpr : seq<one<'{'>,
star<sor<bracedExpr,
not_one<'}'>>>,
star<not_one<'}'>>,
one<'}'>> {};
// Ngspice has some heuristic logic to allow + and - in tokens. We replicate that here.
@@ -132,6 +131,16 @@ namespace SPICE_GRAMMAR
sep,
paramValue> {};
struct paramValuePairs : list<paramValuePair, sep> {};
struct cplSep : opt<one<' '>> {};
struct cplParamValue : sor<list<bracedExpr, cplSep>,
vectorExpr,
list<token, cplSep>> {};
struct cplParamValuePair : seq<param,
sep,
cplParamValue> {};
struct cplParamValuePairs : list<cplParamValuePair, sep> {};
struct dotModelAko : seq<opt<sep>,
if_must<seq<TAO_PEGTL_ISTRING( ".model" ),
sep,
@@ -147,6 +156,17 @@ namespace SPICE_GRAMMAR
opt<sep>,
newline>> {};
struct dotModelCPL : seq<opt<sep>,
if_must<seq<TAO_PEGTL_ISTRING( ".model" ),
sep,
modelName,
sep,
TAO_PEGTL_ISTRING( "CPL" )>,
opt<sep,
cplParamValuePairs>,
opt<sep>,
newline>> {};
struct dotModel : seq<opt<sep>,
if_must<TAO_PEGTL_ISTRING( ".model" ),
sep,
@@ -157,8 +177,6 @@ namespace SPICE_GRAMMAR
paramValuePairs>,
opt<sep>,
newline>> {};
struct dotSubcktParamValuePair : seq<param,
// TODO: Check if these `star<space>`s match Ngspice's
@@ -176,7 +194,8 @@ namespace SPICE_GRAMMAR
struct dotSubcktPinName : seq<not_at<dotSubcktParams>,
plus<not_at<space>, any>> {};
struct dotSubcktPinSequence : list<dotSubcktPinName, sep> {};
struct dotSubcktEnd : seq<TAO_PEGTL_ISTRING( ".ends" ),
struct dotSubcktEnd : seq<opt<sep>,
TAO_PEGTL_ISTRING( ".ends" ),
until<newline>> {};
struct spiceUnit;
struct dotSubckt : seq<opt<sep>,
@@ -195,6 +214,7 @@ namespace SPICE_GRAMMAR
struct modelUnit : seq<star<commentLine>,
sor<dotModelAko,
dotModelCPL,
dotModel,
dotSubckt>> {};
@@ -284,7 +304,9 @@ namespace SPICE_GRAMMAR
"";
template <> inline constexpr auto errorMessage<opt<sep, paramValuePairs>> =
"";
template <> inline constexpr auto errorMessage<opt<sep, dotSubcktPinSequence>> =
template <> inline constexpr auto errorMessage<opt<sep, cplParamValuePairs>> =
"";
template <> inline constexpr auto errorMessage<opt<sep, dotSubcktPinSequence>> =
"";
template <> inline constexpr auto errorMessage<opt<sep, dotSubcktParams>> =
"";
+107
View File
@@ -0,0 +1,107 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Author Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "lib_symbol.h"
#include "sch_symbol.h"
#include "sch_pin.h"
struct ORIENT_MIRROR
{
int flag;
int n_rots;
int mirror_x;
int mirror_y;
};
// symbols_orientations_list is the list of possible orientation+mirror values
// like returned by SCH_SYMBOL::GetOrientation()
// Some transforms are equivalent, like rotation 180 + mirror X = mirror Y
static ORIENT_MIRROR symbols_orientations_list[] =
{
{ SYM_ORIENT_0, 0, 0, 0 },
{ SYM_ORIENT_90, 1, 0, 0 },
{ SYM_ORIENT_180, 2, 0, 0 },
{ SYM_ORIENT_270, 3, 0, 0 },
{ SYM_MIRROR_X + SYM_ORIENT_0, 0, 1, 0 },
{ SYM_MIRROR_X + SYM_ORIENT_90, 1, 1, 0 },
{ SYM_MIRROR_Y, 0, 0, 1 },
{ SYM_MIRROR_X + SYM_ORIENT_270, 3, 1, 0 },
{ SYM_MIRROR_Y + SYM_ORIENT_0, 0, 0, 1 },
{ SYM_MIRROR_Y + SYM_ORIENT_90, 1, 0, 1 },
{ SYM_MIRROR_Y + SYM_ORIENT_180, 2, 0, 1 },
{ SYM_MIRROR_Y + SYM_ORIENT_270, 3, 0, 1 }
};
void OrientAndMirrorSymbolItems( LIB_SYMBOL* aSymbol, int aOrientation )
{
ORIENT_MIRROR o = symbols_orientations_list[ 0 ];
for( ORIENT_MIRROR& i : symbols_orientations_list )
{
if( i.flag == aOrientation )
{
o = i;
break;
}
}
for( LIB_ITEM& item : aSymbol->GetDrawItems() )
{
for( int i = 0; i < o.n_rots; i++ )
item.Rotate( VECTOR2I( 0, 0 ), true );
if( o.mirror_x )
item.MirrorVertical( VECTOR2I( 0, 0 ) );
if( o.mirror_y )
item.MirrorHorizontal( VECTOR2I( 0, 0 ) );
}
}
// Rotate and/or mirror a SCH_PIN according to aOrientMirror.
// aOrientMirror is the orientation/mirror of the parent symbol.
// The modified pin orientation is the actual pin orientation/mirror
// when the parent symbol is drawn.
void RotateAndMirrorPin( LIB_PIN& aPin, int aOrientMirror )
{
ORIENT_MIRROR o = symbols_orientations_list[ 0 ];
for( ORIENT_MIRROR& i : symbols_orientations_list )
{
if( i.flag == aOrientMirror )
{
o = i;
break;
}
}
for( int i = 0; i < o.n_rots; i++ )
aPin.Rotate( VECTOR2I( 0, 0 ), true );
if( o.mirror_x )
aPin.MirrorVertical( VECTOR2I( 0, 0 ) );
if( o.mirror_y )
aPin.MirrorHorizontal( VECTOR2I( 0, 0 ) );
}
+42
View File
@@ -0,0 +1,42 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Author Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
class LIB_SYMBOL;
class LIB_PIN;
/**
* Rotate and/or mirror graphic objects of LIB_SYMBOL aSymbol according to aOrientMirror.
* @param aLibSymbol is the LIB_SYMBOL to modify
* @param aOrientation is the orientation+mirror value like returned by SCH_SYMBOL::GetOrientation()
*/
void OrientAndMirrorSymbolItems( LIB_SYMBOL* aLibSymbol, int aOrientation );
/**
* Rotate and/or mirror a SCH_PIN according to aOrientMirror.
* aOrientMirror is usually the orientation/mirror of the parent symbol.
* The modified pin orientation is the actual pin orientation/mirror
* when the parent symbol is drawn.
* @param aPin is the SCH_PIN to modify
* @param aOrientation is the orientation+mirror value like returned by SCH_SYMBOL::GetOrientation()
*/
void RotateAndMirrorPin( LIB_PIN& aPin, int aOrientMirror );
+1 -1
View File
@@ -1282,7 +1282,7 @@ void SYMBOL_EDIT_FRAME::UpdateSymbolMsgPanelInfo()
else if( m_bodyStyle == LIB_ITEM::BODY_STYLE::BASE )
msg = _( "Standard" );
else
wxT( "?" );
msg = wxT( "?" );
AppendMsgPanel( _( "Body" ), msg, 8 );
+2 -3
View File
@@ -359,10 +359,9 @@ SYMBOL_LIB_TABLE_ROW* SYMBOL_LIB_TABLE::FindRow( const wxString& aNickname, bool
// instantiate a PLUGIN of the proper kind if it is not already in this
// SYMBOL_LIB_TABLE_ROW.
if( !row->plugin )
{
row->setPlugin( SCH_IO_MGR::FindPlugin( row->type ) );
row->plugin->SetLibTable( this );
}
row->plugin->SetLibTable( this );
return row;
}
+124 -20
View File
@@ -64,6 +64,7 @@
#include <view/view_controls.h>
#include <wx/log.h>
#include "symb_transforms_utils.h"
SELECTION_CONDITION EE_CONDITIONS::SingleSymbol = []( const SELECTION& aSel )
{
@@ -148,6 +149,12 @@ SELECTION_CONDITION EE_CONDITIONS::AllPins = []( const SELECTION& aSel )
};
SELECTION_CONDITION EE_CONDITIONS::AllPinsOrSheetPins = []( const SELECTION& aSel )
{
return aSel.GetSize() >= 1 && aSel.OnlyContains( { SCH_PIN_T, SCH_SHEET_PIN_T } );
};
#define HITTEST_THRESHOLD_PIXELS 5
@@ -364,6 +371,42 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
KIID lastRolloverItem = niluuid;
EE_GRID_HELPER grid( m_toolMgr );
auto pinOrientation =
[]( EDA_ITEM* aItem )
{
SCH_PIN* pin = dynamic_cast<SCH_PIN*>( aItem );
if( pin )
{
const SCH_SYMBOL* parent = dynamic_cast<const SCH_SYMBOL*>( pin->GetParentSymbol() );
if( !parent )
return pin->GetOrientation();
else
{
LIB_PIN dummy( *pin->GetLibPin() );
RotateAndMirrorPin( dummy, parent->GetOrientation() );
return dummy.GetOrientation();
}
}
SCH_SHEET_PIN* sheetPin = dynamic_cast<SCH_SHEET_PIN*>( aItem );
if( sheetPin )
{
switch( sheetPin->GetSide() )
{
default:
case SHEET_SIDE::LEFT: return PIN_ORIENTATION::PIN_RIGHT;
case SHEET_SIDE::RIGHT: return PIN_ORIENTATION::PIN_LEFT;
case SHEET_SIDE::TOP: return PIN_ORIENTATION::PIN_DOWN;
case SHEET_SIDE::BOTTOM: return PIN_ORIENTATION::PIN_UP;
}
}
return PIN_ORIENTATION::PIN_LEFT;
};
// Main loop: keep receiving events
while( TOOL_EVENT* evt = Wait() )
{
@@ -621,8 +664,11 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
else if( *evt->GetCommandId() >= ID_POPUP_SCH_PIN_TRICKS_START
&& *evt->GetCommandId() <= ID_POPUP_SCH_PIN_TRICKS_END )
{
if( !m_selection.OnlyContains( { SCH_PIN_T } ) || m_selection.Empty() )
if( !m_selection.OnlyContains( { SCH_PIN_T, SCH_SHEET_PIN_T } )
|| m_selection.Empty() )
{
return 0;
}
// Keep track of new items so we make them the new selection at the end
EDA_ITEMS newItems;
@@ -632,8 +678,7 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
{
for( EDA_ITEM* item : m_selection )
{
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
SCH_NO_CONNECT* nc = new SCH_NO_CONNECT( pin->GetPosition() );
SCH_NO_CONNECT* nc = new SCH_NO_CONNECT( item->GetPosition() );
commit.Add( nc, m_frame->GetScreen() );
newItems.push_back( nc );
}
@@ -647,14 +692,13 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
for( EDA_ITEM* item : m_selection )
{
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
SCH_LINE* wire = new SCH_LINE( pin->GetPosition(), LAYER_WIRE );
SCH_LINE* wire = new SCH_LINE( item->GetPosition(), LAYER_WIRE );
// Add some length to the wire as nothing in our code base handles
// 0 length wires very well, least of all the ortho drag algorithm
VECTOR2I stub;
switch( pin->GetOrientation() )
switch( pinOrientation( item ) )
{
case PIN_ORIENTATION::PIN_LEFT:
stub = VECTOR2I( 1 * wireGrid.x, 0 );
@@ -670,7 +714,7 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
break;
}
wire->SetEndPoint( pin->GetPosition() + stub );
wire->SetEndPoint( item->GetPosition() + stub );
m_frame->AddToScreen( wire, m_frame->GetScreen() );
commit.Added( wire, m_frame->GetScreen() );
@@ -702,24 +746,33 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
// selected by the user
for( EDA_ITEM* item : m_selection )
{
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
SCH_PIN* pin = dynamic_cast<SCH_PIN*>( item );
SCH_SHEET_PIN* sheetPin = dynamic_cast<SCH_SHEET_PIN*>( item );
SCH_EDIT_FRAME* sf = dynamic_cast<SCH_EDIT_FRAME*>( m_frame );
SCH_LABEL_BASE* label = nullptr;
wxString labelText;
if( pin )
labelText = pin->GetShownName();
else if( sheetPin && sf )
labelText = sheetPin->GetShownText( &sf->GetCurrentSheet(), false );
switch( *evt->GetCommandId() )
{
case ID_POPUP_SCH_PIN_TRICKS_NET_LABEL:
label = new SCH_LABEL( pin->GetPosition(), pin->GetShownName() );
label = new SCH_LABEL( item->GetPosition(), labelText );
break;
case ID_POPUP_SCH_PIN_TRICKS_HIER_LABEL:
label = new SCH_HIERLABEL( pin->GetPosition(), pin->GetShownName() );
label = new SCH_HIERLABEL( item->GetPosition(), labelText );
break;
case ID_POPUP_SCH_PIN_TRICKS_GLOBAL_LABEL:
label = new SCH_GLOBALLABEL( pin->GetPosition(), pin->GetShownName() );
label = new SCH_GLOBALLABEL( item->GetPosition(), labelText );
break;
default: continue;
}
switch( pin->GetOrientation() )
switch( pinOrientation( item ) )
{
case PIN_ORIENTATION::PIN_LEFT:
label->SetSpinStyle( SPIN_STYLE::SPIN::RIGHT );
@@ -735,7 +788,25 @@ int EE_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
break;
}
switch( pin->GetType() )
ELECTRICAL_PINTYPE pinType = ELECTRICAL_PINTYPE::PT_UNSPECIFIED;
if( pin )
{
pinType = pin->GetType();
}
else if( sheetPin )
{
switch( sheetPin->GetLabelShape() )
{
case LABEL_INPUT: pinType = ELECTRICAL_PINTYPE::PT_INPUT; break;
case LABEL_OUTPUT: pinType = ELECTRICAL_PINTYPE::PT_OUTPUT; break;
case LABEL_BIDI: pinType = ELECTRICAL_PINTYPE::PT_BIDI; break;
case LABEL_TRISTATE: pinType = ELECTRICAL_PINTYPE::PT_TRISTATE; break;
case LABEL_PASSIVE: pinType = ELECTRICAL_PINTYPE::PT_PASSIVE; break;
}
}
switch( pinType )
{
case ELECTRICAL_PINTYPE::PT_BIDI:
label->SetShape( LABEL_FLAG_SHAPE::L_BIDI );
@@ -953,6 +1024,19 @@ OPT_TOOL_EVENT EE_SELECTION_TOOL::autostartEvent( TOOL_EVENT* aEvent, EE_GRID_HE
if( possibleConnection.IsBus() )
newEvt = EE_ACTIONS::drawBus.MakeEvent();
}
else if( aItem->Type() == SCH_SYMBOL_T )
{
const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( aItem );
wxCHECK( symbol, OPT_TOOL_EVENT() );
const SCH_PIN* pin = symbol->GetPin( pos );
wxCHECK( pin, OPT_TOOL_EVENT() );
if( !pin->IsVisible() && !m_frame->eeconfig()->m_Appearance.show_hidden_pins )
return OPT_TOOL_EVENT();
}
newEvt->SetMousePosition( pos );
newEvt->SetHasPosition( true );
@@ -1354,8 +1438,14 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
}
else
{
if( m_frame->GetRenderSettings()->m_ShowPinsElectricalType )
item->SetFlags( SHOW_ELEC_TYPE );
if( item->HitTest( aPos, 0 ) )
exactHits.insert( item );
item->ClearFlags( SHOW_ELEC_TYPE );
}
}
@@ -1382,6 +1472,11 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
BOX2I bbox = item->GetBoundingBox();
int dist = INT_MAX / 4;
// A dominating item is one that would unfairly win distance tests
// and mask out other items. For example, a filled rectangle "wins"
// with a zero distance over anything inside it.
bool dominating = false;
if( exactHits.count( item ) )
{
if( item->Type() == SCH_PIN_T || item->Type() == SCH_JUNCTION_T )
@@ -1438,6 +1533,9 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
delete s;
}
// Filled shapes win hit tests anywhere inside them
dominating = shape->IsFilled();
}
else if( symbol )
{
@@ -1461,15 +1559,21 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
rect.Collide( poss, collector.m_Threshold, &dist );
}
if( dist == closestDist )
// Don't promote dominating items to be the closest item
// (they'll always win) - they'll still be available for selection, but they
// won't boot out worthy competitors.
if ( !dominating )
{
if( item->GetParent() == closest )
if( dist == closestDist )
{
if( item->GetParent() == closest )
closest = item;
}
else if( dist < closestDist )
{
closestDist = dist;
closest = item;
}
else if( dist < closestDist )
{
closestDist = dist;
closest = item;
}
}
}
+1
View File
@@ -54,6 +54,7 @@ public:
static SELECTION_CONDITION SingleNonExcludedMarker;
static SELECTION_CONDITION MultipleSymbolsOrPower;
static SELECTION_CONDITION AllPins;
static SELECTION_CONDITION AllPinsOrSheetPins;
};
+9 -6
View File
@@ -308,7 +308,13 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
SYMBOL_LIB_TABLE* libs = PROJECT_SCH::SchSymbolLibTable( &m_frame->Prj() );
SYMBOL_LIB* cache = PROJECT_SCH::SchLibs( &m_frame->Prj() )->GetCacheLibrary();
std::vector<LIB_SYMBOL*> part_list;
auto compareByLibID =
[]( const LIB_SYMBOL* aFirst, const LIB_SYMBOL* aSecond ) -> bool
{
return aFirst->LibId().Format() < aSecond->LibId().Format();
};
std::set<LIB_SYMBOL*, decltype( compareByLibID )> part_list( compareByLibID );
for( SCH_SHEET_PATH& sheet : sheets )
{
@@ -321,15 +327,12 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
LIB_SYMBOL* libSymbol = SchGetLibSymbol( s->GetLibId(), libs, cache );
if( libSymbol )
part_list.push_back( libSymbol );
part_list.insert( libSymbol );
}
}
// Remove redundant parts
sort( part_list.begin(), part_list.end() );
part_list.erase( unique( part_list.begin(), part_list.end() ), part_list.end() );
std::vector<PICKED_SYMBOL> alreadyPlaced;
for( LIB_SYMBOL* libSymbol : part_list )
{
PICKED_SYMBOL pickedSymbol;
+39 -33
View File
@@ -189,10 +189,11 @@ private:
EE_SELECTION_TOOL* selTool = getToolManager()->GetTool<EE_SELECTION_TOOL>();
EE_SELECTION& selection = selTool->GetSelection();
SCH_PIN* pin = dynamic_cast<SCH_PIN*>( selection.Front() );
SCH_SHEET_PIN* sheetPin = dynamic_cast<SCH_SHEET_PIN*>( selection.Front() );
Clear();
if( !pin )
if( !pin && !sheetPin )
return;
Add( _( "Wire" ), ID_POPUP_SCH_PIN_TRICKS_WIRE, BITMAPS::add_line );
@@ -578,7 +579,7 @@ bool SCH_EDIT_TOOL::Init()
selToolMenu.AddMenu( makeSymbolUnitMenu( m_selectionTool ), E_C::SingleMultiUnitSymbol, 1 );
selToolMenu.AddMenu( makePinFunctionMenu( m_selectionTool ), E_C::SingleMultiFunctionPin, 1 );
selToolMenu.AddMenu( makePinTricksMenu( m_selectionTool ), E_C::AllPins, 1 );
selToolMenu.AddMenu( makePinTricksMenu( m_selectionTool ), E_C::AllPinsOrSheetPins, 1 );
selToolMenu.AddMenu( makeTransformMenu(), orientCondition, 200 );
selToolMenu.AddMenu( makeAttributesMenu(), E_C::HasType( SCH_SYMBOL_T ), 200 );
@@ -1556,14 +1557,7 @@ void SCH_EDIT_TOOL::editFieldText( SCH_FIELD* aField )
int SCH_EDIT_TOOL::EditField( const TOOL_EVENT& aEvent )
{
EE_SELECTION sel;
if( aEvent.IsAction( &EE_ACTIONS::editReference ) )
sel = m_selectionTool->RequestSelection( { SCH_FIELD_LOCATE_REFERENCE_T, SCH_SYMBOL_T } );
else if( aEvent.IsAction( &EE_ACTIONS::editValue ) )
sel = m_selectionTool->RequestSelection( { SCH_FIELD_LOCATE_VALUE_T, SCH_SYMBOL_T } );
else if( aEvent.IsAction( &EE_ACTIONS::editFootprint ) )
sel = m_selectionTool->RequestSelection( { SCH_FIELD_LOCATE_FOOTPRINT_T, SCH_SYMBOL_T } );
EE_SELECTION sel = m_selectionTool->RequestSelection( { SCH_FIELD_T, SCH_SYMBOL_T } );
if( sel.Size() != 1 )
return 0;
@@ -1571,6 +1565,20 @@ int SCH_EDIT_TOOL::EditField( const TOOL_EVENT& aEvent )
bool clearSelection = sel.IsHover();
EDA_ITEM* item = sel.Front();
if( item->Type() == SCH_FIELD_T )
{
SCH_FIELD* field = static_cast<SCH_FIELD*>( item );
if( ( aEvent.IsAction( &EE_ACTIONS::editReference ) && field->GetId() != REFERENCE_FIELD )
|| ( aEvent.IsAction( &EE_ACTIONS::editValue ) && field->GetId() != VALUE_FIELD )
|| ( aEvent.IsAction( &EE_ACTIONS::editFootprint ) && field->GetId() != FOOTPRINT_FIELD ) )
{
item = field->GetParent();
m_selectionTool->ClearSelection( true );
m_selectionTool->AddItemToSel( item );
}
}
if( item->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( item );
@@ -1783,37 +1791,35 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
}
else if( retval == SYMBOL_PROPS_EDIT_SCHEMATIC_SYMBOL )
{
auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR,
true );
if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, true ) )
{
SYMBOL_EDIT_FRAME* editor = static_cast<SYMBOL_EDIT_FRAME*>( frame );
wxCHECK( editor, 0 );
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
// The broken library symbol link indicator cannot be edited.
if( symbol->IsMissingLibSymbol() )
return 0;
// The broken library symbol link indicator cannot be edited.
if( symbol->IsMissingLibSymbol() )
return 0;
editor->LoadSymbolFromSchematic( symbol );
editor->Show( true );
editor->Raise();
editor->LoadSymbolFromSchematic( symbol );
editor->Show( true );
editor->Raise();
}
}
else if( retval == SYMBOL_PROPS_EDIT_LIBRARY_SYMBOL )
{
auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR,
true );
if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR, true ) )
{
SYMBOL_EDIT_FRAME* editor = static_cast<SYMBOL_EDIT_FRAME*>( frame );
wxCHECK( editor, 0 );
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetBodyStyle() );
editor->Show( true );
editor->Raise();
editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetBodyStyle() );
editor->Show( true );
editor->Raise();
}
}
else if( retval == SYMBOL_PROPS_WANT_UPDATE_SYMBOL )
{
+2 -2
View File
@@ -536,8 +536,8 @@ int SCH_EDITOR_CONTROL::ExportSymbolsToLibrary( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
{
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
SIMULATOR_FRAME* simFrame = (SIMULATOR_FRAME*) m_frame->Kiway().Player( FRAME_SIMULATOR,
false );
KIWAY_PLAYER* player = m_frame->Kiway().Player( FRAME_SIMULATOR, false );
SIMULATOR_FRAME* simFrame = static_cast<SIMULATOR_FRAME*>( player );
if( !simFrame ) // Defensive coding; shouldn't happen.
return 0;
+37 -2
View File
@@ -142,6 +142,18 @@ void SCH_MOVE_TOOL::orthoLineDrag( SCH_COMMIT* aCommit, SCH_LINE* line, const VE
foundPin = true;
break;
case SCH_SHEET_T:
for( const auto& pair : m_specialCaseSheetPins )
{
if( pair.first->IsConnected( selectedEnd ) )
{
foundPin = true;
break;
}
}
break;
default:
break;
}
@@ -1100,11 +1112,17 @@ void SCH_MOVE_TOOL::getConnectedItems( SCH_ITEM* aOriginalItem, const VECTOR2I&
for( SCH_SHEET_PIN* pin : static_cast<SCH_SHEET*>( test )->GetPins() )
{
if( pin->IsConnected( aPoint ) )
m_specialCaseSheetPins[ pin ] = { line, line->GetStartPoint() == aPoint };
{
if( pin->IsSelected() )
m_specialCaseSheetPins[pin] = { line,
line->GetStartPoint() == aPoint };
aList.push_back( pin );
}
}
}
KI_FALLTHROUGH;
break;
case SCH_SYMBOL_T:
case SCH_JUNCTION_T:
@@ -1210,6 +1228,22 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_COMMIT* aCommit, SCH_ITEM* aSelec
for( SCH_ITEM* item : itemsOverlappingRTree )
{
if( item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
{
if( !pin->IsSelected() && pin->GetPosition() == aSelectedItem->GetPosition()
&& pin->CanConnect( aSelectedItem ) )
{
itemsConnectable.push_back( pin );
}
}
continue;
}
// Skip ourselves, skip already selected items (but not lines, they need both ends tested)
// and skip unconnectable items
if( item == aSelectedItem || ( item->Type() != SCH_LINE_T && item->IsSelected() )
@@ -1404,6 +1438,7 @@ void SCH_MOVE_TOOL::getConnectedDragItems( SCH_COMMIT* aCommit, SCH_ITEM* aSelec
case SCH_GLOBAL_LABEL_T:
case SCH_HIER_LABEL_T:
case SCH_DIRECTIVE_LABEL_T:
case SCH_SHEET_PIN_T:
// Performance optimization:
if( test->HasFlag( SELECTED_BY_DRAG ) )
break;
+1 -1
View File
@@ -211,7 +211,7 @@ int SIMULATOR_CONTROL::ExportPlotAsCSV( const TOOL_EVENT& aEvent )
out.Write( wxString::Format( wxT( "%s%c" ), xAxisName, SEPARATOR ) );
for( const auto& [name, trace] : traces )
out.Write( wxString::Format( wxT( "%s%c" ), name, SEPARATOR ) );
out.Write( wxString::Format( wxT( "%s%c" ), trace->GetDisplayName(), SEPARATOR ) );
out.Write( wxS( "\r\n" ) );
+3 -3
View File
@@ -172,8 +172,8 @@ int SYMBOL_EDITOR_CONTROL::AddSymbol( const TOOL_EVENT& aEvent )
{
SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
LIB_ID sel = editFrame->GetTreeLIBID();
const wxString& libName = sel.GetLibNickname();
LIB_ID target = editFrame->GetTargetLibId();
const wxString& libName = target.GetLibNickname();
wxString msg;
if( libName.IsEmpty() )
@@ -196,7 +196,7 @@ int SYMBOL_EDITOR_CONTROL::AddSymbol( const TOOL_EVENT& aEvent )
}
else if( aEvent.IsAction( &EE_ACTIONS::deriveFromExistingSymbol ) )
{
editFrame->CreateNewSymbol( sel.GetLibItemName() );
editFrame->CreateNewSymbol( target.GetLibItemName() );
}
else if( aEvent.IsAction( &EE_ACTIONS::importSymbol ) )
{
+8 -8
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
* 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
@@ -220,7 +220,7 @@ PANEL_SYMBOL_CHOOSER::PANEL_SYMBOL_CHOOSER( SCH_BASE_FRAME* aFrame, wxWindow* aP
detailsPanel->SetSizer( detailsSizer );
m_details = new HTML_WINDOW( detailsPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize );
detailsSizer->Add( m_details, 1, wxEXPAND, 5 );
detailsSizer->Add( m_details, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
detailsPanel->Layout();
detailsSizer->Fit( detailsPanel );
@@ -228,7 +228,7 @@ PANEL_SYMBOL_CHOOSER::PANEL_SYMBOL_CHOOSER( SCH_BASE_FRAME* aFrame, wxWindow* aP
m_vsplitter->SetMinimumPaneSize( 20 );
m_vsplitter->SplitHorizontally( m_hsplitter, detailsPanel );
sizer->Add( m_vsplitter, 1, wxEXPAND, 5 );
sizer->Add( m_vsplitter, 1, wxEXPAND | wxBOTTOM, 5 );
}
wxPanel* treePanel = new wxPanel( m_hsplitter );
@@ -238,7 +238,7 @@ PANEL_SYMBOL_CHOOSER::PANEL_SYMBOL_CHOOSER( SCH_BASE_FRAME* aFrame, wxWindow* aP
m_tree = new LIB_TREE( treePanel, m_showPower ? wxT( "power" ) : wxT( "symbols" ),
libs, m_adapter, LIB_TREE::FLAGS::ALL_WIDGETS, m_details );
treeSizer->Add( m_tree, 1, wxEXPAND, 5 );
treeSizer->Add( m_tree, 1, wxALL | wxEXPAND, 5 );
treePanel->Layout();
treeSizer->Fit( treePanel );
@@ -385,7 +385,7 @@ wxPanel* PANEL_SYMBOL_CHOOSER::constructRightPanel( wxWindow* aParent )
{
FOOTPRINT_LIST* fp_list = FOOTPRINT_LIST::GetInstance( m_frame->Kiway() );
sizer->Add( m_symbol_preview, 11, wxEXPAND | wxBOTTOM, 5 );
sizer->Add( m_symbol_preview, 11, wxEXPAND | wxALL, 5 );
if ( fp_list )
{
@@ -397,14 +397,14 @@ wxPanel* PANEL_SYMBOL_CHOOSER::constructRightPanel( wxWindow* aParent )
}
if( m_fp_sel_ctrl )
sizer->Add( m_fp_sel_ctrl, 0, wxEXPAND | wxTOP | wxBOTTOM, 4 );
sizer->Add( m_fp_sel_ctrl, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
if( m_fp_preview )
sizer->Add( m_fp_preview, 10, wxEXPAND, 5 );
sizer->Add( m_fp_preview, 10, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
}
else
{
sizer->Add( m_symbol_preview, 1, wxEXPAND, 5 );
sizer->Add( m_symbol_preview, 1, wxEXPAND | wxALL, 5 );
}
panel->SetSizer( sizer );
+4 -5
View File
@@ -115,11 +115,6 @@ void SCH_PROPERTIES_PANEL::AfterCommit()
const SELECTION& selection = selectionTool->GetSelection();
rebuildProperties( selection );
CallAfter( [this]()
{
m_frame->GetCanvas()->SetFocus();
} );
}
@@ -175,6 +170,8 @@ void SCH_PROPERTIES_PANEL::valueChanging( wxPropertyGridEvent& aEvent )
aEvent.Veto();
return;
}
aEvent.Skip();
}
@@ -204,6 +201,8 @@ void SCH_PROPERTIES_PANEL::valueChanged( wxPropertyGridEvent& aEvent )
// Perform grid updates as necessary based on value change
AfterCommit();
aEvent.Skip();
}
+3
View File
@@ -877,7 +877,10 @@ void GERBVIEW_FRAME::SetActiveLayer( int aLayer, bool doLayerWidgetUpdate )
UpdateXORLayers();
if( doLayerWidgetUpdate )
{
m_LayersManager->SelectLayer( aLayer );
m_LayersManager->OnLayerSelected();
}
UpdateTitleAndInfo();
+5
View File
@@ -371,6 +371,11 @@ public:
int aClearance, int aError, ERROR_LOC aErrorLoc,
bool ignoreLineWidth = false ) const;
enum COMPARE_FLAGS : int
{
DRC = 0x01
};
struct ptr_cmp
{
bool operator() ( const BOARD_ITEM* a, const BOARD_ITEM* b ) const;
+5
View File
@@ -104,6 +104,11 @@ KICOMMON_API const std::tuple<int, int, int>& GetMajorMinorPatchTuple();
*/
KICOMMON_API bool IsNightlyVersion();
/**
* A setter for OpenGL info when it's initialized.
*/
KICOMMON_API void SetOpenGLInfo( const char* aRenderer, const char* aVendor, const char* aVersion );
/**
* Create a version info string for bug reports and the about dialog
* @param aTitle is the application title to include at the top of the report
+2
View File
@@ -96,6 +96,8 @@ private:
std::string columnsFor( const std::string& aTable );
bool selectAllAndCache( const std::string& aTable, const std::string& aKey );
std::unique_ptr<nanodbc::connection> m_conn;
std::string m_dsn;
+12
View File
@@ -145,6 +145,18 @@ public:
m_endsSwapped = false;
}
void SetCenterY( int y )
{
m_end.y += y - m_start.y;
m_start.y = y;
}
void SetCenterX( int x )
{
m_end.x += x - m_start.x;
m_start.x = x;
}
/**
* Return the ending point of the graphic.
*/
+2 -1
View File
@@ -348,7 +348,8 @@ public:
const VECTOR2I& aOffset = { 0, 0 } ) const;
// Support for reading the cache from disk.
void SetupRenderCache( const wxString& aResolvedText, const EDA_ANGLE& aAngle );
void SetupRenderCache( const wxString& aResolvedText, const KIFONT::FONT* aFont,
const EDA_ANGLE& aAngle, const VECTOR2I& aOffset );
void AddRenderCacheGlyph( const SHAPE_POLY_SET& aPoly );
int Compare( const EDA_TEXT* aOther ) const;

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