Compare commits

..

136 Commits

Author SHA1 Message Date
Seth Hillbrand 2bc8c0ace5 Fix Eeschema Find/Replace
Find/Replace skipped elements that were inside the same symbol,
preventing a full search of the schematic.
2023-03-09 11:51:29 -08:00
jean-pierre charras f439dfb6ea Pcb editor: fix crash when trying to activate the "place anchor" tool.
"place anchor" tool exists only in the Fp editor. However, the hotkey
to activate this tool was also active in the board editor. Now disabled.
From master branch.
2023-02-09 16:58:54 +01:00
Wayne Stambaugh 9fdc1257a1 Fix broken update symbol from library.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13782

(cherry picked from commit baeeeec492)
2023-02-05 11:01:29 -05:00
Wayne Stambaugh 95828ff2e2 Use references instead of copies in map pair for loops. 2023-02-03 10:04:08 -05:00
jean-pierre charras 98e55c0a04 Fix compatibility with older wxWidgets versions. 2023-02-02 20:38:51 +01:00
Wayne Stambaugh 2757d81231 Fix schematic update library symbols issues.
Rather than update library symbols one at a time, queue them up by
schematic symbol to prevent multiple updates to the same symbol in
complex hierarchies.  This also removes all of the library symbols
first which will clear out all of the library symbol variants that
were created by modifying library symbols in place and/or changes to
the symbol in the library.

Don't add new variant library symbol if an equivalent variant already
exists in the schematic local cache.  This prevents duplicate library
symbols from being added to the local cache when the first variant in
the cache does not match that of the symbol being added.
2023-02-02 12:54:08 -05:00
Wayne Stambaugh 985ceb365b Begin 6.0.12 development.
Note: There should not be a 6.0.12 but we said that about 6.0.11.  We
      want to keep the 6.0 branch alive for testing builds for any
      lingering critical bugs until 7.0.0 is released.
2023-02-02 12:45:36 -05:00
Wayne Stambaugh cdf04d5582 Tag release version 6.0.11. 2023-01-24 16:08:09 -05:00
Seth Hillbrand a1ff9134f4 Don't double-tap Connectivity Recalculate
Cherry-picked from 43e4797d4d
2023-01-24 10:35:42 -08:00
Marek Roszko cc0b51c81a Ensure glew is initialized in the 3d model viewer
Fixes KICAD-7M


(cherry picked from commit b3f55e7f8b)
2023-01-24 12:15:13 +00:00
Seth Hillbrand 4e34bdb621 Force realtime connectivity on
The pressure relief valve was not useful for common work patterns as it
forced the recalculation on many common actions such as bus expansion.
This caused it to actually feel slower than with the pressure relief
valve off.

For most schematics, realtime is now fast enough to not need the valve
and for those that are extremely complex, removing the valve helps this
run more predictably

(cherry picked from commit e6dbca051c)
2023-01-23 11:11:48 -08:00
Seth Hillbrand 6d96059917 Fix compile error 2023-01-23 10:47:23 -08:00
Seth Hillbrand 99cfa1fad7 Avoid the obsolete GetNextPin() call
This iterated over all pins to find the pin after a given item.  Because
out pattern is consistently to iterate in the outer loop, this means
that we were an O(n^2) loop for the pins just to find their names.  This
affected very large parts (e.g. FPGAs) when switching sheets to display

(cherry picked from commit 6fa2eedb4b)
2023-01-23 10:46:07 -08:00
Seth Hillbrand b2a6f12645 Don't do a full connection database reset on HardRedraw()
Only update the intersheet references to avoid the penalty of
connectivity re-calculations on each redraw

Cherry-picked from b8ee588a76 and 08c2828bd3
2023-01-23 10:28:29 -08:00
Wayne Stambaugh b33cf23bda Fix library symbol rescue issues.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13602

(cherry picked from commit 0a7bd85cd6)
2023-01-21 11:21:38 -05:00
Steven Falco 5a36c3685e Fix GCC 13 build error.
GCC removed the cstdint header from many other headers, so we can't rely on transitive includes to define these types. This led to a compile error in this file due to no more transitive inclusion.
2023-01-20 21:13:34 +00:00
Seth Hillbrand 5991842ae4 Place hidden PDF text behind words better
Rather than hiding a single line at once, we align each word in the
string with the approximate location of the output word.  This allows
better selecting text in the output pdf

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

(cherry picked from commit da1707d5ba)
2023-01-20 11:15:28 -08:00
Mark Roszko 6c0a30e2f3 Pin curl to the older curl that works 2023-01-19 12:24:55 +00:00
Wayne Stambaugh c0eee45876 Fix another broken graphics import file filter.
(cherry picked from commit 022c913e8f)
2023-01-17 11:43:34 -05:00
Wayne Stambaugh 6ebd970f88 Fix broken graphics import file filters.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13570

(cherry picked from commit f81642bbb3)
2023-01-17 11:27:25 -05:00
Seth Hillbrand 5e3b74aee5 Fix name escaping in Save As
Fixes https://gitlab.com/kicad/code/kicad/issues/13504
2023-01-12 13:34:14 -08:00
jean-pierre charras 316087c468 Protect against null pointer use.
Fixes #13349
https://gitlab.com/kicad/code/kicad/issues/13349
2023-01-02 18:00:18 +01:00
jean-pierre charras 1b1586696f Do not prune items/layers when copying the clipboard to the FP editor: all are allowed
(Some are disabled only for GUI)
Fixes #13334
https://gitlab.com/kicad/code/kicad/issues/13334
2023-01-01 13:39:41 +01:00
Mark Roszko 339a349a58 Fix doxygen output path for copy 2023-01-01 00:14:27 +00:00
Mark Roszko 1a161858fc Add the doxygen dockerfile 2022-12-31 21:43:31 +00:00
Marco Ciampa 12abcd6ece Updated Italian translation 2022-12-30 17:59:16 +01:00
Marco Ciampa 5e64fb1415 Updated Italian translation 2022-12-29 14:41:54 +01:00
Marco Ciampa 7616461e61 Small fix in Italian translation 2022-12-28 09:39:57 +01:00
Jon Evans 968406c6b5 KiWay: Make sure to mark closed windows as closed
Also make sure to veto project import if we couldn't close the existing project.

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

Maybe also fixes some other weird crashes, we'll see.


(cherry picked from commit 7e778c9856)
2022-12-27 15:32:34 +00:00
Jon Evans 5144186fca Fix c0fb041b for old API 2022-12-27 08:33:40 -05:00
Jon Evans c0fb041be6 No-connects might not be connected to a pin
Fixes https://gitlab.com/kicad/code/kicad/-/issues/13256

(cherry picked from commit 5657ca5a04)
2022-12-27 08:14:43 -05:00
Wayne Stambaugh 45e15f2394 Begin 6.0.11 development.
Note: there should not be a 6.0.11 but we want to keep the 6.0 branch
      alive for testing builds for any lingering critical bugs until
      7.0.0 is released.
2022-12-26 13:51:17 -05:00
Marco Ciampa f5b592e38c Updated Italian translation 2022-12-19 14:12:46 +01:00
Marco Ciampa 60a8eee515 Updated Italian translation 2022-12-18 11:47:10 +01:00
Wayne Stambaugh 38e09789e5 Tag release version 6.0.10. 2022-12-17 17:12:38 -05:00
Seth Hillbrand f993e51fba Update translations 2022-12-17 11:14:38 -08:00
Neko Nekowazarashi 7600f45d11 Translated using Weblate (Indonesian)
Currently translated at 24.7% (1769 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/id/
2022-12-17 20:13:43 +01:00
Ulices 48d8c149a8 Translated using Weblate (Spanish (Mexico))
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es_MX/
2022-12-17 20:13:43 +01:00
Henrik Kauhanen 131115e19f Translated using Weblate (Swedish)
Currently translated at 99.9% (7152 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-12-17 20:13:43 +01:00
jean-pierre charras cd7cab9794 SHAPE_ARC::GetCentralAngle(): ensure a 360 deg arc angle is always returned as 360 deg.
An arc having the same start and end points can be 0 or 360 deg arc.
In Kicad it is always 360 deg arc (i.e. a circle)
Fixes #13182
https://gitlab.com/kicad/code/kicad/issues/13182
2022-12-17 14:47:26 +01:00
Wayne Stambaugh 22bece0922 Schematic import bug fix.
Check for already loaded schematics in the current sheet path as well
as the current project root sheet path to prevent multiple loads of
shared schematic.  This bug was causing shared sheets to be loaded more
than once which caused instance data to get separated by each copy rather
than saved in one copy of the schematic which would result in all instance
data being lost except the last saved copy of the schematic.  This bug has
been around forever and may be the cause of some unexplained schematic
instance data corruption issues.  This bug does not apply when opening
the full project.

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

(cherry picked from commit 84f927d057)
2022-12-15 11:44:59 -05:00
Mark Roszko 01cff24e4e vcpkg bump to ngspice 38 2022-12-15 03:02:55 +00:00
Seth Hillbrand 948071183c Don't report a pin if the pin is null
The pins can exist on a different sheet from the no-connect.  In this
case, we do not set the ERC for the current sheet to the remote pins,
instead only link the NC

(cherry picked from commit bc8366cd95)
2022-12-12 19:31:20 -08:00
Seth Hillbrand ee05b67599 Fix crash when moving empty selection
Need to pop the move tool when exiting, even at the beginning

Fixes https://gitlab.com/kicad/code/kicad/issues/13114
2022-12-12 12:59:31 -08:00
Seth Hillbrand c07043e762 Respect the "report all errors" checkbox
When we have objects spanning multiple layers, the user doesn't need to
see every layer/hole combination violation if they do not request it
2022-12-12 10:53:44 -08:00
Alex bd9c37aa5f Fix an incorrect calculation in length tuning tools.
MEANDER_PLACER_BASE::lineLength wasn't calculating the length correctly
when starting and ending pads were on different layers.

Naturally, now jointA corresponds to the start of the path, jointB to the end.

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


(cherry picked from commit 348c3d4216)
2022-12-12 01:58:36 +00:00
Alex 6e6a748320 Use correct pad to die lengths in DP length tuner.
Fixes https://gitlab.com/kicad/code/kicad/issues/12859


(cherry picked from commit 126914859a)
2022-12-12 01:58:13 +00:00
Seth Hillbrand 61c0cac22d Update translations 2022-12-11 12:20:46 -08:00
ZbeeGin 3c973a788d Translated using Weblate (Polish)
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pl/
2022-12-11 21:19:38 +01:00
Mark Hämmerling 048436f0ef Translated using Weblate (German)
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-12-11 21:19:38 +01:00
Jan Straka 491e0cac6a Translated using Weblate (Czech)
Currently translated at 93.2% (6676 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-12-11 21:19:38 +01:00
Henrik Kauhanen cf1d0a9667 Translated using Weblate (Swedish)
Currently translated at 99.9% (7150 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-12-11 21:19:38 +01:00
Henrik Kauhanen 3ae39f9614 Translated using Weblate (Finnish)
Currently translated at 99.9% (7154 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-12-11 21:19:38 +01:00
Henrik Kauhanen 45d9a58bc7 Translated using Weblate (Swedish)
Currently translated at 99.8% (7149 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-12-11 21:19:38 +01:00
Hanna Breisand 1a8d974520 Translated using Weblate (Swedish)
Currently translated at 99.8% (7149 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-12-11 21:19:38 +01:00
Sašo Domadenik 8ea00c42d9 Translated using Weblate (Slovenian)
Currently translated at 3.5% (251 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sl/
2022-12-11 21:19:38 +01:00
Toni Laiho be8750ad1c Translated using Weblate (Finnish)
Currently translated at 99.9% (7154 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-12-11 21:19:38 +01:00
Henrik Kauhanen 350d0323e1 Translated using Weblate (Swedish)
Currently translated at 99.8% (7149 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-12-11 21:19:38 +01:00
ZbeeGin 2c7aee057a Translated using Weblate (Polish)
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pl/
2022-12-11 21:19:38 +01:00
Toni Laiho fb6c89358b Translated using Weblate (Finnish)
Currently translated at 99.9% (7154 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-12-11 21:19:38 +01:00
VicSanRoPe d790e85fe4 Translated using Weblate (Spanish)
Currently translated at 99.8% (7149 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es/
2022-12-11 21:19:37 +01:00
Seth Hillbrand 7f08356a48 Fix NC and label logic
Largely moved for v6 instead of direct cherry-pick due to code
differences

cherry-picked from eaf56bc05a
cherry-picked from 9a5df73060
2022-12-11 12:16:33 -08:00
Simon Schaak 045633626c Clean up autosave file handling edge cases
(cherry picked from commit bd74489b00)
2022-12-11 08:48:48 -05:00
Wayne Stambaugh 5de05312d5 Fix wxWidgets 3.2 assertion when opening symbol field table editor. 2022-12-09 15:05:38 -05:00
jean-pierre charras ecfd74c1be symbol_editor_control: fix incorrect bounding in SVG export.
Fixes #13093
https://gitlab.com/kicad/code/kicad/issues/13093
2022-12-07 13:18:10 +01:00
Mark Roszko cdeb539254 Restore windows ci 2022-12-03 13:45:55 +00:00
Marco Ciampa 540c5d2b16 Updated Italian translation 2022-12-02 08:22:14 +01:00
Mark Roszko 38886c998b Disable Windows CI until its fixed 2022-12-01 20:45:38 +00:00
jean-pierre charras 46b3188737 Some fixes related to translated/not translated mandatory field names.
DIALOG_SYMBOL_FIELDS_TABLE: add new fields to symbols only if the field is not empty.

(cherry picked from commit 45b167dff5)
2022-11-30 11:41:08 -08:00
Seth Hillbrand f663b42d77 Remove unused vars 2022-11-30 11:26:48 -08:00
jean-pierre charras 9ac87132af Fix a few issues related to field names and their translation.
- Do not use translated field names outside strings displayed in dialogs.
- fix code that does not work well with default locale.
- fix some (not all) I18n issues in DIALOG_UPDATE_SYMBOL_FIELDS.

(cherry picked from commit 20d1d0705e)
2022-11-30 11:19:21 -08:00
Seth Hillbrand 8af64fb326 Do not allow dimensions in the footprint editor
The object type doesn't exist in 6.0

Fixes https://gitlab.com/kicad/code/kicad/issues/12841
2022-11-30 11:04:15 -08:00
Seth Hillbrand be86e9f57f Prevent UI events during footprint dialog ctor
Errors may get thrown when the 3d models are loaded for missing search
paths.  This triggers the idle event that makes assumptions about the
state of the dialog.  We halt event handling until the ctor finishes.

Fixes https://gitlab.com/kicad/code/kicad/issues/12944
2022-11-29 19:38:48 -08:00
Marek Roszko 3253bd9a3d Update vcpkg baseline
(cherry picked from commit 933b3cf3df)
2022-11-30 01:58:52 +00:00
Seth Hillbrand 994dd570de Update Translations 2022-11-29 17:26:22 -08:00
Toni Laiho c171f5b1b0 Translated using Weblate (Finnish)
Currently translated at 99.9% (7154 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-11-30 02:23:55 +01:00
VicSanRoPe 36bbe733a8 Translated using Weblate (Spanish)
Currently translated at 99.8% (7149 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es/
2022-11-30 02:23:54 +01:00
Mark Hämmerling 3400b567b1 Translated using Weblate (German)
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-11-30 02:23:54 +01:00
Jan Straka 28d6c17e42 Translated using Weblate (Czech)
Currently translated at 93.1% (6665 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-11-30 02:23:54 +01:00
Toni Laiho 0df81f67ed Translated using Weblate (Finnish)
Currently translated at 99.9% (7154 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-11-30 02:23:54 +01:00
Bế Trọng Nghĩa 30f08024b7 Translated using Weblate (Vietnamese)
Currently translated at 17.0% (1219 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/vi/
2022-11-30 02:23:54 +01:00
Håvard Syslak d93364268b Translated using Weblate (Norwegian Bokmål)
Currently translated at 73.2% (5240 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/nb_NO/
2022-11-30 02:23:54 +01:00
VicSanRoPe 11531471c6 Translated using Weblate (Spanish)
Currently translated at 99.6% (7133 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es/
2022-11-30 02:23:54 +01:00
Mark Hämmerling 1626ba3f58 Translated using Weblate (German)
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-11-30 02:23:54 +01:00
Jan Straka 76479f40ef Translated using Weblate (Czech)
Currently translated at 93.1% (6665 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-11-30 02:23:54 +01:00
Mark Hämmerling 4c9e409df9 Translated using Weblate (German)
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-11-30 02:23:53 +01:00
Neko Nekowazarashi b4b4f1f3ca Translated using Weblate (Indonesian)
Currently translated at 24.2% (1737 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/id/
2022-11-30 02:23:53 +01:00
Jan Straka ed684cd92e Translated using Weblate (Czech)
Currently translated at 93.0% (6661 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-11-30 02:23:53 +01:00
aris-kimi 3f99dae704 Translated using Weblate (Greek)
Currently translated at 99.4% (7118 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/el/
2022-11-30 02:23:53 +01:00
Mark Hämmerling 7e72a3c993 Translated using Weblate (German)
Currently translated at 99.9% (7156 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-11-30 02:23:53 +01:00
Michael Misirlis 2960e9c1b4 Translated using Weblate (Greek)
Currently translated at 99.4% (7117 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/el/
2022-11-30 02:23:53 +01:00
Tokita, Hiroshi 0f5e12a535 Translated using Weblate (Japanese)
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-11-30 02:23:53 +01:00
Neko Nekowazarashi acf62122c8 Translated using Weblate (Indonesian)
Currently translated at 24.3% (1745 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/id/
2022-11-30 02:23:53 +01:00
Toni Laiho bf9db4d4f8 Translated using Weblate (Finnish)
Currently translated at 99.9% (7154 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-11-30 02:23:53 +01:00
Mark Hämmerling e09212ccad Translated using Weblate (German)
Currently translated at 99.9% (7156 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-11-30 02:23:52 +01:00
Jan Straka 390effe3c6 Translated using Weblate (Czech)
Currently translated at 93.0% (6661 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-11-30 02:23:52 +01:00
Mark Hämmerling eaafa5d8f0 Translated using Weblate (German)
Currently translated at 99.9% (7156 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-11-30 02:23:52 +01:00
Mark Hämmerling c558144c7b Translated using Weblate (German)
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-11-30 02:23:52 +01:00
Ettore Atalan b7713dbf0d Translated using Weblate (German)
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-11-30 02:23:52 +01:00
Jan Straka 9b21712ea0 Translated using Weblate (Czech)
Currently translated at 92.8% (6648 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/cs/
2022-11-30 02:23:52 +01:00
Arnau Llovet Vidal 6f7b0cb240 Translated using Weblate (Catalan)
Currently translated at 65.6% (4698 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ca/
2022-11-30 02:23:52 +01:00
Toni Laiho ea1aed2fc9 Translated using Weblate (Finnish)
Currently translated at 99.9% (7154 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-11-30 02:23:52 +01:00
ssantos 88ad0e5a50 Translated using Weblate (Portuguese)
Currently translated at 99.9% (7152 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt/
2022-11-30 02:23:52 +01:00
ZbeeGin 15ead17cea Translated using Weblate (Polish)
Currently translated at 100.0% (7157 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pl/
2022-11-30 02:23:52 +01:00
aris-kimi 92356b4805 Translated using Weblate (Greek)
Currently translated at 99.3% (7112 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/el/
2022-11-30 02:23:51 +01:00
Toni Laiho cec810a452 Translated using Weblate (Finnish)
Currently translated at 99.9% (7154 of 7157 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-11-30 02:23:51 +01:00
Jeff Young ec92def539 Add support for unitless values to PCB_EXPR_EVALUATOR.
Fixes https://gitlab.com/kicad/code/kicad/issues/13016

(cherry picked from commit 8260f0ee13)
2022-11-29 23:28:37 +00:00
Jeff Young 2dd04ea43a Protect move tool from re-entrancy.
m_dragInProgress is usually sufficient, except when we haven't started
one yet.  In any case, conflating the two is probably a bad idea.

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

(cherry picked from commit bc271a8d15)
2022-11-29 23:16:48 +00:00
Jeff Young d7a7ddd80e Allow pads in selection and filter them for free-pads later.
Fixes https://gitlab.com/kicad/code/kicad/issues/12912

(cherry picked from commit cefc5268ab)
2022-11-29 23:15:39 +00:00
Jeff Young 27676f4388 Add mapping for -rescue.lib in project Save As.
Fixes https://gitlab.com/kicad/code/kicad/issues/12503

(cherry picked from commit 5366fa8cee)
2022-11-29 23:14:10 +00:00
Jeff Young 2f47857abc Move zone borders back to their "host" layer.
Zone borders shouldn't be affected by zone-opacity control; we always
draw them in full layer opacity.

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

(cherry picked from commit 25f06eed8c)
2022-11-29 23:05:50 +00:00
Jeff Young ede21ed6ae Handle string escaping for Find/Replace in labels.
Fixes https://gitlab.com/kicad/code/kicad/issues/12789

(cherry picked from commit ae9405a4d3)
2022-11-29 22:54:14 +00:00
Jeff Young a09a3dfe68 Be careful of interveneing priority zones when doing divot prevention.
Fixes https://gitlab.com/kicad/code/kicad/issues/12797

(cherry picked from commit 1f4e51b008)
2022-11-29 22:43:41 +00:00
Jeff Young e083cbaf50 Allow a single net collision with a free pad.
(cherry picked from commit 3534cfbba8)
2022-11-29 22:16:15 +00:00
Seth Hillbrand 9d401b00d8 Allow groups in groups
This was allowed in the qa test, so we allow it going forward

(cherry picked from commit 137b4de1c2)
2022-11-28 11:28:51 -08:00
Seth Hillbrand 25e3b6c1bf Ignore generated files 2022-11-28 11:10:16 -08:00
Seth Hillbrand 2029fc4e8f Don't use modifiers when moving with keyboard
The modifier keys on the keyboard control the motion spacing (Ctrl) and
shouldn't be confused with the modifier key used to disable grid
snapping when moving with the mouse (also Ctrl)

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

(cherry picked from commit 4f6b853756)
2022-11-28 11:06:24 -08:00
Seth Hillbrand c9cc29593a Don't add non-groupable items to groups
This is a re-implementation of 259e41be

Fixes https://gitlab.com/kicad/code/kicad/issues/13026
2022-11-28 09:26:48 -08:00
Seth Hillbrand 42bd43407a Remove clone's group info 2022-11-28 09:17:17 -08:00
Seth Hillbrand de05a513f3 Prevent mirror of text elements
While we never allow the creation of mirrored text elements in the
schematic and symbol library editors, external generation of symbols may
cause the property to be set, which can then never be changed.  This
leaves the property unset for all elements

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

(cherry picked from commit f1556ed801)
2022-11-26 10:51:03 -08:00
Seth Hillbrand 554d82b2a4 Ensure that we clear deleted values
When throwing on an invalid value, we may end up freeing the same tree
twice.  This is generally not an issue but we need to mark the freed
memory as null to avoid a double free

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

(cherry picked from commit 62863d6c5b)
2022-11-25 10:47:03 -08:00
Seth Hillbrand 3b3e86b968 Remove structured binding from v6 commit
C++17 is only for the master branch
2022-11-25 10:43:10 -08:00
Seth Hillbrand f6ca98061c Add terrible hack to get subgraph netname
In certain cases, the subgraph does not receive the proper netname,
preventing us from checking for correct pin counts.  This is a backwards
iteration of the net name <-> subgraph map to extract the proper name
and sibling subgraphs

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

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

(cherry picked from commit 938645b29d)
2022-11-25 08:51:12 -08:00
Tomasz Wlostowski cca7f1dbda router: use actual snap point position for routability checks of a segment instead of the segment endpoint(s).
Explanation:
- place a long segment A with something violating the rules close to its endpoint
- try to start routing in the 2/3 of the length of A (on the obstacle side)
- bummer - the router picks the nearest endpoint of A for the collision check (even though we don't care about this collision since we want to route far away from it)

(cherry picked from commit e558893851)
2022-11-23 06:57:11 -08:00
Seth Hillbrand 2cf4cb937f Fix graphic snapping
If the user has requested the ability to snap to graphics, we want to
add any of the graphical layers to the limit list
2022-11-23 06:57:11 -08:00
jean-pierre charras c3b9c65fd6 Gerbview, read zip archive: do not generate a error message for directory names.
A directory is not a file, and is now just skipped.
From master branch
2022-11-22 17:08:18 +01:00
Wayne Stambaugh d9a1703bcc Fix broken schematic instance data loading legacy files (<=5.1). 2022-11-18 10:07:59 -05:00
Wayne Stambaugh a22c466639 Fix broken legacy schematic file save. 2022-11-17 12:23:14 -05:00
Mark Roszko 9a2f83537d Restore missing libxslt 2022-11-15 03:27:48 +00:00
jean-pierre charras f136f3d7ee pcbnew, SVG import: fix an issue for SVG files using a CR+LF end of file
The issue was in a validity test working only if CR+LF is not replaced by LF
Fixes #10096
https://gitlab.com/kicad/code/kicad/issues/10096
2022-11-09 09:36:06 +01:00
Seth Hillbrand 61d4a5bfbe Resolve embedded text vars
Title Block text variables are embedded into the pcb file and should
be used for resolving when the project file is missing

(cherry picked from commit d1bf889e71)
2022-11-03 10:26:06 -07:00
Mike Williams 6289a82a18 PCB Router: return to original active layer after routing
Fixes: https://gitlab.com/kicad/code/kicad/-/issues/12313
(cherry picked from commit fa3e9efdce)
2022-11-03 10:16:26 -07:00
Marek Roszko 6ca2f6a6e1 Try a hackfix for windows icon scaling
Related https://gitlab.com/kicad/code/kicad/-/issues/11880


(cherry picked from commit 321d6e3ea8)
2022-10-31 21:47:11 +00:00
Marek Roszko 2ff3fac7b3 Don't fix the visibility icon size or it will never scale properly
Related https://gitlab.com/kicad/code/kicad/-/issues/11880


(cherry picked from commit c0f8810759)
2022-10-31 21:46:53 +00:00
Mark Roszko 08452433e8 Check the process exit code rather than output variable for git header creation 2022-10-29 18:39:02 +00:00
Wayne Stambaugh 39b9b3e570 Begin version 6.0.10 development. 2022-10-28 16:55:26 -04:00
151 changed files with 21544 additions and 20908 deletions
+9
View File
@@ -54,6 +54,15 @@ common/pcb_keywords.cpp
include/pcb_lexer.h
fp-info-cache
# .md generated files
eeschema/dialogs/dialog_bom_help_md.h
pcb_calculator/attenuators/bridget_tee_formula.h
pcb_calculator/attenuators/pi_formula.h
pcb_calculator/attenuators/splitter_formula.h
pcb_calculator/attenuators/tee_formula.h
pcb_calculator/eserie_help.h
pcb_calculator/tracks_width_versus_current_formula.h
# demo project auxiliary files
demos/**/*-bak
demos/**/_autosave-*
+1
View File
@@ -43,3 +43,4 @@ include:
- local: '/.gitlab/Windows-CI.yml'
- local: '/.gitlab/coverity.yml'
- local: '/.gitlab/linux-metadata-validate.yml'
- local: '/.gitlab/doxygen.yml'
+18
View File
@@ -0,0 +1,18 @@
build_doxygen_docker:
image: docker:stable
services:
- docker:dind
stage: build
tags:
- docker
before_script:
- docker info
- docker login -u gitlab-ci-token -p "$CI_BUILD_TOKEN" "$CI_REGISTRY"
script:
- docker build -t "${CI_REGISTRY_IMAGE}/doxygen:$CI_COMMIT_BRANCH" -f ./Documentation/doxygen.Dockerfile .
- docker push "${CI_REGISTRY_IMAGE}/doxygen:$CI_COMMIT_BRANCH"
only:
refs:
- schedules
variables:
- $SCHEDULED_JOB_NAME == "doxygen"
@@ -27,6 +27,7 @@
* 3d models that come in the original data from the files without any transformations.
*/
#include <gal/opengl/kiglew.h> // Must be included first
#include <iostream>
#include "3d_rendering/opengl/3d_model.h"
#include "eda_3d_model_viewer.h"
@@ -38,6 +39,7 @@
#include <settings/common_settings.h>
#include <pgm_base.h>
#include <gal/dpi_scaling.h>
#include <macros.h>
/**
* Scale conversion from 3d model units to pcb units
@@ -182,6 +184,20 @@ void EDA_3D_MODEL_VIEWER::Clear3DModel()
void EDA_3D_MODEL_VIEWER::ogl_initialize()
{
const GLenum err = glewInit();
if( GLEW_OK != err )
{
const wxString msgError = (const char*) glewGetErrorString( err );
wxLogMessage( msgError );
}
else
{
wxLogTrace( m_logTrace, wxT( "EDA_3D_MODEL_VIEWER::ogl_initialize Using GLEW version %s" ),
FROM_UTF8( (char*) glewGetString( GLEW_VERSION ) ) );
}
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
glHint( GL_POLYGON_SMOOTH_HINT, GL_NICEST );
+6 -6
View File
@@ -38,8 +38,8 @@ macro( create_git_version_header _git_src_path )
${GIT_EXECUTABLE} describe --dirty
WORKING_DIRECTORY ${_git_src_path}
OUTPUT_VARIABLE _git_DESCRIBE
ERROR_VARIABLE _git_log_error
RESULT_VARIABLE _git_log_result
ERROR_VARIABLE _git_describe_error
RESULT_VARIABLE _git_describe_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(
@@ -47,8 +47,8 @@ macro( create_git_version_header _git_src_path )
${GIT_EXECUTABLE} rev-list --count --first-parent HEAD
WORKING_DIRECTORY ${_git_src_path}
OUTPUT_VARIABLE _git_REV_COUNT
ERROR_VARIABLE _git_log_error
RESULT_VARIABLE _git_log_result
ERROR_VARIABLE _git_rev_count_error
RESULT_VARIABLE _git_rev_count_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
set( ENV{LC_ALL} ${_Git_SAVED_LC_ALL} )
@@ -56,11 +56,11 @@ macro( create_git_version_header _git_src_path )
# Check to make sure 'git' command did not fail. Otherwise fallback
# to KiCadVersion.cmake as the revision level.
if( _git_DESCRIBE )
if( _git_describe_result EQUAL 0 )
set( KICAD_VERSION "(${_git_DESCRIBE})" )
endif()
if( _git_REV_COUNT )
if( _git_rev_count_result EQUAL 0 )
set( KICAD_GIT_REV "${_git_REV_COUNT}" )
# Sanity check
+2 -2
View File
@@ -2,7 +2,7 @@
# This program source code file is part of KICAD, a free EDA CAD application.
#
# Copyright (C) 2016 Wayne Stambaugh <stambaughw@gmail.com>
# Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors.
# Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
@@ -37,7 +37,7 @@
# KiCad.
#
# Note: This version string should follow the semantic versioning system
set( KICAD_SEMANTIC_VERSION "6.0.9" )
set( KICAD_SEMANTIC_VERSION "6.0.11-unknown" )
# Default the version to the semantic version.
# This is overridden by the git repository tag though (if using git)
+23
View File
@@ -0,0 +1,23 @@
FROM registry.gitlab.com/kicad/kicad-ci/source_containers/master/ubuntu:22.04 as build-doxygen-env
USER root
WORKDIR /src
COPY . ./
RUN ls
RUN mkdir build && cd build
WORKDIR /src/build
RUN cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DKICAD_USE_OCC=ON \
-DKICAD_SCRIPTING_WXPYTHON=ON \
-DKICAD_SPICE=ON
RUN make doxygen-docs
RUN make doxygen-python
FROM scratch as output-image
COPY --from=build-doxygen-env /src/Documentation/doxygen/html /doxygen-docs_html
COPY --from=build-doxygen-env /src/build/pcbnew/doxygen-python/html /doxygen-python_html
@@ -0,0 +1,6 @@
doxygen.Dockerfile.dockerignore.git
.gitlab
.github
.idea
.vs
build
-11
View File
@@ -82,13 +82,6 @@ static const wxChar DRCEpsilon[] = wxT( "DRCEpsilon" );
*/
static const wxChar HoleWallThickness[] = wxT( "HoleWallPlatingThickness" );
/**
* Testing mode for new connectivity algorithm. Setting this to on will cause all modifications
* to the netlist to be recalculated on the fly. This may be slower than the standard process
* at the moment
*/
static const wxChar RealtimeConnectivity[] = wxT( "RealtimeConnectivity" );
/**
* Configure the coroutine stack size in bytes. This should be allocated in multiples of
* the system page size (n*4096 is generally safe)
@@ -260,7 +253,6 @@ ADVANCED_CFG::ADVANCED_CFG()
// Init defaults - this is done in case the config doesn't exist,
// then the values will remain as set here.
m_RealTimeConnectivity = true;
m_CoroutineStackSize = AC_STACK::default_stack;
m_ShowRouterDebugGraphics = false;
m_DrawArcAccuracy = 10.0;
@@ -333,9 +325,6 @@ void ADVANCED_CFG::loadSettings( wxConfigBase& aCfg )
{
std::vector<PARAM_CFG*> configParams;
configParams.push_back( new PARAM_CFG_BOOL( true, AC_KEYS::RealtimeConnectivity,
&m_RealTimeConnectivity, m_RealTimeConnectivity ) );
configParams.push_back( new PARAM_CFG_DOUBLE( true, AC_KEYS::ExtraFillMargin,
&m_ExtraClearance, m_ExtraClearance, 0.0, 1.0 ) );
+8
View File
@@ -121,6 +121,13 @@ wxBitmap KiBitmap( const BITMAP_OPAQUE* aBitmap )
int KiIconScale( wxWindow* aWindow )
{
#if defined( __WXMSW__) && wxCHECK_VERSION( 3, 1, 6 )
// Basically don't try and scale within kicad and let wx do its thing
// with wx introducing bitmap bundles, it will auto scale automatically with dpi
// the issue is, none of the scaling factors have any tie to system scaling
// this means wx is actually going to scale again causing even more distorted icons
return 4;
#else
const int vert_size = aWindow->ConvertDialogToPixels( wxSize( 0, 8 ) ).y;
// Autoscale won't exceed unity until the system has quite high resolution,
@@ -131,6 +138,7 @@ int KiIconScale( wxWindow* aWindow )
else if( vert_size > 29 ) return 7;
else if( vert_size > 24 ) return 6;
else return 4;
#endif
}
+3
View File
@@ -465,7 +465,10 @@ bool KIWAY::PlayerClose( FRAME_T aFrameType, bool doForce )
return true;
if( frame->NonUserClose( doForce ) )
{
m_playerFrameId[aFrameType] = wxID_NONE;
return true;
}
return false;
}
+9 -4
View File
@@ -249,6 +249,7 @@ COMPILER::~COMPILER()
if( m_tree )
{
freeTree( m_tree );
m_tree = nullptr;
}
// Allow explicit call to destructor
@@ -693,6 +694,7 @@ void COMPILER::freeTree( LIBEVAL::TREE_NODE *tree )
freeTree( tree->leaf[1] );
delete tree->uop;
tree->uop = nullptr;
}
@@ -1006,10 +1008,13 @@ bool COMPILER::generateUCode( UCODE* aCode, CONTEXT* aPreflightContext )
}
else
{
msg.Printf( _( "Missing units for '%s'| (%s)" ),
*node->value.str,
m_unitResolver->GetSupportedUnitsMessage() );
reportError( CST_CODEGEN, msg, node->srcPos );
if( !m_unitResolver->GetSupportedUnitsMessage().empty() )
{
msg.Printf( _( "Missing units for '%s'| (%s)" ),
*node->value.str,
m_unitResolver->GetSupportedUnitsMessage() );
reportError( CST_CODEGEN, msg, node->srcPos );
}
value = DoubleValueFromString( EDA_UNITS::UNSCALED, *node->value.str );
}
+55 -17
View File
@@ -38,6 +38,7 @@
#include <macros.h>
#include <trigo.h>
#include <basic_gal.h>
#include <plotters/plotters_pslike.h>
@@ -837,6 +838,7 @@ void PDF_PLOTTER::Text( const wxPoint& aPos,
// be pixel-accurate, but it doesn't matter for searching.
int render_mode = 3; // invisible
wxPoint pos( aPos );
const char *fontname = aItalic ? ( aBold ? "/KicadFontBI" : "/KicadFontI" )
: ( aBold ? "/KicadFontB" : "/KicadFont" );
@@ -844,28 +846,64 @@ void PDF_PLOTTER::Text( const wxPoint& aPos,
double ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f;
double wideningFactor, heightFactor;
computeTextParameters( aPos, aText, aOrient, aSize, m_plotMirror, aH_justify,
aV_justify, aWidth, aItalic, aBold,
&wideningFactor, &ctm_a, &ctm_b, &ctm_c,
&ctm_d, &ctm_e, &ctm_f, &heightFactor );
SetColor( aColor );
SetCurrentLineWidth( aWidth, aData );
/* We use the full CTM instead of the text matrix because the same
coordinate system will be used for the overlining. Also the %f
for the trig part of the matrix to avoid %g going in exponential
format (which is not supported) */
fprintf( workFile, "q %f %f %f %f %g %g cm BT %s %g Tf %d Tr %g Tz ",
ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f,
fontname, heightFactor, render_mode, wideningFactor * 100 );
const auto& font = basic_gal.GetStrokeFont();
VECTOR2D fontSize( aSize.x, aSize.y );
double penWidth( aWidth );
VECTOR2D extents = font.ComputeStringBoundaryLimits( aText, fontSize, penWidth );
// The text must be escaped correctly
std:: string txt_pdf = encodeStringForPlotter( aText );
fprintf( workFile, "%s Tj ET\n", txt_pdf.c_str() );
wxPoint box_x( KiROUND( extents.x ), 0 );
wxPoint box_y( 0, KiROUND( extents.y ) );
// Restore the CTM
fputs( "Q\n", workFile );
RotatePoint( &box_x, aOrient );
RotatePoint( &box_y, aOrient );
if( aH_justify == GR_TEXT_HJUSTIFY_CENTER )
pos -= box_x / 2;
else if( aH_justify == GR_TEXT_HJUSTIFY_RIGHT )
pos -= box_x;
if( aV_justify == GR_TEXT_VJUSTIFY_CENTER )
pos += box_y / 2;
else if( aV_justify == GR_TEXT_VJUSTIFY_TOP )
pos += box_y;
wxStringTokenizer str_tok( aText, " ", wxTOKEN_RET_DELIMS );
while( str_tok.HasMoreTokens() )
{
wxString word = str_tok.GetNextToken();
computeTextParameters( pos, word, aOrient, aSize, m_plotMirror, GR_TEXT_HJUSTIFY_LEFT,
GR_TEXT_VJUSTIFY_BOTTOM, aWidth, aItalic, aBold, &wideningFactor, &ctm_a,
&ctm_b, &ctm_c, &ctm_d, &ctm_e, &ctm_f, &heightFactor );
// Extract the changed width and rotate by the orientation to get the offset for the
// next word
extents = font.ComputeStringBoundaryLimits( word, fontSize, penWidth );
wxPoint bbox( KiROUND( extents.x ), 0 );
RotatePoint( &bbox, aOrient );
pos += bbox;
// Don't try to output a blank string
if( word.Trim( false ).Trim( true ).empty() )
continue;
/* We use the full CTM instead of the text matrix because the same
coordinate system will be used for the overlining. Also the %f
for the trig part of the matrix to avoid %g going in exponential
format (which is not supported) */
fprintf( workFile, "q %f %f %f %f %g %g cm BT %s %g Tf %d Tr %g Tz ",
ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f,
fontname, heightFactor, render_mode, wideningFactor * 100 );
std::string txt_pdf = encodeStringForPlotter( word );
fprintf( workFile, "%s Tj ET\n", txt_pdf.c_str() );
// Restore the CTM
fputs( "Q\n", workFile );
}
// Plot the stroked text (if requested)
PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, aWidth,
+9 -40
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.TXT for contributors.
* Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -35,18 +35,9 @@ using namespace TFIELD_T;
#define FOOTPRINT_CANONICAL "Footprint"
#define DATASHEET_CANONICAL "Datasheet"
static std::mutex s_defaultFieldMutex;
const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTranslate )
const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTranslateForHI )
{
static void* locale = nullptr;
static wxString referenceDefault;
static wxString valueDefault;
static wxString footprintDefault;
static wxString datasheetDefault;
static wxString fieldDefault;
if( !aTranslate )
if( !aTranslateForHI )
{
switch( aFieldNdx )
{
@@ -54,42 +45,20 @@ const wxString TEMPLATE_FIELDNAME::GetDefaultFieldName( int aFieldNdx, bool aTra
case VALUE_FIELD: return VALUE_CANONICAL; // The symbol value
case FOOTPRINT_FIELD: return FOOTPRINT_CANONICAL; // The footprint for use with Pcbnew
case DATASHEET_FIELD: return DATASHEET_CANONICAL; // Link to a datasheet for symbol
default: return wxString::Format( wxT( "Field%d" ), aFieldNdx );
}
}
// Mutex protection is needed so that multiple loader threads don't write to the static
// variables at once
std::lock_guard<std::mutex> lock( s_defaultFieldMutex );
// Fetching translations can take a surprising amount of time when loading libraries,
// so only do it when necessary.
if( Pgm().GetLocale() != locale )
{
referenceDefault = _( REFERENCE_CANONICAL );
valueDefault = _( VALUE_CANONICAL );
footprintDefault = _( FOOTPRINT_CANONICAL );
datasheetDefault = _( DATASHEET_CANONICAL );
fieldDefault = _( "Field%d" );
locale = Pgm().GetLocale();
}
// Fixed values for the mandatory fields
switch( aFieldNdx )
{
case REFERENCE_FIELD: return referenceDefault; // The symbol reference, R1, C1, etc.
case VALUE_FIELD: return valueDefault; // The symbol value
case FOOTPRINT_FIELD: return footprintDefault; // The footprint for use with Pcbnew
case DATASHEET_FIELD: return datasheetDefault; // Link to a datasheet for symbol
default: return wxString::Format( fieldDefault, aFieldNdx );
case REFERENCE_FIELD: return _( REFERENCE_CANONICAL ); // The symbol reference, R1, C1, etc.
case VALUE_FIELD: return _( VALUE_CANONICAL ); // The symbol value
case FOOTPRINT_FIELD: return _( FOOTPRINT_CANONICAL ); // The footprint for use with Pcbnew
case DATASHEET_FIELD: return _( DATASHEET_CANONICAL ); // Link to a datasheet for symbol
default: return wxString::Format( _( "Field%d" ), aFieldNdx );
}
}
#undef REFERENCE_CANONICAL
#undef VALUE_CANONICAL
#undef FOOTPRINT_CANONICAL
#undef DATASHEET_CANONICAL
void TEMPLATE_FIELDNAME::Format( OUTPUTFORMATTER* out, int nestLevel ) const
{
+7 -1
View File
@@ -91,6 +91,7 @@ void TITLE_BLOCK::GetContextualTextVars( wxArrayString* aVars )
bool TITLE_BLOCK::TextVarResolver( wxString* aToken, const PROJECT* aProject ) const
{
bool tokenUpdated = false;
wxString originalToken = *aToken;
if( aToken->IsSameAs( wxT( "ISSUE_DATE" ) ) )
{
@@ -146,7 +147,12 @@ bool TITLE_BLOCK::TextVarResolver( wxString* aToken, const PROJECT* aProject ) c
if( tokenUpdated )
{
*aToken = ExpandTextVars( *aToken, aProject );
*aToken = ExpandTextVars( *aToken, aProject );
// This is the default fallback, so don't claim we resolved it
if( *aToken == wxT( "${" ) + originalToken + wxT( "}" ) )
return false;
return true;
}
+5 -2
View File
@@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -117,8 +117,11 @@ bool TOOLS_HOLDER::IsCurrentTool( const TOOL_ACTION& aAction ) const
void TOOLS_HOLDER::ShowChangedLanguage()
{
if( !GetToolManager() )
return;
std::string actionName = CurrentToolName();
TOOL_ACTION* action = m_toolManager->GetActionManager()->FindAction( actionName );
TOOL_ACTION* action = GetToolManager()->GetActionManager()->FindAction( actionName );
if( action )
DisplayToolMsg( action->GetLabel() );
+1
View File
@@ -39,6 +39,7 @@ const wxChar* const kicadTraceCoroutineStack = wxT( "KICAD_COROUTINE_STACK" );
const wxChar* const traceSchLibMem = wxT( "KICAD_SCH_LIB_MEM" );
const wxChar* const traceFindItem = wxT( "KICAD_FIND_ITEM" );
const wxChar* const traceSchLegacyPlugin = wxT( "KICAD_SCH_LEGACY_PLUGIN" );
const wxChar* const traceSchPlugin = wxT( "KICAD_SCH_PLUGIN" );
const wxChar* const traceGedaPcbPlugin = wxT( "KICAD_GEDA_PLUGIN" );
const wxChar* const traceKicadPcbPlugin = wxT( "KICAD_PCB_PLUGIN" );
const wxChar* const tracePrinting = wxT( "KICAD_PRINT" );
+1 -1
View File
@@ -148,7 +148,7 @@ void VIEW_GROUP::ViewDraw( int aLayer, VIEW* aView ) const
{
int layer = layers[i];
if( IsZoneLayer( layer ) )
if( IsZoneFillLayer( layer ) )
layer = layer - LAYER_ZONE_START;
bool draw = aView->IsLayerVisible( layer );
+15 -10
View File
@@ -353,7 +353,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
// Refresh the zoom level and mouse position on message panel
// (mouse position has not changed, only the zoom level has changed):
refreshMouse();
refreshMouse( true );
}
else
{
@@ -371,7 +371,7 @@ void WX_VIEW_CONTROLS::onWheel( wxMouseEvent& aEvent )
VECTOR2D delta( scrollX, scrollY );
m_view->SetCenter( m_view->GetCenter() + delta );
refreshMouse();
refreshMouse( true );
}
// Do not skip this event, otherwise wxWidgets will fire
@@ -545,7 +545,7 @@ void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
dir = m_view->ToWorld( dir, false );
m_view->SetCenter( m_view->GetCenter() + dir );
refreshMouse();
refreshMouse( true );
}
break;
@@ -766,7 +766,9 @@ void WX_VIEW_CONTROLS::WarpCursor( const VECTOR2D& aPosition, bool aWorldCoordin
KIPLATFORM::UI::WarpPointer( m_parentPanel, aPosition.x, aPosition.y );
}
refreshMouse();
// If we are not refreshing because of mouse movement, don't set the modifiers
// because we are refreshing for keyboard movement, which uses the same modifiers for other actions
refreshMouse( m_updateCursor );
}
@@ -894,7 +896,7 @@ void WX_VIEW_CONTROLS::handleCursorCapture( int x, int y )
}
void WX_VIEW_CONTROLS::refreshMouse()
void WX_VIEW_CONTROLS::refreshMouse( bool aSetModifiers )
{
// Notify tools that the cursor position has changed in the world coordinates
wxMouseEvent moveEvent( EVT_REFRESH_MOUSE );
@@ -902,10 +904,13 @@ void WX_VIEW_CONTROLS::refreshMouse()
moveEvent.SetX( msp.x );
moveEvent.SetY( msp.y );
// Set the modifiers state
moveEvent.SetControlDown( wxGetKeyState( WXK_CONTROL ) );
moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) );
moveEvent.SetAltDown( wxGetKeyState( WXK_ALT ) );
if( aSetModifiers )
{
// Set the modifiers state
moveEvent.SetControlDown( wxGetKeyState( WXK_CONTROL ) );
moveEvent.SetShiftDown( wxGetKeyState( WXK_SHIFT ) );
moveEvent.SetAltDown( wxGetKeyState( WXK_ALT ) );
}
m_cursorPos = GetClampedCoords( m_view->ToWorld( VECTOR2D( msp.x, msp.y ) ) );
wxPostEvent( m_parentPanel, moveEvent );
@@ -954,7 +959,7 @@ void WX_VIEW_CONTROLS::UpdateScrollbars()
// Trigger a mouse refresh to get the canvas update in GTK (re-draws the scrollbars).
// Note that this causes an infinite loop on OSX and Windows (in certain cases) as it
// generates a paint event.
refreshMouse();
refreshMouse( false );
#endif
}
}
+1 -1
View File
@@ -44,7 +44,7 @@ BITMAP_TOGGLE::BITMAP_TOGGLE( wxWindow *aParent, wxWindowID aId, const wxBitmap&
const wxBitmap& bitmap = aChecked ? m_checked_bitmap : m_unchecked_bitmap;
m_bitmap = new wxStaticBitmap( this, aId, bitmap, wxDefaultPosition, bitmap.GetSize() );
m_bitmap = new wxStaticBitmap( this, aId, bitmap, wxDefaultPosition );
sizer->Add( m_bitmap, 0, 0 );
-4
View File
@@ -437,7 +437,6 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
}
int LastReferenceNumber = 0;
int NumberOfUnits, Unit;
/* calculate index of the first symbol with the same reference prefix
* than the current symbol. All symbols having the same reference
@@ -518,9 +517,6 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
continue;
}
// Annotation of multi-unit parts ( n units per part ) (complex case)
NumberOfUnits = ref_unit.GetLibPart()->GetUnitCount();
// If this symbol is in aLockedUnitMap, copy the annotation to all
// symbols that are not it
if( lockedList != nullptr )
+151 -157
View File
@@ -410,9 +410,6 @@ CONNECTION_SUBGRAPH::PRIORITY CONNECTION_SUBGRAPH::GetDriverPriority( SCH_ITEM*
}
bool CONNECTION_GRAPH::m_allowRealTime = true;
void CONNECTION_GRAPH::Reset()
{
for( auto& subgraph : m_subgraphs )
@@ -481,17 +478,6 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
recalc_time.Show();
#ifndef DEBUG
// Pressure relief valve for release builds
const double max_recalc_time_msecs = 250.;
if( m_allowRealTime && ADVANCED_CFG::GetCfg().m_RealTimeConnectivity &&
recalc_time.msecs() > max_recalc_time_msecs )
{
m_allowRealTime = false;
}
#endif
}
@@ -2205,6 +2191,31 @@ CONNECTION_SUBGRAPH* CONNECTION_GRAPH::FindSubgraphByName( const wxString& aNetN
}
wxString CONNECTION_GRAPH::GetResolvedSubgraphName( const CONNECTION_SUBGRAPH* aSubGraph ) const
{
wxString retval = aSubGraph->GetNetName();
bool found = false;
// This is a hacky way to find the true subgraph net name (why do we not store it?)
// TODO: Remove once the actual netname of the subgraph is stored with the subgraph
for( auto it = m_net_name_to_subgraphs_map.begin(); it != m_net_name_to_subgraphs_map.end() && !found; ++it )
{
for( CONNECTION_SUBGRAPH* graph : it->second )
{
if( graph == aSubGraph )
{
retval = it->first;
found = true;
break;
}
}
}
return retval;
}
CONNECTION_SUBGRAPH* CONNECTION_GRAPH::FindFirstSubgraphByName( const wxString& aNetName )
{
auto it = m_net_name_to_subgraphs_map.find( aNetName );
@@ -2630,68 +2641,96 @@ bool CONNECTION_GRAPH::ercCheckBusToBusEntryConflicts( const CONNECTION_SUBGRAPH
bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph )
{
ERC_SETTINGS& settings = m_schematic->ErcSettings();
wxString msg;
const SCH_SHEET_PATH& sheet = aSubgraph->m_sheet;
SCH_SCREEN* screen = sheet.LastScreen();
bool ok = true;
SCH_PIN* pin = nullptr;
if( aSubgraph->m_no_connect != nullptr )
std::set<SCH_PIN*> unique_pins;
std::set<SCH_TEXT*> unique_labels;
wxString netName = GetResolvedSubgraphName( aSubgraph );
auto process_subgraph = [&]( const CONNECTION_SUBGRAPH* aProcessGraph )
{
bool has_invalid_items = false;
bool has_other_items = false;
SCH_PIN* pin = nullptr;
std::vector<SCH_ITEM*> invalid_items;
wxPoint noConnectPos = aSubgraph->m_no_connect->GetPosition();
double minDist = 0;
// Any subgraph that contains a no-connect should not
// more than one pin (which would indicate it is connected
// Any subgraph that contains both a pin and a no-connect should not
// contain any other driving items.
for( SCH_ITEM* item : aSubgraph->m_items )
for( SCH_ITEM* item : aProcessGraph->m_items )
{
switch( item->Type() )
{
case SCH_PIN_T:
{
SCH_PIN* candidate = static_cast<SCH_PIN*>( item );
double dist = VECTOR2I( candidate->GetTransformedPosition() - noConnectPos )
.SquaredEuclideanNorm();
SCH_PIN* test_pin = static_cast<SCH_PIN*>( item );
if( !pin || dist < minDist )
// Only link NC to pin on the current subgraph being checked
if( aProcessGraph == aSubgraph )
pin = test_pin;
if( std::none_of( unique_pins.begin(), unique_pins.end(),
[test_pin]( SCH_PIN* aPin )
{
return test_pin->IsStacked( aPin );
}
) )
{
pin = candidate;
minDist = dist;
unique_pins.insert( test_pin );
}
has_invalid_items |= has_other_items;
has_other_items = true;
break;
}
case SCH_LINE_T:
case SCH_JUNCTION_T:
case SCH_NO_CONNECT_T:
break;
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
case SCH_HIER_LABEL_T:
unique_labels.insert( static_cast<SCH_TEXT*>( item ) );
KI_FALLTHROUGH;
default:
has_invalid_items = true;
has_other_items = true;
invalid_items.push_back( item );
break;
}
}
};
if( pin && has_invalid_items && settings.IsTestEnabled( ERCE_NOCONNECT_CONNECTED ) )
auto it = m_net_name_to_subgraphs_map.find( netName );
if( it != m_net_name_to_subgraphs_map.end() )
{
for( const CONNECTION_SUBGRAPH* subgraph : it->second )
{
process_subgraph( subgraph );
}
}
else
{
process_subgraph( aSubgraph );
}
if( aSubgraph->m_no_connect != nullptr )
{
if( unique_pins.size() > 1 && settings.IsTestEnabled( ERCE_NOCONNECT_CONNECTED ) )
{
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_NOCONNECT_CONNECTED );
ercItem->SetItems( pin );
wxPoint pos;
SCH_MARKER* marker = new SCH_MARKER( ercItem, pin->GetTransformedPosition() );
if( pin )
{
ercItem->SetItems( pin, aSubgraph->m_no_connect );
pos = pin->GetTransformedPosition();
}
else
{
ercItem->SetItems( aSubgraph->m_no_connect );
pos = aSubgraph->m_no_connect->GetPosition();
}
SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
screen->Append( marker );
ok = false;
}
if( !has_other_items && settings.IsTestEnabled( ERCE_NOCONNECT_NOT_CONNECTED ) )
if( unique_pins.empty() && unique_labels.empty() && settings.IsTestEnabled( ERCE_NOCONNECT_NOT_CONNECTED ) )
{
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_NOCONNECT_NOT_CONNECTED );
ercItem->SetItems( aSubgraph->m_no_connect );
@@ -2719,12 +2758,11 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph
// Stacked pins do not count as other connections but non-stacked pins do
if( !has_other_connections && !pins.empty() )
{
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
SCH_PIN* test_pin = static_cast<SCH_PIN*>( item );
for( SCH_PIN* other_pin : pins )
{
if( other_pin->GetParent() != pin->GetParent()
|| other_pin->GetPosition() != pin->GetPosition() )
if( !test_pin->IsStacked( other_pin ) )
{
has_other_connections = true;
break;
@@ -2746,7 +2784,17 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph
}
// For many checks, we can just use the first pin
SCH_PIN* pin = pins.empty() ? nullptr : pins[0];
pin = pins.empty() ? nullptr : pins[0];
// But if there is a power pin, it might be connected elsewhere
for( SCH_PIN* test_pin : pins )
{
if( test_pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN )
{
pin = test_pin;
break;
}
}
// Check if invisible power input pins connect to anything else via net name,
// but not for power symbols as the ones in the standard library all have invisible pins
@@ -2868,9 +2916,10 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph )
if( aSubgraph->m_driver_connection->IsBus() )
return true;
ERC_SETTINGS& settings = m_schematic->ErcSettings();
bool ok = true;
int pinCount = 0;
ERC_SETTINGS& settings = m_schematic->ErcSettings();
bool ok = true;
int pinCount = 0;
bool has_nc = !!aSubgraph->m_no_connect;
std::map<KICAD_T, std::vector<SCH_TEXT*>> label_map;
@@ -2878,22 +2927,9 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph )
auto hasPins =
[]( const CONNECTION_SUBGRAPH* aLocSubgraph ) -> int
{
int retval = 0;
for( const SCH_ITEM* item : aLocSubgraph->m_items )
{
switch( item->Type() )
{
case SCH_PIN_T:
case SCH_SHEET_PIN_T:
++retval;
break;
default: break;
}
}
return retval;
return
std::count_if( aLocSubgraph->m_items.begin(), aLocSubgraph->m_items.end(), []( const SCH_ITEM* item )
{ return item->Type() == SCH_PIN_T; } );
};
auto reportError = [&]( SCH_TEXT* aText, int errCode )
@@ -2934,11 +2970,6 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph )
break;
}
// If this subgraph has a no-connect, do not continue processing as we do not
// submit no-connect errors for nets explicitly designated as no-connect
case SCH_NO_CONNECT_T:
return true;
default:
break;
}
@@ -2947,105 +2978,68 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph )
if( label_map.empty() )
return true;
wxCHECK_MSG( m_schematic, true, wxT( "Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" ) );
wxString netName = GetResolvedSubgraphName( aSubgraph );
wxCHECK_MSG( m_schematic, true, "Null m_schematic in CONNECTION_GRAPH::ercCheckLabels" );
// Labels that have multiple pins connected are not dangling (may be used for naming segments)
// so leave them without errors here
if( pinCount > 1 )
return true;
for( const auto& label_pair : label_map )
for( auto label_el : label_map )
{
const KICAD_T type = label_pair.first;
std::vector<SCH_TEXT*> label_vec = label_pair.second;
KICAD_T type = label_el.first;
std::vector<SCH_TEXT*>& label_vec = label_el.second;
switch( type )
{
case SCH_GLOBAL_LABEL_T:
if( !settings.IsTestEnabled( ERCE_GLOBLABEL ) )
break;
for( SCH_TEXT* text : label_vec )
{
wxString name = EscapeString( text->GetShownText(), CTX_NETNAME );
int allPins = pinCount;
// If the global label is connected to a subgraph but is not the driver
// then there is a driver conflict somewhere that is handled by a different
// ERC check. Here, we are just looking for unconnected elements
if( name != aSubgraph->m_driver_connection->Name() )
continue;
// Global labels are connected if there is another instance of
// their name in the circuit
auto it = m_net_name_to_subgraphs_map.find( name );
for( const CONNECTION_SUBGRAPH* neighbor : it->second )
{
if( neighbor == aSubgraph )
continue;
allPins += hasPins( neighbor );
}
if( allPins < 2 )
{
reportError( text, ERCE_GLOBLABEL );
ok = false;
}
}
break;
case SCH_HIER_LABEL_T:
if( !settings.IsTestEnabled( ERCE_LABEL_NOT_CONNECTED ) )
break;
for( SCH_TEXT* text : label_vec )
{
if( !aSubgraph->m_hier_parent
|| ( !aSubgraph->m_hier_parent->m_strong_driver
&& aSubgraph->m_hier_parent->m_drivers.size() <= 1 ) )
{
reportError( text, ERCE_LABEL_NOT_CONNECTED );
ok = false;
}
}
break;
case SCH_LABEL_T:
if( !settings.IsTestEnabled( ERCE_LABEL_NOT_CONNECTED ) )
break;
for( SCH_TEXT* text : label_vec )
{
int allPins = pinCount;
wxString name = EscapeString( text->GetShownText(), CTX_NETNAME );
auto pair = std::make_pair( aSubgraph->m_sheet, name );
auto it = m_local_label_cache.find( pair );
if( it == m_local_label_cache.end() )
continue;
for( const CONNECTION_SUBGRAPH* neighbor : it->second )
{
if( neighbor == aSubgraph )
continue;
allPins += hasPins( neighbor );
}
if( allPins < 2 )
{
reportError( text, ERCE_LABEL_NOT_CONNECTED );
ok = false;
}
}
continue;
break;
default:
if( !settings.IsTestEnabled( ERCE_LABEL_NOT_CONNECTED ) )
continue;
break;
}
for( SCH_TEXT* text : label_vec )
{
int allPins = pinCount;
auto net_it = m_net_name_to_subgraphs_map.find( netName );
if( net_it != m_net_name_to_subgraphs_map.end() )
{
for( const CONNECTION_SUBGRAPH* neighbor : net_it->second )
{
if( neighbor == aSubgraph )
continue;
if( neighbor->m_no_connect )
has_nc = true;
allPins += hasPins( neighbor );
}
}
if( allPins == 1 && !has_nc )
{
reportError( text,
type == SCH_GLOBAL_LABEL_T ? ERCE_GLOBLABEL : ERCE_LABEL_NOT_CONNECTED );
ok = false;
}
if( allPins == 0 )
{
reportError( text,
type == SCH_GLOBAL_LABEL_T ? ERCE_GLOBLABEL : ERCE_LABEL_NOT_CONNECTED );
ok = false;
}
}
}
return ok;
+7 -4
View File
@@ -324,6 +324,13 @@ public:
CONNECTION_SUBGRAPH* GetSubgraphForItem( SCH_ITEM* aItem );
/**
* Returns the fully-resolved netname for a given subgraph
* @param aSubGraph Reference to the subgraph
* @return Netname string usable with m_net_name_to_subgraphs_map
*/
wxString GetResolvedSubgraphName( const CONNECTION_SUBGRAPH* aSubGraph ) const;
private:
/**
* Updates the graphical connectivity between items (i.e. where they touch)
@@ -530,10 +537,6 @@ private:
*/
int ercCheckHierSheets();
public:
// TODO(JE) Remove this when pressure valve is removed
static bool m_allowRealTime;
private:
// All the sheets in the schematic (as long as we don't have partial updates)
SCH_SHEET_LIST m_sheetList;
-5
View File
@@ -578,11 +578,6 @@ void SCH_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
NETLIST_EXPORTER_KICAD exporter( &Schematic() );
STRING_FORMATTER formatter;
// TODO remove once real-time connectivity is a given
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
// Ensure the netlist data is up to date:
RecalculateConnections( NO_CLEANUP );
exporter.Format( &formatter, GNL_ALL | GNL_OPT_KICAD );
payload = formatter.GetString();
+223 -161
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020-2021 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Wayne Stambaugh <stambaughw@gmail.com>
*
@@ -25,14 +25,12 @@
#include <bitmaps.h>
#include <string_utils.h> // WildCompareString
#include <kiway.h>
#include <lib_id.h>
#include <refdes_utils.h>
#include <core/kicad_algo.h>
#include <dialog_change_symbols.h>
#include <sch_symbol.h>
#include <sch_edit_frame.h>
#include <sch_screen.h>
#include <sch_sheet_path.h>
#include <schematic.h>
#include <template_fieldnames.h>
#include <wx_html_report_panel.h>
@@ -100,7 +98,7 @@ DIALOG_CHANGE_SYMBOLS::DIALOG_CHANGE_SYMBOLS( SCH_EDIT_FRAME* aParent, SCH_SYMBO
for( int i = 0; i < MANDATORY_FIELDS; ++i )
{
m_fieldsBox->Append( TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) );
m_fieldsBox->Append( TEMPLATE_FIELDNAME::GetDefaultFieldName( i, DO_TRANSLATE ) );
if( i == REFERENCE_FIELD )
m_fieldsBox->Check( i, g_selectRefDes );
@@ -399,7 +397,9 @@ void DIALOG_CHANGE_SYMBOLS::onOkButtonClicked( wxCommandEvent& aEvent )
m_updateFields.insert( dummy_field.GetCanonicalName() );
}
else
{
m_updateFields.insert( m_fieldsBox->GetString( i ) );
}
}
}
@@ -451,15 +451,16 @@ bool DIALOG_CHANGE_SYMBOLS::isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInsta
}
bool DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
int DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
{
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
wxCHECK( frame, false );
LIB_ID newId;
bool appendToUndo = false;
bool changed = false;
wxString msg;
int matchesProcessed = 0;
SCH_SYMBOL* symbol = nullptr;
SCH_SHEET_LIST hierarchy = frame->Schematic().GetSheets();
if( m_mode == MODE::CHANGE )
@@ -470,70 +471,258 @@ bool DIALOG_CHANGE_SYMBOLS::processMatchingSymbols()
return false;
}
std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO> symbols;
for( SCH_SHEET_PATH& instance : hierarchy )
{
SCH_SCREEN* screen = instance.LastScreen();
wxCHECK2( screen, continue );
std::vector<SCH_SYMBOL*> symbols;
// Fetch all the symbols that meet the change criteria.
for( SCH_ITEM* item : screen->Items().OfType( SCH_SYMBOL_T ) )
symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
for( SCH_SYMBOL* symbol : symbols )
{
symbol = static_cast<SCH_SYMBOL*>( item );
wxCHECK2( symbol, continue );
if( !isMatch( symbol, &instance ) )
continue;
if( m_mode == MODE::UPDATE )
newId = symbol->GetLibId();
auto it = symbols.find( symbol );
if( it == symbols.end() )
{
if( processSymbol( symbol, &instance, symbol->GetLibId(), appendToUndo ) )
changed = true;
SYMBOL_CHANGE_INFO info;
info.m_Instances.emplace_back( instance );
info.m_LibId = newId;
symbols.insert( { symbol, info } );
}
else
{
if( processSymbol( symbol, &instance, newId, appendToUndo ) )
changed = true;
it->second.m_Instances.emplace_back( instance );
}
if( changed )
appendToUndo = true;
}
}
matchesProcessed += processSymbols( symbols );
frame->GetCurrentSheet().UpdateAllScreenReferences();
return changed;
return matchesProcessed;
}
bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_PATH* aInstance,
const LIB_ID& aNewId, bool aAppendToUndo )
int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
SYMBOL_CHANGE_INFO>& aSymbols )
{
wxCHECK( aSymbol, false );
wxCHECK( aNewId.IsValid(), false );
wxCHECK( !aSymbols.empty(), 0 );
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
SCH_SCREEN* screen = aInstance->LastScreen();
int matchesProcessed = 0;
SCH_EDIT_FRAME* frame = dynamic_cast<SCH_EDIT_FRAME*>( GetParent() );
SCH_SCREEN* screen = nullptr;
SCH_SYMBOL* symbol = nullptr;
LIB_SYMBOL* libSymbol = nullptr;
std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO> symbols = aSymbols;
wxCHECK( frame, false );
wxCHECK( frame, 0 );
LIB_ID oldId = aSymbol->GetLibId();
wxString msg;
wxString references;
for( SYMBOL_INSTANCE_REFERENCE instance : aSymbol->GetInstanceReferences() )
auto it = symbols.begin();
// Remove all symbols that don't have a valid library symbol link or enough units to
// satify the library symbol update.
while( it != symbols.end() )
{
symbol = it->first;
wxCHECK2( symbol && it->second.m_LibId.IsValid(), continue );
libSymbol = frame->GetLibSymbol( it->second.m_LibId );
if( !libSymbol )
{
msg = getSymbolReferences( *symbol, it->second.m_LibId );
msg << wxT( ": " ) << _( "*** symbol not found ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
it = symbols.erase( it );
continue;
}
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
if( flattenedSymbol->GetUnitCount() < symbol->GetUnit() )
{
msg = getSymbolReferences( *symbol, it->second.m_LibId );
msg << wxT( ": " ) << _( "*** new symbol has too few units ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
it = symbols.erase( it );
}
else
{
++it;
}
}
// Removing the symbol needs to be done before the LIB_SYMBOL is changed to prevent stale
// library symbols in the schematic file.
for( auto& pair : symbols )
{
symbol = pair.first;
wxCHECK( symbol && !pair.second.m_Instances.empty(), 0 );
screen = pair.second.m_Instances[0].LastScreen();
wxCHECK( screen, 0 );
screen->Remove( symbol );
frame->SaveCopyInUndoList( screen, symbol, UNDO_REDO::CHANGED, true );
}
for( auto& pair : symbols )
{
symbol = pair.first;
if( pair.second.m_LibId != symbol->GetLibId() )
symbol->SetLibId( pair.second.m_LibId );
libSymbol = frame->GetLibSymbol( pair.second.m_LibId );
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
symbol->SetLibSymbol( flattenedSymbol.release() );
if( m_resetAttributes->GetValue() )
{
symbol->SetIncludeInBom( libSymbol->GetIncludeInBom() );
symbol->SetIncludeOnBoard( libSymbol->GetIncludeOnBoard() );
}
bool removeExtras = m_removeExtraBox->GetValue();
bool resetVis = m_resetFieldVisibilities->GetValue();
bool resetEffects = m_resetFieldEffects->GetValue();
bool resetPositions = m_resetFieldPositions->GetValue();
for( unsigned i = 0; i < symbol->GetFields().size(); ++i )
{
SCH_FIELD& field = symbol->GetFields()[i];
LIB_FIELD* libField = nullptr;
// Mandatory fields always exist in m_updateFields, but these names can be translated.
// so use GetCanonicalName().
if( !alg::contains( m_updateFields, field.GetCanonicalName() ) )
continue;
if( i < MANDATORY_FIELDS )
libField = libSymbol->GetFieldById( (int) i );
else
libField = libSymbol->FindField( field.GetName() );
if( libField )
{
bool resetText = libField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
: m_resetFieldText->GetValue();
if( resetText )
{
for( const SCH_SHEET_PATH& instance : pair.second.m_Instances )
{
if( i == REFERENCE_FIELD )
symbol->SetRef( &instance,
UTIL::GetRefDesUnannotated( libField->GetText() ) );
else if( i == VALUE_FIELD )
symbol->SetValue( &instance, UnescapeString( libField->GetText() ) );
else if( i == FOOTPRINT_FIELD )
symbol->SetFootprint( &instance, libField->GetText() );
else
field.SetText( libField->GetText() );
}
}
if( resetVis )
field.SetVisible( libField->IsVisible() );
if( resetEffects )
{
// Careful: the visible bit and position are also in Effects
bool visible = field.IsVisible();
wxPoint pos = field.GetPosition();
field.SetEffects( *libField );
field.SetVisible( visible );
field.SetPosition( pos );
}
if( resetPositions )
field.SetTextPos( symbol->GetPosition() + libField->GetTextPos() );
}
else if( i >= MANDATORY_FIELDS && removeExtras )
{
symbol->RemoveField( field.GetName() );
i--;
}
}
std::vector<LIB_FIELD*> libFields;
libSymbol->GetFields( libFields );
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
{
const LIB_FIELD& libField = *libFields[i];
if( !alg::contains( m_updateFields, libField.GetCanonicalName() ) )
continue;
if( !symbol->FindField( libField.GetName(), false ) )
{
wxString fieldName = libField.GetCanonicalName();
SCH_FIELD newField( wxPoint( 0, 0 ), symbol->GetFieldCount(), symbol,
fieldName );
SCH_FIELD* schField = symbol->AddField( newField );
schField->SetEffects( libField );
schField->SetText( libField.GetText() );
schField->SetTextPos( symbol->GetPosition() + libField.GetTextPos() );
}
}
symbol->SetSchSymbolLibraryName( wxEmptyString );
screen = pair.second.m_Instances[0].LastScreen();
screen->Append( symbol );
frame->GetCanvas()->GetView()->Update( symbol );
msg = getSymbolReferences( *symbol, pair.second.m_LibId );
msg += wxS( ": OK" );
m_messagePanel->Report( msg, RPT_SEVERITY_ACTION );
matchesProcessed +=1;
}
return matchesProcessed;
}
wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId )
{
wxString msg;
wxString references;
LIB_ID oldId = aSymbol.GetLibId();
for( const SYMBOL_INSTANCE_REFERENCE& instance : aSymbol.GetInstanceReferences() )
{
if( references.IsEmpty() )
references = instance.m_Reference;
else
references += wxT( " " ) + instance.m_Reference;
}
if( m_mode == MODE::UPDATE )
{
if( aSymbol->GetInstanceReferences().size() == 1 )
if( aSymbol.GetInstanceReferences().size() == 1 )
{
msg.Printf( _( "Update symbol %s from '%s' to '%s'" ),
references,
@@ -550,7 +739,7 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_
}
else
{
if( aSymbol->GetInstanceReferences().size() == 1 )
if( aSymbol.GetInstanceReferences().size() == 1 )
{
msg.Printf( _( "Change symbol %s from '%s' to '%s'" ),
references,
@@ -566,132 +755,5 @@ bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_
}
}
LIB_SYMBOL* libSymbol = frame->GetLibSymbol( aNewId );
if( !libSymbol )
{
msg << wxT( ": " ) << _( "*** symbol not found ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
return false;
}
std::unique_ptr<LIB_SYMBOL> flattenedSymbol = libSymbol->Flatten();
if( flattenedSymbol->GetUnitCount() < aSymbol->GetUnit() )
{
msg << wxT( ": " ) << _( "*** new symbol has too few units ***" );
m_messagePanel->Report( msg, RPT_SEVERITY_ERROR );
return false;
}
// Removing the symbol needs to be done before the LIB_SYMBOL is changed to prevent stale
// library symbols in the schematic file.
screen->Remove( aSymbol );
frame->SaveCopyInUndoList( screen, aSymbol, UNDO_REDO::CHANGED, aAppendToUndo );
if( aNewId != aSymbol->GetLibId() )
aSymbol->SetLibId( aNewId );
aSymbol->SetLibSymbol( flattenedSymbol.release() );
if( m_resetAttributes->GetValue() )
{
aSymbol->SetIncludeInBom( libSymbol->GetIncludeInBom() );
aSymbol->SetIncludeOnBoard( libSymbol->GetIncludeOnBoard() );
}
bool removeExtras = m_removeExtraBox->GetValue();
bool resetVis = m_resetFieldVisibilities->GetValue();
bool resetEffects = m_resetFieldEffects->GetValue();
bool resetPositions = m_resetFieldPositions->GetValue();
for( unsigned i = 0; i < aSymbol->GetFields().size(); ++i )
{
SCH_FIELD& field = aSymbol->GetFields()[i];
LIB_FIELD* libField = nullptr;
// Mandatory fields always exist in m_updateFields, but these names can be translated.
// so use GetCanonicalName().
if( !alg::contains( m_updateFields, field.GetCanonicalName() ) )
continue;
if( i < MANDATORY_FIELDS )
libField = libSymbol->GetFieldById( (int) i );
else
libField = libSymbol->FindField( field.GetName() );
if( libField )
{
bool resetText = libField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
: m_resetFieldText->GetValue();
if( resetText )
{
if( i == REFERENCE_FIELD )
aSymbol->SetRef( aInstance, UTIL::GetRefDesUnannotated( libField->GetText() ) );
else if( i == VALUE_FIELD )
aSymbol->SetValue( aInstance, UnescapeString( libField->GetText() ) );
else if( i == FOOTPRINT_FIELD )
aSymbol->SetFootprint( aInstance, libField->GetText() );
else
field.SetText( libField->GetText() );
}
if( resetVis )
field.SetVisible( libField->IsVisible() );
if( resetEffects )
{
// Careful: the visible bit and position are also in Effects
bool visible = field.IsVisible();
wxPoint pos = field.GetPosition();
field.SetEffects( *libField );
field.SetVisible( visible );
field.SetPosition( pos );
}
if( resetPositions )
field.SetTextPos( aSymbol->GetPosition() + libField->GetTextPos() );
}
else if( i >= MANDATORY_FIELDS && removeExtras )
{
aSymbol->RemoveField( field.GetName() );
i--;
}
}
std::vector<LIB_FIELD*> libFields;
libSymbol->GetFields( libFields );
for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
{
const LIB_FIELD& libField = *libFields[i];
if( !alg::contains( m_updateFields, libField.GetCanonicalName() ) )
continue;
if( !aSymbol->FindField( libField.GetName(), false ) )
{
wxString fieldName = libField.GetCanonicalName();
SCH_FIELD newField( wxPoint( 0, 0), aSymbol->GetFieldCount(), aSymbol, fieldName );
SCH_FIELD* schField = aSymbol->AddField( newField );
schField->SetEffects( libField );
schField->SetText( libField.GetText() );
schField->SetTextPos( aSymbol->GetPosition() + libField.GetTextPos() );
}
}
aSymbol->SetSchSymbolLibraryName( wxEmptyString );
screen->Append( aSymbol );
frame->GetCanvas()->GetView()->Update( aSymbol );
msg += wxT( ": OK" );
m_messagePanel->Report( msg, RPT_SEVERITY_ACTION );
return true;
return msg;
}
+16 -6
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 CERN
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Wayne Stambaugh <stambaughw@gmail.com>
*
@@ -25,11 +25,21 @@
#include <dialog_change_symbols_base.h>
class LIB_ID;
#include <lib_id.h>
#include <sch_sheet_path.h>
class SCH_SYMBOL;
class SCH_EDIT_FRAME;
class SCH_SCREEN;
class SCH_SHEET_PATH;
struct SYMBOL_CHANGE_INFO
{
std::vector<SCH_SHEET_PATH> m_Instances;
LIB_ID m_LibId;
};
/**
* Dialog to update or change schematic library symbols.
@@ -73,9 +83,9 @@ private:
void updateFieldsList();
bool isMatch( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aInstance );
bool processMatchingSymbols();
bool processSymbol( SCH_SYMBOL* aSymbol, const SCH_SHEET_PATH* aInstance,
const LIB_ID& aNewId, bool aAppendToUndo );
int processMatchingSymbols();
int processSymbols( const std::map<SCH_SYMBOL*, SYMBOL_CHANGE_INFO>& aSymbols );
wxString getSymbolReferences( SCH_SYMBOL& aSymbol, const LIB_ID& aNewId );
SCH_SYMBOL* m_symbol;
MODE m_mode;
+8 -3
View File
@@ -53,8 +53,6 @@ DIALOG_FIELD_PROPERTIES::DIALOG_FIELD_PROPERTIES( SCH_BASE_FRAME* aParent, const
{
wxASSERT( aTextItem );
SetTitle( aTitle );
m_note->SetFont( KIUI::GetInfoFont( this ).Italic() );
m_note->Show( false );
@@ -348,7 +346,14 @@ DIALOG_SCH_FIELD_PROPERTIES::DIALOG_SCH_FIELD_PROPERTIES( SCH_BASE_FRAME* aParen
m_isPower = false;
m_textLabel->SetLabel( m_field->GetName() + wxT( ":" ) );
wxString translated_fieldname;
if( m_field->GetId() < MANDATORY_FIELDS )
translated_fieldname = TEMPLATE_FIELDNAME::GetDefaultFieldName( m_field->GetId(), DO_TRANSLATE );
else
translated_fieldname = m_field->GetName();
m_textLabel->SetLabel( translated_fieldname + ":" );
m_position = m_field->GetPosition();
@@ -109,10 +109,6 @@ DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS( SCH_
m_parent = parent;
m_appendUndo = false;
// TODO(JE) remove once real-time connectivity is a given
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
m_parent->RecalculateConnections( NO_CLEANUP );
m_lineStyle->Append( DEFAULT_STYLE );
m_lineStyle->Append( INDETERMINATE_ACTION );
@@ -556,7 +556,9 @@ DIALOG_LIB_EDIT_PIN_TABLE::~DIALOG_LIB_EDIT_PIN_TABLE()
bool DIALOG_LIB_EDIT_PIN_TABLE::TransferDataToWindow()
{
// Make a copy of the pins for editing
for( LIB_PIN* pin = m_part->GetNextPin( nullptr ); pin; pin = m_part->GetNextPin( pin ) )
std::vector<LIB_PIN*> pins = m_part->GetAllLibPins();
for( LIB_PIN* pin : pins )
m_pins.push_back( new LIB_PIN( *pin ) );
m_dataModel->RebuildRows( m_pins, m_cbGroup->GetValue() );
@@ -573,7 +575,9 @@ bool DIALOG_LIB_EDIT_PIN_TABLE::TransferDataFromWindow()
return false;
// Delete the part's pins
while( LIB_PIN* pin = m_part->GetNextPin( nullptr ) )
std::vector<LIB_PIN*> pins = m_part->GetAllLibPins();
for( LIB_PIN* pin : pins )
m_part->RemoveDrawItem( pin );
// Transfer our pins to the part
@@ -233,6 +233,10 @@ public:
if( aCol == QUANTITY_COLUMN )
return _( "Qty" );
else if( aCol < MANDATORY_FIELDS )
// FIX ME: the column label should be displayed translated.
// but when translated, and the DATASHEET column is shown, a new field
// with the translated DATASHEET field name is added when saving fields
// return TEMPLATE_FIELDNAME::GetDefaultFieldName( aCol, DO_TRANSLATE );
return TEMPLATE_FIELDNAME::GetDefaultFieldName( aCol );
else
return m_fieldNames[ aCol ];
@@ -615,19 +619,21 @@ public:
const wxString& srcValue = srcData.second;
SCH_FIELD* destField = symbol.FindField( srcName );
if( !destField && !srcValue.IsEmpty() )
// Add a not existing field if it has a value for this symbol
bool createField = !destField && !srcValue.IsEmpty();
if( createField )
{
const wxPoint symbolPos = symbol.GetPosition();
destField = symbol.AddField( SCH_FIELD( symbolPos, -1, &symbol, srcName ) );
}
if( !destField )
continue;
if( destField->GetId() == REFERENCE_FIELD )
{
symbol.RemoveField( srcName );
}
else if( destField->GetId() == REFERENCE_FIELD )
{
// Reference is not editable
// Reference is not editable from this dialog
}
else if( destField->GetId() == VALUE_FIELD )
{
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Oliver Walters
* Copyright (C) 2017-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -74,6 +74,8 @@ private:
SCH_REFERENCE_LIST m_symbolsList;
FIELDS_EDITOR_GRID_DATA_MODEL* m_dataModel;
static int m_newFieldsOption; // Store the option choice for new fields
// during a session:
};
#endif /* DIALOG_SYMBOL_FIELDS_TABLE_H */
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -32,7 +32,7 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
m_groupSymbolsBox->SetValue(true);
m_groupSymbolsBox->SetToolTip( _("Group symbols together based on common properties") );
bGroupSizer->Add( m_groupSymbolsBox, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT, 5 );
bGroupSizer->Add( m_groupSymbolsBox, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
bGroupSizer->Add( 0, 0, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 );
@@ -103,7 +103,7 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
bButtonsSizer->Add( 0, 0, 1, wxEXPAND, 5 );
m_buttonApply = new wxButton( this, wxID_ANY, _("Apply, Save Schematic && Continue"), wxDefaultPosition, wxDefaultSize, 0 );
bButtonsSizer->Add( m_buttonApply, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
bButtonsSizer->Add( m_buttonApply, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
@@ -112,10 +112,10 @@ DIALOG_SYMBOL_FIELDS_TABLE_BASE::DIALOG_SYMBOL_FIELDS_TABLE_BASE( wxWindow* pare
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bButtonsSizer->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND|wxLEFT, 5 );
bButtonsSizer->Add( m_sdbSizer, 0, wxEXPAND|wxLEFT, 5 );
bMainSizer->Add( bButtonsSizer, 0, wxEXPAND, 5 );
bMainSizer->Add( bButtonsSizer, 0, wxBOTTOM|wxEXPAND|wxTOP, 5 );
this->SetSizer( bMainSizer );
@@ -191,7 +191,7 @@
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="0">
<property name="BottomDockable">1</property>
@@ -603,7 +603,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="flag">wxBOTTOM|wxEXPAND|wxTOP</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
@@ -622,7 +622,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
@@ -696,7 +696,7 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT</property>
<property name="flag">wxEXPAND|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxStdDialogButtonSizer" expanded="1">
<property name="Apply">0</property>
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -867,7 +867,7 @@ void DIALOG_SYMBOL_PROPERTIES::OnAddField( wxCommandEvent& event )
SCHEMATIC_SETTINGS& settings = m_symbol->Schematic()->Settings();
int fieldID = m_fields->size();
SCH_FIELD newField( wxPoint( 0, 0 ), fieldID, m_symbol,
TEMPLATE_FIELDNAME::GetDefaultFieldName( fieldID ) );
TEMPLATE_FIELDNAME::GetDefaultFieldName( fieldID, DO_TRANSLATE ) );
newField.SetTextAngle( m_fields->at( REFERENCE_FIELD ).GetTextAngle() );
newField.SetTextSize( wxSize( settings.m_DefaultTextSize, settings.m_DefaultTextSize ) );
@@ -47,7 +47,7 @@ DIALOG_UPDATE_SYMBOL_FIELDS::DIALOG_UPDATE_SYMBOL_FIELDS( SYMBOL_EDIT_FRAME* aPa
for( int i = 0; i < MANDATORY_FIELDS; ++i )
{
m_fieldsBox->Append( TEMPLATE_FIELDNAME::GetDefaultFieldName( i ) );
m_fieldsBox->Append( TEMPLATE_FIELDNAME::GetDefaultFieldName( i, DO_TRANSLATE ) );
m_fieldsBox->Check( i, true );
}
+4 -1
View File
@@ -356,7 +356,10 @@ void IFACE::SaveFileAs( const wxString& aProjectBasePath, const wxString& aProje
ext == KiCadSymbolLibFileExtension )
{
if( destFile.GetName() == aProjectName + wxT( "-cache" ) )
destFile.SetName( aNewProjectName + wxT( "-cache" ) );
destFile.SetName( aNewProjectName + wxT( "-cache" ) );
if( destFile.GetName() == aProjectName + wxT( "-rescue" ) )
destFile.SetName( aNewProjectName + wxT( "-rescue" ) );
KiCopyFile( aSrcFilePath, destFile.GetFullPath(), aErrors );
}
+1 -1
View File
@@ -389,7 +389,7 @@ wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
if( aRow < m_mandatoryFieldCount )
{
if( m_parentType == SCH_SYMBOL_T )
return TEMPLATE_FIELDNAME::GetDefaultFieldName( aRow );
return TEMPLATE_FIELDNAME::GetDefaultFieldName( aRow, DO_TRANSLATE );
else if( m_parentType == SCH_SHEET_T )
return SCH_SHEET::GetDefaultFieldName( aRow );
}
+12 -10
View File
@@ -4,7 +4,7 @@
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2013 CERN (www.cern.ch)
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -456,7 +456,6 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
// Legacy schematic can have duplicate time stamps so fix that before converting
// to the s-expression format.
schematic.ReplaceDuplicateTimeStamps();
schematic.SetLegacySymbolInstanceData();
// Allow the schematic to be saved to new file format without making any edits.
OnModify();
@@ -490,7 +489,6 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
{
DIALOG_MIGRATE_BUSES dlg( this );
dlg.ShowQuasiModal();
RecalculateConnections( NO_CLEANUP );
OnModify();
}
@@ -627,7 +625,8 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
allWildcards += "*." + formatWildcardExt( plugin->GetFileExtension() ) + ";";
}
fileFilters = _( "All supported formats|" ) + allWildcards + "|" + fileFilters;
fileFilters = _( "All supported formats" ) + wxS( "|" ) + allWildcards + wxS( "|" ) +
fileFilters;
wxFileDialog dlg( this, _( "Import Schematic" ), path, wxEmptyString, fileFilters,
wxFD_OPEN | wxFD_FILE_MUST_EXIST ); // TODO
@@ -1422,12 +1421,17 @@ void SCH_EDIT_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
" Auto save file: '%s'" ),
recoveredFn.GetFullPath(), backupFn.GetFullPath(), fn );
// Attempt to back up the last schematic file before overwriting it with the auto
// save file.
if( !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
if( !wxFileExists( fn ) )
{
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
}
// Attempt to back up the last schematic file before overwriting it with the auto
// save file.
else if( !wxCopyFile( recoveredFn.GetFullPath(), backupFn.GetFullPath() ) )
{
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
}
// Attempt to replace last saved file with auto save file
else if( !wxRenameFile( fn, recoveredFn.GetFullPath() ) )
{
unrecoveredFiles.Add( recoveredFn.GetFullPath() );
@@ -1455,10 +1459,8 @@ void SCH_EDIT_FRAME::CheckForAutoSaveFile( const wxFileName& aFileName )
{
wxLogTrace( traceAutoSave, wxT( "Removing auto save file " ) + fn );
if( !wxRemoveFile( fn ) )
{
if( wxFileExists( fn ) && !wxRemoveFile( fn ) )
unremovedFiles.Add( fn );
}
}
if( !unremovedFiles.IsEmpty() )
+5 -4
View File
@@ -403,10 +403,11 @@ wxString LIB_FIELD::GetCanonicalName() const
{
switch( m_id )
{
case REFERENCE_FIELD: return wxT( "Reference" );
case VALUE_FIELD: return wxT( "Value" );
case FOOTPRINT_FIELD: return wxT( "Footprint" );
case DATASHEET_FIELD: return wxT( "Datasheet" );
case REFERENCE_FIELD:
case VALUE_FIELD:
case FOOTPRINT_FIELD:
case DATASHEET_FIELD:
return TEMPLATE_FIELDNAME::GetDefaultFieldName( m_id );
}
return m_name;
+1 -1
View File
@@ -85,7 +85,7 @@ public:
void Init( int aId );
/**
* Return the field name.
* Return the field name (not translated).
*
* The first four field IDs are reserved and therefore always return their respective
* names.
+9 -29
View File
@@ -732,35 +732,6 @@ void LIB_SYMBOL::AddDrawItem( LIB_ITEM* aItem, bool aSort )
}
LIB_ITEM* LIB_SYMBOL::GetNextDrawItem( const LIB_ITEM* aItem, KICAD_T aType )
{
if( aItem == nullptr )
{
LIB_ITEMS_CONTAINER::ITERATOR it1 = m_drawings.begin( aType );
return (it1 != m_drawings.end( aType ) ) ? &( *( m_drawings.begin( aType ) ) ) : nullptr;
}
// Search for the last item, assume aItem is of type aType
wxASSERT( ( aType == TYPE_NOT_INIT ) || ( aType == aItem->Type() ) );
LIB_ITEMS_CONTAINER::ITERATOR it = m_drawings.begin( aType );
while( ( it != m_drawings.end( aType ) ) && ( aItem != &( *it ) ) )
++it;
// Search the next item
if( it != m_drawings.end( aType ) )
{
++it;
if( it != m_drawings.end( aType ) )
return &( *it );
}
return nullptr;
}
void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) const
{
/* Notes:
@@ -788,6 +759,15 @@ void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) const
}
std::vector<LIB_PIN*> LIB_SYMBOL::GetAllLibPins() const
{
std::vector<LIB_PIN*> pinList;
GetPins( pinList, 0, 0 );
return pinList;
}
LIB_PIN* LIB_SYMBOL::GetPin( const wxString& aNumber, int aUnit, int aConvert ) const
{
LIB_PINS pinList;
+6 -25
View File
@@ -367,35 +367,10 @@ public:
*/
void RemoveDrawItem( LIB_ITEM* aItem );
/**
* Return the next draw object pointer.
*
* @param aItem - Pointer to the current draw item. Setting item NULL
* with return the first item of type in the list.
* @param aType - type of searched item (filter).
* if TYPE_NOT_INIT search for all items types
* @return - The next drawing object in the list if found, otherwise NULL.
*/
LIB_ITEM* GetNextDrawItem( const LIB_ITEM* aItem = nullptr, KICAD_T aType = TYPE_NOT_INIT );
size_t GetPinCount() const { return m_drawings.size( LIB_PIN_T ); }
size_t GetFieldCount() const { return m_drawings.size( LIB_FIELD_T ); }
/**
* Return the next pin object from the draw list.
*
* This is just a pin object specific version of GetNextDrawItem().
*
* @param aItem - Pointer to the previous pin item, or NULL to get the
* first pin in the draw object list.
* @return - The next pin object in the list if found, otherwise NULL.
*/
LIB_PIN* GetNextPin( LIB_PIN* aItem = nullptr )
{
return (LIB_PIN*) GetNextDrawItem( (LIB_ITEM*) aItem, LIB_PIN_T );
}
/**
* Return a list of pin object pointers from the draw item list.
*
@@ -411,6 +386,12 @@ public:
*/
void GetPins( LIB_PINS& aList, int aUnit = 0, int aConvert = 0 ) const;
/**
* Return a list of pin pointers for all units / converts. Used primarily for SPICE where
* we want to treat all unit as a single part.
*/
std::vector<LIB_PIN*> GetAllLibPins() const;
/**
* Return pin object with the requested pin \a aNumber.
*
@@ -48,9 +48,6 @@ bool SCH_EDIT_FRAME::WriteNetListFile( int aFormat, const wxString& aFullFileNam
// Ensure all power symbols have a valid reference
Schematic().GetSheets().AnnotatePowerSymbols();
// Ensure the netlist data is up to date:
RecalculateConnections( NO_CLEANUP );
if( !ReadyToNetlist( _( "Exporting netlist requires a fully annotated schematic." ) ) )
return false;
+26 -5
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Chris Pavlina <pavlina.chris@gmail.com>
* Copyright (C) 2015-2022 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2015-2023 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -164,9 +164,22 @@ void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
case_sensitive_match = aRescuer.GetPrj()->SchLibs()->FindLibSymbol( id );
// If the case sensitive match failed, try a case insensitive match.
if( !case_sensitive_match )
aRescuer.GetPrj()->SchLibs()->FindLibraryNearEntries( case_insensitive_matches,
search_name );
if( case_sensitive_match )
continue;
aRescuer.GetPrj()->SchLibs()->FindLibraryNearEntries( case_insensitive_matches,
symbol_name );
// If there are not case insensitive matches either, the symbol cannot be rescued.
if( !case_insensitive_matches.size() )
continue;
RESCUE_CASE_CANDIDATE candidate( symbol_name, case_insensitive_matches[0]->GetName(),
case_insensitive_matches[0],
eachSymbol->GetUnit(),
eachSymbol->GetConvert() );
candidate_map[symbol_name] = candidate;
}
if( case_sensitive_match || !( case_insensitive_matches.size() ) )
@@ -198,6 +211,12 @@ wxString RESCUE_CASE_CANDIDATE::GetActionDescription() const
bool RESCUE_CASE_CANDIDATE::PerformAction( RESCUER* aRescuer )
{
wxCHECK( m_lib_candidate, true );
std::unique_ptr<LIB_SYMBOL> new_symbol = m_lib_candidate->Flatten();
new_symbol->SetName( m_new_name );
aRescuer->AddSymbol( new_symbol.get() );
for( SCH_SYMBOL* eachSymbol : *aRescuer->GetSymbols() )
{
if( eachSymbol->GetLibId().GetLibItemName() != UTF8( m_requested_name ) )
@@ -316,7 +335,9 @@ bool RESCUE_CACHE_CANDIDATE::PerformAction( RESCUER* aRescuer )
{
LIB_SYMBOL* tmp = ( m_cache_candidate ) ? m_cache_candidate : m_lib_candidate;
wxCHECK_MSG( tmp, false, wxT( "Both cache and library symbols undefined." ) );
// A symbol that cannot be rescued is a valid condition so just bail out here.
if( !tmp )
return true;
std::unique_ptr<LIB_SYMBOL> new_symbol = tmp->Flatten();
new_symbol->SetName( m_new_name );
-3
View File
@@ -443,9 +443,6 @@ void SCH_CONNECTION::AppendInfoToMsgPanel( std::vector<MSG_PANEL_ITEM>& aList )
#if defined(DEBUG)
// These messages are not flagged as translatable, because they are only debug messages
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
return;
if( IsBus() )
aList.emplace_back( wxT( "Bus Code" ), wxString::Format( wxT( "%d" ), m_bus_code ) );
+4 -6
View File
@@ -614,7 +614,8 @@ void SCH_EDIT_FRAME::SetCurrentSheet( const SCH_SHEET_PATH& aSheet )
void SCH_EDIT_FRAME::HardRedraw()
{
RecalculateConnections( LOCAL_CLEANUP );
if( Schematic().Settings().m_IntersheetRefsShow )
RecomputeIntersheetRefs();
FocusOnItem( nullptr );
@@ -838,10 +839,7 @@ void SCH_EDIT_FRAME::OnModify()
GetScreen()->SetContentModified();
if( ADVANCED_CFG::GetCfg().m_RealTimeConnectivity && CONNECTION_GRAPH::m_allowRealTime )
RecalculateConnections( NO_CLEANUP );
else
GetScreen()->SetConnectivityDirty();
RecalculateConnections( NO_CLEANUP );
GetCanvas()->Refresh();
UpdateHierarchyNavigator();
@@ -1252,7 +1250,7 @@ void SCH_EDIT_FRAME::AddItemToScreenAndUndoList( SCH_SCREEN* aScreen, SCH_ITEM*
}
// Update connectivity info for new item
if( !aItem->IsMoving() )
if( !aItem->IsMoving() && aItem->IsConnectable() )
{
RecalculateConnections( LOCAL_CLEANUP );
+1 -1
View File
@@ -94,7 +94,7 @@ public:
void DoHypertextMenu( EDA_DRAW_FRAME* aFrame ) override;
/**
* Return the field name.
* Return the field name (not translated)..
*
* @param aUseDefaultName When true return the default field name if the field name is
* empty. Otherwise the default field name is returned.
+10
View File
@@ -233,6 +233,16 @@ void SCH_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITE
}
bool SCH_PIN::IsStacked( const SCH_PIN* aPin ) const
{
return m_parent == aPin->GetParent()
&& GetTransformedPosition() == aPin->GetTransformedPosition()
&& ( ( GetType() == aPin->GetType() )
|| ( GetType() == ELECTRICAL_PINTYPE::PT_PASSIVE )
|| ( aPin->GetType() == ELECTRICAL_PINTYPE::PT_PASSIVE ) );
}
void SCH_PIN::ClearDefaultNetName( const SCH_SHEET_PATH* aPath )
{
std::lock_guard<std::recursive_mutex> lock( m_netmap_mutex );
+6
View File
@@ -98,6 +98,12 @@ public:
void SetIsDangling( bool isDangling ) { m_isDangling = isDangling; }
/**
* @param aPin Comparison Pin
* @return True if aPin is stacked with this pin
*/
bool IsStacked( const SCH_PIN* aPin ) const;
bool IsPointClickableAnchor( const wxPoint& aPos ) const override
{
return m_isDangling && GetPosition() == aPos;
@@ -650,7 +650,8 @@ void SCH_SEXPR_PARSER::parseEDA_TEXT( EDA_TEXT* aText, bool aConvertOverbarSynta
case T_right: aText->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT ); break;
case T_top: aText->SetVertJustify( GR_TEXT_VJUSTIFY_TOP ); break;
case T_bottom: aText->SetVertJustify( GR_TEXT_VJUSTIFY_BOTTOM ); break;
case T_mirror: aText->SetMirrored( true ); break;
// Do not set mirror property for schematic text elements
case T_mirror: break;
default: Expecting( "left, right, top, bottom, or mirror" );
}
}
@@ -536,7 +536,7 @@ SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchema
if( aAppendToMe )
{
wxLogTrace( traceSchLegacyPlugin, "Append \"%s\" to sheet \"%s\".",
wxLogTrace( traceSchPlugin, "Append \"%s\" to sheet \"%s\".",
aFileName, aAppendToMe->GetFileName() );
wxFileName normedFn = aAppendToMe->GetFileName();
@@ -550,7 +550,7 @@ SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchema
if( m_path.IsEmpty() )
m_path = aSchematic->Prj().GetProjectPath();
wxLogTrace( traceSchLegacyPlugin, "Normalized append path \"%s\".", m_path );
wxLogTrace( traceSchPlugin, "Normalized append path \"%s\".", m_path );
}
else
{
@@ -598,6 +598,8 @@ SCH_SHEET* SCH_SEXPR_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchema
void SCH_SEXPR_PLUGIN::loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SCH_SHEET* aSheet )
{
m_currentSheetPath.push_back( aSheet );
SCH_SCREEN* screen = nullptr;
if( !aSheet->GetScreen() )
@@ -613,10 +615,10 @@ void SCH_SEXPR_PLUGIN::loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SC
// Save the current path so that it gets restored when descending and ascending the
// sheet hierarchy which allows for sheet schematic files to be nested in folders
// relative to the last path a schematic was loaded from.
wxLogTrace( traceSchLegacyPlugin, "Saving path '%s'", m_currentPath.top() );
wxLogTrace( traceSchPlugin, "Saving path '%s'", m_currentPath.top() );
m_currentPath.push( fileName.GetPath() );
wxLogTrace( traceSchLegacyPlugin, "Current path '%s'", m_currentPath.top() );
wxLogTrace( traceSchLegacyPlugin, "Loading '%s'", fileName.GetFullPath() );
wxLogTrace( traceSchPlugin, "Current path '%s'", m_currentPath.top() );
wxLogTrace( traceSchPlugin, "Loading '%s'", fileName.GetFullPath() );
SCH_SHEET_PATH ancestorSheetPath = aParentSheetPath;
@@ -645,7 +647,12 @@ void SCH_SEXPR_PLUGIN::loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SC
}
if( ancestorSheetPath.empty() )
m_rootSheet->SearchHierarchy( fileName.GetFullPath(), &screen );
{
// Existing schematics could be either in the root sheet path or the current sheet
// load path so we have to check both.
if( !m_rootSheet->SearchHierarchy( fileName.GetFullPath(), &screen ) )
m_currentSheetPath.at( 0 )->SearchHierarchy( fileName.GetFullPath(), &screen );
}
if( screen )
{
@@ -702,8 +709,10 @@ void SCH_SEXPR_PLUGIN::loadHierarchy( const SCH_SHEET_PATH& aParentSheetPath, SC
}
m_currentPath.pop();
wxLogTrace( traceSchLegacyPlugin, "Restoring path \"%s\"", m_currentPath.top() );
wxLogTrace( traceSchPlugin, "Restoring path \"%s\"", m_currentPath.top() );
}
m_currentSheetPath.pop_back();
}
@@ -167,6 +167,7 @@ protected:
wxString m_path; ///< Root project path for loading child sheets.
std::stack<wxString> m_currentPath; ///< Stack to maintain nested sheet paths
SCH_SHEET* m_rootSheet; ///< The root sheet of the schematic being loaded.
SCH_SHEET_PATH m_currentSheetPath;
SCHEMATIC* m_schematic;
OUTPUTFORMATTER* m_out; ///< The formatter for saving SCH_SCREEN objects.
SCH_SEXPR_PLUGIN_CACHE* m_cache;
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Wayne Stambaugh <stambaughw@gmail.com>
*
@@ -4024,14 +4024,20 @@ void SCH_LEGACY_PLUGIN_CACHE::saveBezier( LIB_SHAPE* aBezier, OUTPUTFORMATTER& a
{
wxCHECK_RET( aBezier && aBezier->GetShape() == SHAPE_T::BEZIER, "Invalid BEZIER object." );
aFormatter.Print( 0, "B %u %d %d %d",
(unsigned)aBezier->GetBezierPoints().size(),
aFormatter.Print( 0, "B 4 %d %d %d",
aBezier->GetUnit(),
aBezier->GetConvert(),
Iu2Mils( aBezier->GetWidth() ) );
for( const wxPoint& pt : aBezier->GetBezierPoints() )
aFormatter.Print( 0, " %d %d", Iu2Mils( pt.x ), Iu2Mils( pt.y ) );
aFormatter.Print( 0, " %d %d %d %d %d %d %d %d",
Iu2Mils( aBezier->GetStart().x ),
Iu2Mils( aBezier->GetStart().y ),
Iu2Mils( aBezier->GetBezierC1().x ),
Iu2Mils( aBezier->GetBezierC1().y ),
Iu2Mils( aBezier->GetBezierC2().x ),
Iu2Mils( aBezier->GetBezierC2().y ),
Iu2Mils( aBezier->GetEnd().x ),
Iu2Mils( aBezier->GetEnd().y ) );
aFormatter.Print( 0, " %c\n", fill_tab[ static_cast<int>( aBezier->GetFillType() ) - 1 ] );
}
+87 -35
View File
@@ -4,7 +4,7 @@
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -145,14 +145,14 @@ bool SCH_SCREEN::ClassOf( const EDA_ITEM* aItem )
}
void SCH_SCREEN::Append( SCH_ITEM* aItem )
void SCH_SCREEN::Append( SCH_ITEM* aItem, bool aUpdateLibSymbol )
{
if( aItem->Type() != SCH_SHEET_PIN_T && aItem->Type() != SCH_FIELD_T )
{
// Ensure the item can reach the SCHEMATIC through this screen
aItem->SetParent( this );
if( aItem->Type() == SCH_SYMBOL_T )
if( aItem->Type() == SCH_SYMBOL_T && aUpdateLibSymbol )
{
SCH_SYMBOL* symbol = static_cast<SCH_SYMBOL*>( aItem );
@@ -179,30 +179,63 @@ void SCH_SCREEN::Append( SCH_ITEM* aItem )
if( *foundSymbol != *symbol->GetLibSymbolRef() )
{
int cnt = 1;
wxString newName;
std::vector<wxString> matches;
newName.Printf( wxT( "%s_%d" ), symbol->GetLibId().GetUniStringLibItemName(),
cnt );
getLibSymbolNameMatches( *symbol, matches );
foundSymbol = nullptr;
while( m_libSymbols.find( newName ) != m_libSymbols.end() )
for( const wxString& libSymbolName : matches )
{
cnt += 1;
newName.Printf( wxT( "%s_%d" ), symbol->GetLibId().GetUniStringLibItemName(),
cnt );
it = m_libSymbols.find( libSymbolName );
if( it == m_libSymbols.end() )
continue;
foundSymbol = it->second;
wxCHECK2( foundSymbol, continue );
if( *foundSymbol == *symbol->GetLibSymbolRef() )
{
newName = libSymbolName;
break;
}
foundSymbol = nullptr;
}
if( !foundSymbol )
{
int cnt = 1;
newName.Printf( wxT( "%s_%d" ),
symbol->GetLibId().GetUniStringLibItemName(),
cnt );
while( m_libSymbols.find( newName ) != m_libSymbols.end() )
{
cnt += 1;
newName.Printf( wxT( "%s_%d" ),
symbol->GetLibId().GetUniStringLibItemName(),
cnt );
}
}
// Update the schematic symbol library link as this symbol only exists
// in the schematic.
symbol->SetSchSymbolLibraryName( newName );
LIB_SYMBOL* newLibSymbol = new LIB_SYMBOL( *symbol->GetLibSymbolRef() );
LIB_ID newLibId( wxEmptyString, newName );
if( !foundSymbol )
{
// Update the schematic symbol library link as this symbol does not
// exist in any symbol library.
LIB_ID newLibId( wxEmptyString, newName );
LIB_SYMBOL* newLibSymbol = new LIB_SYMBOL( *symbol->GetLibSymbolRef() );
newLibSymbol->SetLibId( newLibId );
newLibSymbol->SetName( newName );
symbol->SetLibSymbol( newLibSymbol->Flatten().release() );
m_libSymbols[newName] = newLibSymbol;
newLibSymbol->SetLibId( newLibId );
newLibSymbol->SetName( newName );
symbol->SetLibSymbol( newLibSymbol->Flatten().release() );
m_libSymbols[newName] = newLibSymbol;
}
}
}
}
@@ -265,19 +298,19 @@ void SCH_SCREEN::FreeDrawList()
}
void SCH_SCREEN::Update( SCH_ITEM* aItem )
void SCH_SCREEN::Update( SCH_ITEM* aItem, bool aUpdateLibSymbol )
{
if( Remove( aItem ) )
Append( aItem );
if( Remove( aItem, aUpdateLibSymbol ) )
Append( aItem, aUpdateLibSymbol );
}
bool SCH_SCREEN::Remove( SCH_ITEM* aItem )
bool SCH_SCREEN::Remove( SCH_ITEM* aItem, bool aUpdateLibSymbol )
{
bool retv = m_rtree.remove( aItem );
// Check if the library symbol for the removed schematic symbol is still required.
if( retv && aItem->Type() == SCH_SYMBOL_T )
if( retv && aItem->Type() == SCH_SYMBOL_T && aUpdateLibSymbol )
{
SCH_SYMBOL* removedSymbol = static_cast<SCH_SYMBOL*>( aItem );
@@ -947,20 +980,16 @@ LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_SYMBOL** aSymbol,
if( !candidate->GetLibSymbolRef() )
continue;
for( pin = candidate->GetLibSymbolRef()->GetNextPin(); pin;
pin = candidate->GetLibSymbolRef()->GetNextPin( pin ) )
std::vector<LIB_PIN*> pins;
candidate->GetLibPins( pins );
for( LIB_PIN* test_pin : pins )
{
// Skip items not used for this part.
if( candidate->GetUnit() && pin->GetUnit() &&
( pin->GetUnit() != candidate->GetUnit() ) )
continue;
if( candidate->GetConvert() && pin->GetConvert() &&
( pin->GetConvert() != candidate->GetConvert() ) )
continue;
if( candidate->GetPinPhysicalPosition( pin ) == aPosition )
if( candidate->GetPinPhysicalPosition( test_pin ) == aPosition )
{
pin = test_pin;
break;
}
}
if( pin )
@@ -1202,6 +1231,29 @@ void SCH_SCREEN::SetLegacySymbolInstanceData()
}
size_t SCH_SCREEN::getLibSymbolNameMatches( const SCH_SYMBOL& aSymbol,
std::vector<wxString>& aMatches )
{
wxString searchName = aSymbol.GetLibId().GetUniStringLibId();
if( m_libSymbols.find( searchName ) != m_libSymbols.end() )
aMatches.emplace_back( searchName );
searchName = aSymbol.GetLibId().GetUniStringLibItemName() + wxS( "_" );
long tmp;
wxString suffix;
for( auto pair : m_libSymbols )
{
if( pair.first.StartsWith( searchName, &suffix ) && suffix.ToLong( &tmp ) )
aMatches.emplace_back( pair.first );
}
return aMatches.size();
}
#if defined(DEBUG)
void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
{
+23 -6
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -181,7 +181,7 @@ public:
return m_clientSheetPathList;
}
void Append( SCH_ITEM* aItem );
void Append( SCH_ITEM* aItem, bool aUpdateLibSymbol = true );
/**
* Copy the contents of \a aScreen into this #SCH_SCREEN object.
@@ -264,16 +264,18 @@ public:
*
* @note The removed item is not deleted. It is only unlinked from the item list.
* @param[in] aItem Item to be removed from schematic.
* @param aUpdateLibSymbol removes the library symbol as required when true.
* @return True if we successfully removed the item
*/
bool Remove( SCH_ITEM* aItem );
bool Remove( SCH_ITEM* aItem, bool aUpdateLibSymbol = true );
/**
* Update \a aItem's bounding box in the tree
*
* @param[in] aItem Item that needs to be updated.
* @param aUpdateLibSymbol removes the library symbol as required when true.
*/
void Update( SCH_ITEM* aItem );
void Update( SCH_ITEM* aItem, bool aUpdateLibSymbol = true );
/**
* Removes \a aItem from the linked list and deletes the object.
@@ -516,13 +518,28 @@ private:
bool doIsJunction( const wxPoint& aPosition, bool aBreakCrossings,
bool* aHasExplicitJunctionDot, bool* aHasBusEntry ) const;
void clearLibSymbols();
/**
* Return a list of potential library symbol matches for \a aSymbol.
*
* When and existing library symbol named with the full #LIB_ID object is found, there may
* be more potential matches if the #SCH_SCREEN::Append() method need to create an alternate
* symbol due to differences from the original symbol. This process creates a new library
* symbol name by adding a "_#" suffix to the existing #LIB_ID item name.
*
* @param[in] aSymbol is the schematic symbol to search for potential library symbol matches.
* @param[out] aMatches contains library cache names of all of the potential matches.
*
* @return the number of potential matches found for \a aSymbol.
*/
size_t getLibSymbolNameMatches( const SCH_SYMBOL& aSymbol, std::vector<wxString>& aMatches );
private:
friend SCH_EDIT_FRAME; // Only to populate m_symbolInstances.
friend SCH_SEXPR_PARSER; // Only to load instance information from schematic file.
friend SCH_SEXPR_PLUGIN; // Only to save the loaded instance information to schematic file.
void clearLibSymbols();
wxString m_fileName; // File used to load the screen.
int m_fileFormatVersionAtLoad;
int m_refCount; // Number of sheets referencing this screen.
+3 -18
View File
@@ -52,11 +52,6 @@
const wxString SCH_SHEET::GetDefaultFieldName( int aFieldNdx, bool aTranslated )
{
static void* locale = nullptr;
static wxString sheetnameDefault;
static wxString sheetfilenameDefault;
static wxString userFieldDefault;
if( !aTranslated )
{
switch( aFieldNdx )
@@ -67,22 +62,12 @@ const wxString SCH_SHEET::GetDefaultFieldName( int aFieldNdx, bool aTranslated )
}
}
// Fetching translations can take a surprising amount of time when loading libraries,
// so only do it when necessary.
if( Pgm().GetLocale() != locale )
{
sheetnameDefault = _( SHEET_NAME_CANONICAL );
sheetfilenameDefault = _( SHEET_FILE_CANONICAL );
userFieldDefault = _( USER_FIELD_CANONICAL );
locale = Pgm().GetLocale();
}
// Fixed values for the mandatory fields
switch( aFieldNdx )
{
case SHEETNAME: return sheetnameDefault;
case SHEETFILENAME: return sheetfilenameDefault;
default: return wxString::Format( userFieldDefault, aFieldNdx );
case SHEETNAME: return _( SHEET_NAME_CANONICAL );
case SHEETFILENAME: return _( SHEET_FILE_CANONICAL );
default: return wxString::Format( _( USER_FIELD_CANONICAL ), aFieldNdx );
}
}
+2 -2
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -310,7 +310,7 @@ void SCH_SHEET_PATH::UpdateAllScreenReferences()
symbol->GetField( VALUE_FIELD )->SetText( symbol->GetValue( this, false ) );
symbol->GetField( FOOTPRINT_FIELD )->SetText( symbol->GetFootprint( this, false ) );
symbol->UpdateUnit( symbol->GetUnitSelection( this ) );
LastScreen()->Update( item );
LastScreen()->Update( item, false );
}
}
+5 -3
View File
@@ -335,10 +335,12 @@ void SCH_SYMBOL::UpdatePins()
unsigned i = 0;
for( LIB_PIN* libPin = m_part->GetNextPin(); libPin; libPin = m_part->GetNextPin( libPin ) )
{
wxASSERT( libPin->Type() == LIB_PIN_T );
std::vector<LIB_PIN*> pins = m_part->GetAllLibPins();
for( LIB_PIN* libPin : pins )
{
// NW: Don't filter by unit: this data-structure is used for all instances,
// some if which might have different units.
if( libPin->GetConvert() && m_convert && ( m_convert != libPin->GetConvert() ) )
continue;
+20
View File
@@ -665,6 +665,26 @@ wxString SCH_TEXT::GetShownText( int aDepth, bool aAllowExtraText ) const
}
bool SCH_TEXT::Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const
{
return SCH_ITEM::Matches( UnescapeString( GetText() ), aSearchData );
}
bool SCH_TEXT::Replace( const wxFindReplaceData& aSearchData, void* aAuxData )
{
wxFindReplaceData localSearchData( aSearchData );
if( Type() == SCH_LABEL_T || Type() == SCH_HIER_LABEL_T || Type() == SCH_GLOBAL_LABEL_T )
{
localSearchData.SetFindString( EscapeString( aSearchData.GetFindString(), CTX_NETNAME ) );
localSearchData.SetReplaceString( EscapeString( aSearchData.GetReplaceString(), CTX_NETNAME ) );
}
return EDA_TEXT::Replace( localSearchData );
}
wxString SCH_TEXT::GetSelectMenuText( EDA_UNITS aUnits ) const
{
return wxString::Format( _( "Graphic Text '%s'" ), ShortenedShownText() );
+2 -9
View File
@@ -210,15 +210,8 @@ public:
virtual void Rotate90( bool aClockwise );
virtual void MirrorSpinStyle( bool aLeftRight );
bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override
{
return SCH_ITEM::Matches( GetText(), aSearchData );
}
bool Replace( const wxFindReplaceData& aSearchData, void* aAuxData ) override
{
return EDA_TEXT::Replace( aSearchData );
}
bool Matches( const wxFindReplaceData& aSearchData, void* aAuxData ) const override;
bool Replace( const wxFindReplaceData& aSearchData, void* aAuxData ) override;
virtual bool IsReplaceable() const override { return true; }
+2
View File
@@ -714,6 +714,8 @@ void SYMBOL_EDIT_FRAME::saveSymbolAs()
return;
}
new_name = EscapeString( new_name, CTX_LIBID );
// Test if there is a symbol with this name already.
if( m_libMgr->SymbolExists( new_name, new_lib ) )
{
+7 -3
View File
@@ -676,7 +676,7 @@ int SCH_EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &selectionCopy );
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selectionCopy );
m_frame->RecalculateConnections( LOCAL_CLEANUP );
m_frame->SchematicCleanUp();
m_frame->TestDanglingEnds();
m_frame->OnModify();
@@ -920,7 +920,7 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &new_sel );
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &new_sel );
m_frame->RecalculateConnections( LOCAL_CLEANUP );
m_frame->SchematicCleanUp();
m_frame->TestDanglingEnds();
}
@@ -1122,7 +1122,11 @@ void SCH_EDIT_TOOL::editFieldText( SCH_FIELD* aField )
// Use title caps for mandatory fields. "Edit Sheet name Field" looks dorky.
if( parentType == SCH_SYMBOL_T && aField->GetId() < MANDATORY_FIELDS )
caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
{
wxString translated_fieldname;
translated_fieldname = TEMPLATE_FIELDNAME::GetDefaultFieldName( aField->GetId(), DO_TRANSLATE );
caption.Printf( _( "Edit %s Field" ), TitleCaps( translated_fieldname ) );
}
else if( parentType == SCH_SHEET_T && aField->GetId() < SHEET_MANDATORY_FIELDS )
caption.Printf( _( "Edit %s Field" ), TitleCaps( aField->GetName() ) );
else
+21 -54
View File
@@ -228,9 +228,6 @@ int SCH_EDITOR_CONTROL::RemapSymbols( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::Print( const TOOL_EVENT& aEvent )
{
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
m_frame->RecalculateConnections( NO_CLEANUP );
InvokeDialogPrintUsingPrinter( m_frame );
wxFileName fn = m_frame->Prj().AbsolutePath( m_frame->Schematic().RootScreen()->GetFileName() );
@@ -244,9 +241,6 @@ int SCH_EDITOR_CONTROL::Print( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::Plot( const TOOL_EVENT& aEvent )
{
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
m_frame->RecalculateConnections( NO_CLEANUP );
DIALOG_PLOT_SCHEMATIC dlg( m_frame );
dlg.ShowModal();
@@ -346,15 +340,32 @@ SCH_ITEM* SCH_EDITOR_CONTROL::nextMatch( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aS
if( aAfter != nullptr )
{
past_item = false;
if( aAfter->Type() == SCH_PIN_T || aAfter->Type() == SCH_FIELD_T )
aAfter = static_cast<SCH_ITEM*>( aAfter->GetParent() );
}
std::vector<SCH_ITEM*> sorted_items;
for( SCH_ITEM* item : aScreen->Items() )
{
if( SCH_SYMBOL* sym = dyn_cast<SCH_SYMBOL*>( item ) )
{
for( SCH_FIELD& field : sym->GetFields() )
sorted_items.push_back( &field );
for( SCH_PIN* pin : sym->GetPins() )
sorted_items.push_back( pin );
}
if( SCH_SHEET* sheet = dyn_cast<SCH_SHEET*>( item ) )
{
for( SCH_FIELD& field : sheet->GetFields() )
sorted_items.push_back( &field );
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
sorted_items.push_back( pin );
}
sorted_items.push_back( item );
}
std::sort( sorted_items.begin(), sorted_items.end(),
[&]( SCH_ITEM* a, SCH_ITEM* b )
@@ -385,40 +396,6 @@ SCH_ITEM* SCH_EDITOR_CONTROL::nextMatch( SCH_SCREEN* aScreen, SCH_SHEET_PATH* aS
if( item->Matches( aData, aSheet ) )
return item;
if( item->Type() == SCH_SYMBOL_T )
{
SCH_SYMBOL* cmp = static_cast<SCH_SYMBOL*>( item );
for( SCH_FIELD& field : cmp->GetFields() )
{
if( field.Matches( aData, aSheet ) )
return &field;
}
for( SCH_PIN* pin : cmp->GetPins() )
{
if( pin->Matches( aData, aSheet ) )
return pin;
}
}
if( item->Type() == SCH_SHEET_T )
{
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( item );
for( SCH_FIELD& field : sheet->GetFields() )
{
if( field.Matches( aData, aSheet ) )
return &field;
}
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
{
if( pin->Matches( aData, aSheet ) )
return pin;
}
}
}
}
@@ -1061,10 +1038,6 @@ int SCH_EDITOR_CONTROL::AssignNetclass( const TOOL_EVENT& aEvent )
KIGFX::VIEW_CONTROLS* controls = getViewControls();
VECTOR2D cursorPos = controls->GetCursorPosition( !aEvent.DisableGridSnapping() );
// TODO remove once real-time connectivity is a given
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
// Ensure the netlist data is up to date:
m_frame->RecalculateConnections( NO_CLEANUP );
// Remove selection in favor of highlighting so the whole net is highlighted
selectionTool->ClearSelection();
@@ -1314,10 +1287,6 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent )
{
// TODO(JE) remove once real-time connectivity is a given
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
m_frame->RecalculateConnections( NO_CLEANUP );
std::string tool = aEvent.GetCommandStr().get();
PICKER_TOOL* picker = m_toolMgr->GetTool<PICKER_TOOL>();
@@ -2090,9 +2059,7 @@ int SCH_EDITOR_CONTROL::GenerateBOM( const TOOL_EVENT& aEvent )
int SCH_EDITOR_CONTROL::DrawSheetOnClipboard( const TOOL_EVENT& aEvent )
{
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
m_frame->RecalculateConnections( LOCAL_CLEANUP );
m_frame->RecalculateConnections( LOCAL_CLEANUP );
m_frame->DrawCurrentSheetToClipboard();
return 0;
}
-11
View File
@@ -93,7 +93,6 @@ protected:
private:
void update() override
{
SCH_EDIT_FRAME* frame = (SCH_EDIT_FRAME*) getToolManager()->GetToolHolder();
EE_SELECTION_TOOL* selTool = getToolManager()->GetTool<EE_SELECTION_TOOL>();
KICAD_T busType[] = { SCH_LINE_LOCATE_BUS_T, EOT };
EE_SELECTION& selection = selTool->RequestSelection( busType );
@@ -101,16 +100,6 @@ private:
Clear();
// TODO(JE) remove once real-time is enabled
if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
{
frame->RecalculateConnections( NO_CLEANUP );
// Pick up the pointer again because it may have been changed by SchematicCleanUp
selection = selTool->RequestSelection( busType );
bus = (SCH_LINE*) selection.Front();
}
if( !bus )
{
Append( ID_POPUP_SCH_UNFOLD_BUS, _( "No bus selected" ), wxEmptyString );
+8 -2
View File
@@ -47,6 +47,7 @@
SCH_MOVE_TOOL::SCH_MOVE_TOOL() :
EE_TOOL_BASE<SCH_EDIT_FRAME>( "eeschema.InteractiveMove" ),
m_inMoveTool( false ),
m_moveInProgress( false ),
m_isDrag( false ),
m_moveOffset( 0, 0 )
@@ -126,6 +127,11 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
return 0;
}
if( m_inMoveTool ) // Must come after m_moveInProgress checks above...
return 0;
REENTRANCY_GUARD guard( &m_inMoveTool );
// Be sure that there is at least one item that we can move. If there's no selection try
// looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection).
EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::MovableItems );
@@ -528,7 +534,7 @@ int SCH_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &selectionCopy );
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selectionCopy );
m_frame->RecalculateConnections( LOCAL_CLEANUP );
m_frame->SchematicCleanUp();
m_frame->TestDanglingEnds();
m_frame->OnModify();
@@ -1003,7 +1009,7 @@ int SCH_MOVE_TOOL::AlignElements( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &selection );
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &selection );
m_frame->RecalculateConnections( LOCAL_CLEANUP );
m_frame->SchematicCleanUp();
m_frame->TestDanglingEnds();
m_frame->OnModify();
+3
View File
@@ -81,6 +81,9 @@ private:
void setTransitions() override;
private:
///< Re-entrancy guard
bool m_inMoveTool;
///< Flag determining if anything is being dragged right now
bool m_moveInProgress;
bool m_isDrag;
+2 -2
View File
@@ -457,8 +457,8 @@ int SYMBOL_EDITOR_CONTROL::ExportSymbolAsSVG( const TOOL_EVENT& aEvent )
editFrame->GetConvert() ).GetSize();
// Add a small margin to the plot bounding box
pageTemp.SetWidthMils( int( symbolSize.x * 1.2 ) );
pageTemp.SetHeightMils( int( symbolSize.y * 1.2 ) );
pageTemp.SetWidthMils( Iu2Mils( symbolSize.x * 1.2 ) );
pageTemp.SetHeightMils( Iu2Mils( symbolSize.y * 1.2 ) );
editFrame->GetScreen()->SetPageSettings( pageTemp );
editFrame->SVGPlotSymbol( fullFileName );
@@ -536,10 +536,15 @@ int SYMBOL_EDITOR_DRAWING_TOOLS::RepeatDrawItem( const TOOL_EVENT& aEvent )
return 0;
// See if we have a pin matching our weak ptr
for( LIB_PIN* test = symbol->GetNextPin(); test; test = symbol->GetNextPin( test ) )
std::vector<LIB_PIN*> pins = symbol->GetAllLibPins();
for( LIB_PIN* test : pins )
{
if( (void*) test == g_lastPinWeakPtr )
{
sourcePin = test;
break;
}
}
if( sourcePin )
+9 -12
View File
@@ -282,30 +282,27 @@ int SYMBOL_EDITOR_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
int curr_convert = pin->GetConvert();
ELECTRICAL_PINTYPE etype = pin->GetType();
wxString name = pin->GetName();
LIB_PIN* next_pin = symbol->GetNextPin();
std::vector<LIB_PIN*> pins = symbol->GetAllLibPins();
while( next_pin != nullptr )
for( LIB_PIN* test_pin : pins )
{
pin = next_pin;
next_pin = symbol->GetNextPin( pin );
if( got_unit[pin->GetUnit()] )
if( got_unit[test_pin->GetUnit()] )
continue;
if( pin->GetPosition() != pos )
if( test_pin->GetPosition() != pos )
continue;
if( pin->GetConvert() != curr_convert )
if( test_pin->GetConvert() != curr_convert )
continue;
if( pin->GetType() != etype )
if( test_pin->GetType() != etype )
continue;
if( pin->GetName() != name )
if( test_pin->GetName() != name )
continue;
toDelete.insert( pin );
got_unit[pin->GetUnit()] = true;
toDelete.insert( test_pin );
got_unit[test_pin->GetUnit()] = true;
}
}
}
+3 -2
View File
@@ -160,8 +160,9 @@ int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
got_unit[cur_pin->GetUnit()] = true;
for( LIB_PIN* pin = symbol->GetNextPin(); pin;
pin = symbol->GetNextPin( pin ) )
std::vector<LIB_PIN*> pins = symbol->GetAllLibPins();
for( LIB_PIN* pin : pins )
{
if( !got_unit[pin->GetUnit()]
&& pin->GetPosition() == cur_pin->GetPosition()
+6 -3
View File
@@ -221,7 +221,9 @@ bool SYMBOL_EDITOR_PIN_TOOL::PlacePin( LIB_PIN* aPin )
LIB_SYMBOL* symbol = m_frame->GetCurSymbol();
bool ask_for_pin = true; // Test for another pin in same position in other units
for( LIB_PIN* test = symbol->GetNextPin(); test; test = symbol->GetNextPin( test ) )
std::vector<LIB_PIN*> pins = symbol->GetAllLibPins();
for( LIB_PIN* test : pins )
{
if( test == aPin || aPin->GetPosition() != test->GetPosition() || test->GetEditFlags() )
continue;
@@ -270,7 +272,7 @@ bool SYMBOL_EDITOR_PIN_TOOL::PlacePin( LIB_PIN* aPin )
}
// Put linked pins in new position, and clear flags
for( LIB_PIN* pin = symbol->GetNextPin(); pin; pin = symbol->GetNextPin( pin ) )
for( LIB_PIN* pin : pins )
{
if( ( pin->GetEditFlags() & IS_LINKED ) == 0 )
continue;
@@ -383,8 +385,9 @@ int SYMBOL_EDITOR_PIN_TOOL::PushPinProperties( const TOOL_EVENT& aEvent )
return 0;
saveCopyInUndoList( symbol, UNDO_REDO::LIBEDIT );
std::vector<LIB_PIN*> pins = symbol->GetAllLibPins();
for( LIB_PIN* pin = symbol->GetNextPin(); pin; pin = symbol->GetNextPin( pin ) )
for( LIB_PIN* pin : pins )
{
if( pin == sourcePin )
continue;
+3
View File
@@ -506,6 +506,9 @@ bool GERBVIEW_FRAME::unarchiveFiles( const wxString& aFullFileName, REPORTER* aR
while( ( entry = zipArchive.GetNextEntry() ) )
{
if( entry->IsDir() )
continue;
wxString fname = entry->GetName();
wxFileName uzfn = fname;
wxString curr_ext = uzfn.GetExt().Lower();
-5
View File
@@ -107,11 +107,6 @@ public:
*/
double m_HoleWallThickness;
/**
* Do real-time connectivity
*/
bool m_RealTimeConnectivity;
/**
* Set the stack size for coroutines
*/
+1 -1
View File
@@ -980,7 +980,7 @@ inline bool IsNetnameLayer( LAYER_NUM aLayer )
}
inline bool IsZoneLayer( LAYER_NUM aLayer )
inline bool IsZoneFillLayer( int aLayer )
{
return aLayer >= LAYER_ZONE_START && aLayer <= LAYER_ZONE_END;
}
+7
View File
@@ -221,6 +221,13 @@ public:
*/
void RunOnDescendants( const std::function<void( BOARD_ITEM* )>& aFunction ) const;
/**
* Check if the proposed type can be added to a group
* @param aType KICAD_T type to check
* @return true if the type can belong to a group, false otherwise
*/
static bool IsGroupableType( KICAD_T aType );
private:
std::unordered_set<BOARD_ITEM*> m_items; // Members of the group
wxString m_name; // Optional group name
+7 -3
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2014-2020 KiCad Developers, see AUTHORS.TXT for contributors.
* Copyright (C) 2014-2022 KiCad Developers, see AUTHORS.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -50,6 +50,9 @@ enum MANDATORY_FIELD_T {
MANDATORY_FIELDS
};
// A helper to call GetDefaultFieldName with or without translation.
// Translation should be used only to display field names in dialogs
#define DO_TRANSLATE true
/**
* Hold a name of a symbol's field, field value, and default visibility.
@@ -103,9 +106,10 @@ struct TEMPLATE_FIELDNAME
* These field names are not modifiable but template field names are.
*
* @param aFieldNdx The field number index, > 0.
* @param aTranslate If true, return the translated field name, else get the canonical name.
* @param aTranslateForHI If true, return the translated field name,
* else get the canonical name (defualt). Translation is intended only for dialogs
*/
static const wxString GetDefaultFieldName( int aFieldNdx, bool aTranslate = true );
static const wxString GetDefaultFieldName( int aFieldNdx, bool aTranslateForHI = false );
wxString m_Name; // The field name
bool m_Visible; // Field defaults to being visible in schematic.
+7
View File
@@ -106,6 +106,13 @@ extern const wxChar* const traceAutoSave;
*/
extern const wxChar* const traceSchLibMem;
/**
* Flag to enable legacy schematic plugin debug output.
*
* Use "KICAD_SCH_PLUGIN" to enable.
*/
extern const wxChar* const traceSchPlugin;
/**
* Flag to enable legacy schematic plugin debug output.
*
+2 -1
View File
@@ -151,8 +151,9 @@ private:
* It is mostly used for notifying the tools that the cursor position in the world
* coordinates has changed, whereas the screen coordinates remained the same (e.g.
* frame edge autopanning).
* @param aSetModifiers If false, don't change the modifiers (they were set using the keyboard motion)
*/
void refreshMouse();
void refreshMouse( bool aSetModifiers);
/**
* Get the cursor position in the screen coordinates.
+2 -1
View File
@@ -69,7 +69,8 @@ void KICAD_MANAGER_FRAME::ImportNonKiCadProject( const wxString& aWindowTitle,
// OK, we got a new project to open. Time to close any existing project before we go on
// to collect info about where to put the new one, etc. Otherwise the workflow is kind of
// disjoint.
CloseProject( true );
if( !CloseProject( true ) )
return;
wxFileName sch( schdlg.GetPath() );
sch.SetExt( aSchFileExtension );
+6
View File
@@ -438,6 +438,12 @@ double SHAPE_ARC::GetLength() const
double SHAPE_ARC::GetCentralAngle() const
{
// Arcs with same start and end points can be 0 deg or 360 deg arcs.
// However, they are expected to be circles.
// So return 360 degrees as central arc:
if( m_start == m_end )
return 360.0;
VECTOR2I center = GetCenter();
VECTOR2I p0 = m_start - center;
VECTOR2I p1 = m_mid - center;
+1
View File
@@ -18,6 +18,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cstdint>
#include <array>
#include <vector>
#include <string>
+4 -2
View File
@@ -239,13 +239,15 @@ std::vector<PCB_MARKER*> BOARD::ResolveDRCExclusions()
bool BOARD::ResolveTextVar( wxString* token, int aDepth ) const
{
wxString var = *token;
if( GetTitleBlock().TextVarResolver( token, m_project ) )
{
return true;
}
else if( m_properties.count( *token ) )
else if( m_properties.count( var ) )
{
*token = m_properties.at( *token );
*token = m_properties.at( var );
return true;
}
+4 -1
View File
@@ -165,8 +165,11 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry, bool a
{
case CHT_ADD:
{
if( selTool->GetEnteredGroup() && !boardItem->GetParentGroup() )
if( selTool && selTool->GetEnteredGroup() && !boardItem->GetParentGroup()
&& PCB_GROUP::IsGroupableType( boardItem->Type() ) )
{
selTool->GetEnteredGroup()->AddItem( boardItem );
}
if( m_isFootprintEditor )
{
@@ -70,6 +70,7 @@ DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR(
m_solderPasteRatio( aParent, m_PasteMarginRatioLabel, m_PasteMarginRatioCtrl,
m_PasteMarginRatioUnits )
{
SetEvtHandlerEnabled( false );
// Create the 3D models page
m_3dPanel = new PANEL_FP_PROPERTIES_3D_MODEL( m_frame, m_footprint, this, m_NoteBook );
m_NoteBook->AddPage( m_3dPanel, _("3D Models"), false );
@@ -145,6 +146,7 @@ DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR::DIALOG_FOOTPRINT_PROPERTIES_FP_EDITOR(
nullptr, this );
finishDialogSettings();
SetEvtHandlerEnabled( true );
}
+1 -1
View File
@@ -88,7 +88,7 @@ bool DRC_RULE_CONDITION::EvaluateFor( const BOARD_ITEM* aItemA, const BOARD_ITEM
bool DRC_RULE_CONDITION::Compile( REPORTER* aReporter, int aSourceLine, int aSourceOffset )
{
PCB_EXPR_COMPILER compiler;
PCB_EXPR_COMPILER compiler( new PCB_UNIT_RESOLVER() );
if( aReporter )
{
+9 -5
View File
@@ -297,6 +297,8 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
reportError( msg );
}
bool unitless = c.m_Type == VIA_COUNT_CONSTRAINT;
if( c.m_Type == DISALLOW_CONSTRAINT )
{
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
@@ -355,7 +357,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
break;
}
parseValueWithUnits( FromUTF8(), value );
parseValueWithUnits( FromUTF8(), value, unitless );
c.m_Value.SetMin( value );
if( (int) NextTok() != DSN_RIGHT )
@@ -375,7 +377,8 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
break;
}
parseValueWithUnits( FromUTF8(), value );
parseValueWithUnits( FromUTF8(), value, unitless );
c.m_Value.SetMax( value );
if( (int) NextTok() != DSN_RIGHT )
@@ -395,7 +398,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
break;
}
parseValueWithUnits( FromUTF8(), value );
parseValueWithUnits( FromUTF8(), value, unitless );
c.m_Value.SetOpt( value );
if( (int) NextTok() != DSN_RIGHT )
@@ -426,7 +429,7 @@ void DRC_RULES_PARSER::parseConstraint( DRC_RULE* aRule )
}
void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult )
void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult, bool aUnitless )
{
auto errorHandler = [&]( const wxString& aMessage, int aOffset )
{
@@ -449,7 +452,8 @@ void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult
}
};
PCB_EXPR_EVALUATOR evaluator;
PCB_EXPR_EVALUATOR evaluator( aUnitless ? (LIBEVAL::UNIT_RESOLVER*) new PCB_UNITLESS_RESOLVER()
: (LIBEVAL::UNIT_RESOLVER*) new PCB_UNIT_RESOLVER() );
evaluator.SetErrorCallback( errorHandler );
evaluator.Evaluate( aExpr );
+1 -1
View File
@@ -49,7 +49,7 @@ private:
DRC_RULE* parseDRC_RULE();
void parseConstraint( DRC_RULE* aRule );
void parseValueWithUnits( const wxString& aExpr, int& aResult );
void parseValueWithUnits( const wxString& aExpr, int& aResult, bool aUnitless = false );
LSET parseLayer();
void parseUnknown();
@@ -83,6 +83,14 @@ public:
int GetNumPhases() const override;
private:
/**
* Checks for track/via/hole <-> clearance
* @param track Track to text
* @param trackShape Primitive track shape
* @param layer Which layer to test (in case of vias this can be multiple
* @param other item against which to test the track item
* @return false if there is a clearance violation reported, true if there is none
*/
bool testTrackAgainstItem( PCB_TRACK* track, SHAPE* trackShape, PCB_LAYER_ID layer,
BOARD_ITEM* other );
@@ -96,6 +104,18 @@ private:
void testItemAgainstZones( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer );
typedef struct checked
{
checked()
: layers(), has_error( false ) {}
checked( PCB_LAYER_ID aLayer )
: layers( aLayer ), has_error( false ) {}
LSET layers;
bool has_error;
} layers_checked;
private:
DRC_RTREE m_copperTree;
int m_drcEpsilon;
@@ -267,6 +287,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
int clearance = -1;
int actual;
VECTOR2I pos;
bool has_error = false;
std::shared_ptr<SHAPE> otherShape = DRC_ENGINE::GetShape( other, layer );
@@ -300,7 +321,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
reportViolation( drcItem, (wxPoint) intersection.get() );
return m_drcEngine->GetReportAllTrackErrors();
return false;
}
}
@@ -319,6 +340,7 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
drce->SetViolatingRule( constraint.GetParentRule() );
reportViolation( drce, (wxPoint) pos );
has_error = true;
if( !m_drcEngine->GetReportAllTrackErrors() )
return false;
@@ -330,14 +352,12 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
std::array<BOARD_ITEM*, 2> a{ track, other };
std::array<BOARD_ITEM*, 2> b{ other, track };
std::array<SHAPE*, 2> a_shape{ trackShape, otherShape.get() };
bool has_error = false;
for( size_t ii = 0; ii < 2 && !has_error; ++ii )
for( size_t ii = 0; ii < 2; ++ii )
{
std::unique_ptr<SHAPE_SEGMENT> holeShape;
bool has_hole = b[ii]->Type() == PCB_VIA_T ||
bool has_hole = b[ii]->Type() == PCB_VIA_T ||
( b[ii]->Type() == PCB_PAD_T && static_cast<PAD*>( b[ii] )->GetDrillSize().x );
// We only test a track item here against an item with a hole.
@@ -385,16 +405,13 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
drce->SetViolatingRule( constraint.GetParentRule() );
reportViolation( drce, (wxPoint) pos );
has_error = true;
if( !m_drcEngine->GetReportAllTrackErrors() )
return false;
return false;
}
}
}
}
return true;
return !has_error;
}
@@ -532,7 +549,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
reportAux( wxT( "Testing %d tracks & vias..." ), m_board->Tracks().size() );
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, LSET> checkedPairs;
std::map<BOARD_ITEM*, int> freePadsUsageMap;
std::map< std::pair<BOARD_ITEM*, BOARD_ITEM*>, layers_checked> checkedPairs;
for( PCB_TRACK* track : m_board->Tracks() )
{
@@ -567,20 +585,59 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
auto it = checkedPairs.find( { a, b } );
if( it != checkedPairs.end() && it->second.test( layer ) )
if( it != checkedPairs.end() && ( it->second.layers.test( layer )
|| ( it->second.has_error && !m_drcEngine->GetReportAllTrackErrors() ) ) )
{
return false;
}
else
{
checkedPairs[ { a, b } ].set( layer );
checkedPairs[ { a, b } ].layers.set( layer );
return true;
}
},
// Visitor:
[&]( BOARD_ITEM* other ) -> bool
{
return testTrackAgainstItem( track, trackShape.get(), layer, other );
if( other->Type() == PCB_PAD_T && static_cast<PAD*>( other )->IsFreePad() )
{
if( other->GetEffectiveShape( layer )->Collide( trackShape.get() ) )
{
auto it = freePadsUsageMap.find( other );
if( it == freePadsUsageMap.end() )
{
freePadsUsageMap[ other ] = track->GetNetCode();
return false;
}
else if( it->second == track->GetNetCode() )
{
return false;
}
}
}
BOARD_ITEM* a = track;
BOARD_ITEM* b = other;
// store canonical order so we don't collide in both directions
// (a:b and b:a)
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
std::swap( a, b );
auto it = checkedPairs.find( { a, b } );
// If we get an error, mark the pair as having a clearance error already
// Only continue if we are reporting all track errors
if( !testTrackAgainstItem( track, trackShape.get(), layer, other ) )
{
if( it != checkedPairs.end() )
it->second.has_error = true;
return m_drcEngine->GetReportAllTrackErrors();
}
return true;
},
m_largestClearance );
@@ -161,18 +161,22 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
edges.back()->SetShape( SHAPE_T::SEGMENT );
edges.back()->SetEndX( shape->GetStartX() );
edges.back()->SetWidth( 0 );
edges.back()->SetParentGroup( nullptr );
edges.emplace_back( static_cast<PCB_SHAPE*>( shape->Clone() ) );
edges.back()->SetShape( SHAPE_T::SEGMENT );
edges.back()->SetEndY( shape->GetStartY() );
edges.back()->SetWidth( 0 );
edges.back()->SetParentGroup( nullptr );
edges.emplace_back( static_cast<PCB_SHAPE*>( shape->Clone() ) );
edges.back()->SetShape( SHAPE_T::SEGMENT );
edges.back()->SetStartX( shape->GetEndX() );
edges.back()->SetWidth( 0 );
edges.back()->SetParentGroup( nullptr );
edges.emplace_back( static_cast<PCB_SHAPE*>( shape->Clone() ) );
edges.back()->SetShape( SHAPE_T::SEGMENT );
edges.back()->SetStartY( shape->GetEndY() );
edges.back()->SetWidth( 0 );
edges.back()->SetParentGroup( nullptr );
return true;
}
else if( shape->GetShape() == SHAPE_T::POLY )
@@ -189,11 +193,13 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::Run()
edges.back()->SetStart((wxPoint) seg.A );
edges.back()->SetEnd((wxPoint) seg.B );
edges.back()->SetWidth( 0 );
edges.back()->SetParentGroup( nullptr );
}
}
edges.emplace_back( static_cast<PCB_SHAPE*>( shape->Clone() ) );
edges.back()->SetWidth( 0 );
edges.back()->SetParentGroup( nullptr );
return true;
};
+5 -3
View File
@@ -3,7 +3,7 @@
*
* Copyright (C) 2004-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2016-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -157,10 +157,12 @@ bool AskLoadBoardFileName( PCB_EDIT_FRAME* aParent, int* aCtl, wxString* aFileNa
PLUGIN::RELEASER plugin( IO_MGR::PluginFind( loaders[ii].pluginType ) );
wxCHECK( plugin, false );
allWildcards += wxT( "*." ) + formatWildcardExt( plugin->GetFileExtension() ) + wxT( ";" );
allWildcards += wxT( "*." ) + formatWildcardExt( plugin->GetFileExtension() ) +
wxT( ";" );
}
fileFilters = _( "All supported formats|" ) + allWildcards + wxT( "|" ) + fileFilters;
fileFilters = _( "All supported formats" ) + wxT( "|" ) + allWildcards + wxT( "|" ) +
fileFilters;
}
+13
View File
@@ -734,6 +734,19 @@ EDA_RECT FOOTPRINT::GetFpPadsLocalBbox() const
}
LSET FOOTPRINT::GetLayerSet() const
{
LSET retval;
RunOnChildren( [&retval]( BOARD_ITEM* aItem )
{
retval |= aItem->GetLayerSet();
} );
return retval;
}
const EDA_RECT FOOTPRINT::GetBoundingBox() const
{
return GetBoundingBox( true, true );
+2
View File
@@ -166,6 +166,8 @@ public:
const EDA_RECT GetBoundingBox() const override;
const EDA_RECT GetBoundingBox( bool aIncludeText, bool aIncludeInvisibleText ) const;
LSET GetLayerSet() const override;
PADS& Pads() { return m_pads; }
const PADS& Pads() const { return m_pads; }
+2 -2
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -275,7 +275,7 @@ void DIALOG_IMPORT_GFX::onBrowseFiles( wxCommandEvent& event )
allWildcards += plugin->GetWildcards() + wxT( ";" );
}
wildcardsDesc = _( "All supported formats|" ) + allWildcards + wildcardsDesc;
wildcardsDesc = _( "All supported formats" ) + wxT( "|" ) + allWildcards + wildcardsDesc;
wxFileDialog dlg( m_parent, _( "Open File" ), path, filename, wildcardsDesc,
wxFD_OPEN | wxFD_FILE_MUST_EXIST );
+5 -2
View File
@@ -56,8 +56,11 @@ bool SVG_IMPORT_PLUGIN::Load( const wxString& aFileName )
{
wxCHECK( m_importer, false );
// wxFopen takes care of unicode filenames across platforms
FILE* fp = wxFopen( aFileName, wxT( "rt" ) );
// 1- wxFopen takes care of unicode filenames across platforms
// 2 - nanosvg (exactly nsvgParseFromFile) expects a binary file (exactly the CRLF eof must
// not be replaced by LF and changes the byte count) in one validity test,
// so open it in binary mode.
FILE* fp = wxFopen( aFileName, wxT( "rb" ) );
if( fp == nullptr )
return false;
+45 -37
View File
@@ -1144,49 +1144,57 @@ BOARD* PCB_EXPR_CONTEXT::GetBoard() const
}
class PCB_UNIT_RESOLVER : public LIBEVAL::UNIT_RESOLVER
const std::vector<wxString>& PCB_UNIT_RESOLVER::GetSupportedUnits() const
{
public:
virtual ~PCB_UNIT_RESOLVER()
{
}
static const std::vector<wxString> pcbUnits = { wxT( "mil" ), wxT( "mm" ), wxT( "in" ) };
virtual const std::vector<wxString>& GetSupportedUnits() const override
{
static const std::vector<wxString> pcbUnits = { wxT( "mil" ), wxT( "mm" ), wxT( "in" ) };
return pcbUnits;
}
virtual wxString GetSupportedUnitsMessage() const override
{
return _( "must be mm, in, or mil" );
}
virtual double Convert( const wxString& aString, int unitId ) const override
{
double v = wxAtof( aString );
switch( unitId )
{
case 0: return DoubleValueFromString( EDA_UNITS::MILS, aString );
case 1: return DoubleValueFromString( EDA_UNITS::MILLIMETRES, aString );
case 2: return DoubleValueFromString( EDA_UNITS::INCHES, aString );
default: return v;
}
};
};
PCB_EXPR_COMPILER::PCB_EXPR_COMPILER()
{
m_unitResolver = std::make_unique<PCB_UNIT_RESOLVER>();
return pcbUnits;
}
PCB_EXPR_EVALUATOR::PCB_EXPR_EVALUATOR() :
wxString PCB_UNIT_RESOLVER::GetSupportedUnitsMessage() const
{
return _( "must be mm, in, or mil" );
}
double PCB_UNIT_RESOLVER::Convert( const wxString& aString, int unitId ) const
{
double v = wxAtof( aString );
switch( unitId )
{
case 0: return DoubleValueFromString( EDA_UNITS::MILS, aString );
case 1: return DoubleValueFromString( EDA_UNITS::MILLIMETRES, aString );
case 2: return DoubleValueFromString( EDA_UNITS::INCHES, aString );
default: return v;
}
};
const std::vector<wxString>& PCB_UNITLESS_RESOLVER::GetSupportedUnits() const
{
static const std::vector<wxString> emptyUnits;
return emptyUnits;
}
double PCB_UNITLESS_RESOLVER::Convert( const wxString& aString, int unitId ) const
{
return wxAtof( aString );
};
PCB_EXPR_COMPILER::PCB_EXPR_COMPILER( LIBEVAL::UNIT_RESOLVER* aUnitResolver )
{
m_unitResolver.reset( aUnitResolver );
}
PCB_EXPR_EVALUATOR::PCB_EXPR_EVALUATOR( LIBEVAL::UNIT_RESOLVER* aUnitResolver ) :
m_result( 0 ),
m_compiler(),
m_compiler( aUnitResolver ),
m_ucode(),
m_errorStatus()
{
+22 -2
View File
@@ -196,17 +196,37 @@ private:
};
class PCB_UNIT_RESOLVER : public LIBEVAL::UNIT_RESOLVER
{
public:
const std::vector<wxString>& GetSupportedUnits() const override;
wxString GetSupportedUnitsMessage() const override;
double Convert( const wxString& aString, int unitId ) const override;
};
class PCB_UNITLESS_RESOLVER : public LIBEVAL::UNIT_RESOLVER
{
public:
const std::vector<wxString>& GetSupportedUnits() const override;
double Convert( const wxString& aString, int unitId ) const override;
};
class PCB_EXPR_COMPILER : public LIBEVAL::COMPILER
{
public:
PCB_EXPR_COMPILER();
PCB_EXPR_COMPILER( LIBEVAL::UNIT_RESOLVER* aUnitResolver );
};
class PCB_EXPR_EVALUATOR
{
public:
PCB_EXPR_EVALUATOR( );
PCB_EXPR_EVALUATOR( LIBEVAL::UNIT_RESOLVER* aUnitResolver );
~PCB_EXPR_EVALUATOR();
bool Evaluate( const wxString& aExpr );
+34
View File
@@ -30,14 +30,48 @@
#include <widgets/msgpanel.h>
#include <view/view.h>
#include <wx/debug.h>
PCB_GROUP::PCB_GROUP( BOARD_ITEM* aParent ) :
BOARD_ITEM( aParent, PCB_GROUP_T )
{
}
bool PCB_GROUP::IsGroupableType( KICAD_T aType )
{
switch ( aType )
{
case PCB_FOOTPRINT_T:
case PCB_PAD_T:
case PCB_SHAPE_T:
case PCB_TEXT_T:
case PCB_FP_TEXT_T:
case PCB_FP_SHAPE_T:
case PCB_FP_ZONE_T:
case PCB_GROUP_T:
case PCB_TRACE_T:
case PCB_VIA_T:
case PCB_ARC_T:
case PCB_DIMENSION_T:
case PCB_DIM_ALIGNED_T:
case PCB_DIM_LEADER_T:
case PCB_DIM_CENTER_T:
case PCB_DIM_ORTHOGONAL_T:
case PCB_ZONE_T:
return true;
default:
return false;
}
}
bool PCB_GROUP::AddItem( BOARD_ITEM* aItem )
{
wxCHECK_MSG( IsGroupableType( aItem->Type() ), false,
wxT( "Invalid item type added to group: " )
+ aItem->GetSelectMenuText( EDA_UNITS::MILLIMETRES ) );
// Items can only be in one group at a time
if( aItem->GetParentGroup() )
aItem->GetParentGroup()->RemoveItem( aItem );
+36 -28
View File
@@ -262,7 +262,7 @@ COLOR4D PCB_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) cons
// Zones should pull from the copper layer
if( item && ( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T ) )
{
if( IsZoneLayer( aLayer ) )
if( IsZoneFillLayer( aLayer ) )
aLayer = aLayer - LAYER_ZONE_START;
}
@@ -1742,8 +1742,12 @@ void PCB_PAINTER::draw( const ZONE* aZone, int aLayer )
* The color for the zone comes from the associated copper layer ( aLayer - LAYER_ZONE_START )
* and the visibility comes from the combination of that copper layer and LAYER_ZONES
*/
wxASSERT( IsZoneLayer( aLayer ) );
PCB_LAYER_ID layer = static_cast<PCB_LAYER_ID>( aLayer - LAYER_ZONE_START );
PCB_LAYER_ID layer;
if( IsZoneFillLayer( aLayer ) )
layer = ToLAYER_ID( aLayer - LAYER_ZONE_START );
else
layer = ToLAYER_ID( aLayer );
if( !aZone->IsOnLayer( layer ) )
return;
@@ -1753,41 +1757,45 @@ void PCB_PAINTER::draw( const ZONE* aZone, int aLayer )
ZONE_DISPLAY_MODE displayMode = m_pcbSettings.m_zoneDisplayMode;
// Draw the outline
const SHAPE_POLY_SET* outline = aZone->Outline();
if( m_pcbSettings.m_zoneOutlines && outline && outline->OutlineCount() > 0 )
if( !IsZoneFillLayer( aLayer ) )
{
m_gal->SetStrokeColor( color.a > 0.0 ? color.WithAlpha( 1.0 ) : color );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
const SHAPE_POLY_SET* outline = aZone->Outline();
// Draw each contour (main contour and holes)
if( !m_pcbSettings.m_isPrinting && outline && outline->OutlineCount() > 0 )
{
m_gal->SetStrokeColor( color.a > 0.0 ? color.WithAlpha( 1.0 ) : color );
m_gal->SetIsFill( false );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
/*
* m_gal->DrawPolygon( *outline );
* should be enough, but currently does not work to draw holes contours in a complex
* polygon so each contour is draw as a simple polygon
*/
// Draw each contour (main contour and holes)
// Draw the main contour
m_gal->DrawPolyline( outline->COutline( 0 ) );
/*
* m_gal->DrawPolygon( *outline );
* should be enough, but currently does not work to draw holes contours in a complex
* polygon so each contour is draw as a simple polygon
*/
// Draw holes
int holes_count = outline->HoleCount( 0 );
// Draw the main contour
m_gal->DrawPolyline( outline->COutline( 0 ) );
for( int ii = 0; ii < holes_count; ++ii )
m_gal->DrawPolyline( outline->CHole( 0, ii ) );
// Draw holes
int holes_count = outline->HoleCount( 0 );
// Draw hatch lines
for( const SEG& hatchLine : aZone->GetHatchLines() )
m_gal->DrawLine( hatchLine.A, hatchLine.B );
for( int ii = 0; ii < holes_count; ++ii )
m_gal->DrawPolyline( outline->CHole( 0, ii ) );
// Draw hatch lines
for( const SEG& hatchLine : aZone->GetHatchLines() )
m_gal->DrawLine( hatchLine.A, hatchLine.B );
}
}
// Draw the filling
if( displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED
|| displayMode == ZONE_DISPLAY_MODE::SHOW_FRACTURE_BORDERS
|| displayMode == ZONE_DISPLAY_MODE::SHOW_TRIANGULATION )
if( IsZoneFillLayer( aLayer )
&& ( displayMode == ZONE_DISPLAY_MODE::SHOW_FILLED
|| displayMode == ZONE_DISPLAY_MODE::SHOW_FRACTURE_BORDERS
|| displayMode == ZONE_DISPLAY_MODE::SHOW_TRIANGULATION ) )
{
const SHAPE_POLY_SET& polySet = aZone->GetFilledPolysList( layer );
+2 -2
View File
@@ -138,8 +138,8 @@ void DP_MEANDER_PLACER::release()
long long int DP_MEANDER_PLACER::origPathLength() const
{
long long int totalP = m_padToDieLength + lineLength( m_tunedPathP, m_startPad_p, m_endPad_p );
long long int totalN = m_padToDieLength + lineLength( m_tunedPathN, m_startPad_n, m_endPad_n );
long long int totalP = m_padToDieP + lineLength( m_tunedPathP, m_startPad_p, m_endPad_p );
long long int totalN = m_padToDieN + lineLength( m_tunedPathN, m_startPad_n, m_endPad_n );
return std::max( totalP, totalN );
}

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