Compare commits

...

85 Commits

Author SHA1 Message Date
Wayne Stambaugh f9a2dced07 Tag release version 6.0.7. 2022-07-25 18:57:34 -04:00
qu1ck 52157acbfe PCM: fix kicad version restriction logic
The json schema for packages implies that kicad min/max version
restriction takes major.minor.patch string but actual logic
only checks major and minor.

This fixes the logic to work with full major.minor.patch tuple.
Additionally the version max logic will substitute missing portions
with 999 for a reasonable default so that say 7.1 is still considered
as >= 7.1.5 when checking for max version.

Reported here
https://forum.kicad.info/t/updating-already-installed-plugins-using-content-manager/35532/5?u=qu1ck

(cherry picked from commit 06028d5015)
2022-07-18 10:26:27 -07:00
dsa-t 17f220590b OpenGL: Use glGetProgramiv instead of the extension function.
(cherry picked from commit 3a76435eda)
2022-07-18 10:20:04 -07:00
Alex 33027b8f66 OpenGL: Fix SetSwapInterval logic.
- Don't use GLX extension functions unless they are supported on the
connection. GLEW only checks for client library support.

- Don't try to set swap interval using glXSwapIntervalSGI when vsync is
not requested.

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

(cherry picked from commit 0e2d3236b5)
2022-07-18 10:19:36 -07:00
Seth Hillbrand 064a9688c0 Make annotation case-insensitive
U1 and u1 are allowed but if they both exist in the same schematic, they
will throw an ERC and annotation error.  Reannotating will make them U1
and u2.

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

(cherry picked from commit 00c7b64b13)
2022-07-18 09:49:28 -07:00
Seth Hillbrand c1ec63d4f9 Protect the Kiway dereference
Also find a few more places where we are reaching into a new frame to
perform actions that need to have dialogs closed.

Running actions should also wait for the next cycle rather than being
immediately executed when we are calling into a new frame.  This allow
for the cleanup actions onClose() to happen prior to the next action
starting

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

(cherry picked from commit 93fb00d815)
2022-07-18 09:48:50 -07:00
Seth Hillbrand 995b2c517d Catch some crashes on shutdown
These can happen when a tool is active that sends signals when exiting
(e.g. deselectEvent).  These may be caught by the active loop in another
tool which might try to update the UI after it has been freed.  By
marking all tools as "shutdown", the only event returned to them should
be null.  As an extra precaution, we flag the shutdown globally within
the tool manager and check this flag before launching either events or
new tools

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

(cherry picked from commit db4f2d9dd8)
2022-07-18 09:48:16 -07:00
Seth Hillbrand a8c0bc0430 Keep track of blocking windows
Allows the calling KiWAY player to send messages to the blocking window
before signaling a separate call

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

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

(cherry picked from commit b5bf1da251)
2022-07-18 09:47:32 -07:00
Seth Hillbrand 902629c139 Fix name escaping in symbol editor
When renaming a symbol, be sure to handle name escaping in all of the
various places that we do renaming (!)

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

(cherry picked from commit 0dab566270)
2022-07-18 09:46:57 -07:00
Seth Hillbrand 63e638cfab Enforce group selection to abide by L/R behavior
When selecting greedy (right to left), selecting any part of the group
will get the whole group.  When selecting left to right, we must select
all items in the group to get the grouped items unless we are in the
group itself

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

(cherry picked from commit e87ba10a5a)
2022-07-18 09:45:10 -07:00
Seth Hillbrand 48b520a098 Update Translations 2022-07-18 09:39:03 -07:00
Tokita, Hiroshi b55352da7e Translated using Weblate (Japanese)
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-07-18 18:31:51 +02:00
dsa-t cd41a42775 Translated using Weblate (Russian)
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ru/
2022-07-18 18:31:51 +02:00
김랑기 6f82cec3a4 Translated using Weblate (Korean)
Currently translated at 99.9% (7154 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-07-18 18:31:51 +02:00
jeongsuAn 2f9cd25850 Translated using Weblate (Korean)
Currently translated at 99.9% (7150 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-07-18 18:31:51 +02:00
Seth Hillbrand 865bb54591 Flag ERC error on non-stacked pins
Pins that are explicitly connected in the schematic should not have an
"unconnected pin" ERC error.  But stacked pins do not count as
explicitly connected because the schematic designer has not connected
them
2022-07-17 20:16:55 -07:00
Alex 6d26e8e3e8 math: Use intrinsic functions for 64-bit rescale on MSVC.
(cherry picked from commit c107abe247)
2022-07-16 18:05:35 +00:00
jean-pierre charras 9c50a9fa4a FP_SHAPE in pads: always specify fill mode for shapes that can be filled or not.
From Master branch
2022-07-15 17:42:31 +02:00
이기형 406dd58002 Translated using Weblate (Korean)
Currently translated at 99.9% (7150 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-07-13 15:29:26 +02:00
이상수 bd7ba5f6b1 Translated using Weblate (Korean)
Currently translated at 99.9% (7149 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-07-13 15:29:26 +02:00
박세훈 d174cff9ae Translated using Weblate (Korean)
Currently translated at 99.8% (7147 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-07-13 15:29:26 +02:00
gurqja3810 bbce24ab32 Translated using Weblate (Korean)
Currently translated at 99.8% (7147 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-07-13 15:29:26 +02:00
박세훈 ad2c5b40ff Translated using Weblate (Korean)
Currently translated at 99.8% (7146 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-07-13 15:29:25 +02:00
Tokita, Hiroshi 8e0784d4fa Translated using Weblate (Japanese)
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-07-13 15:29:25 +02:00
jean-pierre charras 926818097b Fix compatibility issues with wxWidgets 3.2 and gcc 12.1:
hastable.h: remove deprecated binary/unary base class not actually needed.
Fix  compil warnings.
From master branch.
2022-07-12 18:24:12 +02:00
jean-pierre charras fd65bd8e6e Rework on bitmap_info.cpp cmake build process.
on gcc 12.1 / msys2 the large initialized list in bitmap_info.cpp breaks the
compiler (perhaps a bug in the compiler).
So, as workaround, the initialization sequence is modified.
Form master branch
2022-07-12 17:34:25 +02:00
jean-pierre charras d53c6f8abe Eeschema, DIALOG_SCH_FIND: ensure the search flags actually used are up to date.
Flags are encoded using internal wx values, that can change with wxWidgets versions.
They need to be always rebuilt from the displayed options in dialog.
From master branch.
2022-07-12 08:36:15 +02:00
Jon Evans 2512375988 PNS: Fix IsLineCorner logic
Handle segment width test in the case of locked segs
Fix logic failure where vias on path cause crash

Fixes https://gitlab.com/kicad/code/kicad/-/issues/11990
2022-07-11 22:47:28 -04:00
Wayne Stambaugh 4b4d082fa4 Pcbnew: fix minor white space issue in board file.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/11669

(cherry picked from commit 6a74ecbffd)
2022-07-11 11:25:02 -04:00
Seth Hillbrand 374dfdbe16 Update Translations 2022-07-08 08:59:32 -07:00
co8 j 3c476157c1 Translated using Weblate (Japanese)
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-07-08 17:57:36 +02:00
Marcel Hecko 3af058a281 Translated using Weblate (Slovak)
Currently translated at 77.0% (5513 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sk/
2022-07-08 17:57:36 +02:00
leonardokr 8a1e400d81 Translated using Weblate (Portuguese)
Currently translated at 99.5% (7122 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt/
2022-07-08 17:57:36 +02:00
Eric fb4fa9ae41 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-07-08 17:57:35 +02:00
Mustafa Selçuk ÇAVDAR ede0ab5b79 Translated using Weblate (Turkish)
Currently translated at 43.9% (3147 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/tr/
2022-07-08 17:57:35 +02:00
Henrik Kauhanen 2723898ff4 Translated using Weblate (Swedish)
Currently translated at 99.8% (7142 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/sv/
2022-07-08 17:57:35 +02:00
dsa-t b470d9ed8a Translated using Weblate (Russian)
Currently translated at 99.9% (7151 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ru/
2022-07-08 17:57:35 +02:00
Wellington Terumi Uemura f0446aab90 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt_BR/
2022-07-08 17:57:35 +02:00
ZbeeGin be3ee24826 Translated using Weblate (Polish)
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pl/
2022-07-08 17:57:35 +02:00
김랑기 68a1f9e512 Translated using Weblate (Korean)
Currently translated at 99.8% (7145 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ko/
2022-07-08 17:57:35 +02:00
co8 j bf90966901 Translated using Weblate (Japanese)
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-07-08 17:57:35 +02:00
Toni Laiho 7a5e9cce6d Translated using Weblate (Finnish)
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-07-08 17:57:35 +02:00
Ulices 3f7da644eb Translated using Weblate (Spanish (Mexico))
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es_MX/
2022-07-08 17:57:35 +02:00
Jonathan Haas e424dbea2d Translated using Weblate (German)
Currently translated at 100.0% (7155 of 7155 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-07-08 17:57:34 +02:00
Seth Hillbrand 4d1fcff732 Fix compile error in v6 2022-07-07 12:19:38 -07:00
Seth Hillbrand dac08643c3 Update Altium SCH QA with rounding factors 2022-07-07 12:03:18 -07:00
Seth Hillbrand 95fcf53353 Handle basic rounding error in schematic import
The fractional part of Altium schematic units is an integer number of
1/10000 mil segments, which is 2.54 nm.  The internal unit of eeschema
is 10 nm, so each fractional unit in Altium is 0.254 base eeschema
units.  To be consistent with
https://gitlab.com/kicad/code/kicad/-/commit/cf33cfcad1ce01d866548c4ef87a1125141d427b
we round to the nearest 10nm for each element

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

(cherry picked from commit 6fef054c51)
2022-07-07 11:14:25 -07:00
Marek Roszko 7dc6abd533 Add 3.2 as search candidates for wxwidgets
(cherry picked from commit c12a723d41)
2022-07-07 11:45:44 +00:00
Jeff Young 042b49ee7b Update message panel from PCB point editor and SCH drawing tools.
Fixes https://gitlab.com/kicad/code/kicad/issues/11961

(cherry picked from commit 4f62960334)
2022-07-06 19:48:09 -07:00
Seth Hillbrand 6a1dfd6e32 Overplot schematic symbol fields and pins
In the absence of z-ordering, we need to ensure that pin text and symbol
fields are always visible in plots as they are in the schematic window.
We do this by overplotting the fields/pins when symbols overlap each
other.

This can be removed if/when we implement https://gitlab.com/kicad/code/kicad/-/issues/2211

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

(cherry picked from commit ff54b8c718)
2022-07-05 16:47:07 -07:00
Wayne Stambaugh b2855e6288 Fix KiCad2Step virtual keyword handling.
The "virtual" keyword has been deprecated from the board file format so
use "exclude_from_bom" as the flag for the old virtual behavior.  This
is only a partial fix.  Full support for the "exclude_from_bom" will be
added later for V7.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/10563
(cherry picked from commit 497061de35)
2022-07-05 09:30:59 -04:00
jean-pierre charras 86f9f169cd Pcbnew, printing in B&W: never draw the background color.
Otherwise a black background is printed.
Fixes #11625
https://gitlab.com/kicad/code/kicad/issues/11625
2022-07-04 12:03:17 +02:00
Seth Hillbrand 9052b063de Remove duplicate strid 2022-06-30 13:24:48 -07:00
Seth Hillbrand 1a6be90c4f Update Translations 2022-06-30 11:25:11 -07:00
Seth Hillbrand 55de16e874 Remove extraneous files added in 69858ab4c0
Files were master-only
2022-06-30 11:09:03 -07:00
Seth Hillbrand ef2bb0b621 Avoid documentation in dialogs
If the nomenclature is unclear, we should rework the dialog rather than
adding documentation strings to a crowded dialog.

This also prevents new strings from appearing in v6

(cherry picked from commit 0c796697b4)
2022-06-30 10:58:13 -07:00
Mark Hämmerling 09d4543071 Translated using Weblate (German)
Currently translated at 100.0% (7156 of 7156 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-06-30 19:44:04 +02:00
Allan Nordhøy 7ef63f0159 Translated using Weblate (Norwegian Bokmål)
Currently translated at 73.1% (5235 of 7156 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/nb_NO/
2022-06-30 19:44:04 +02:00
Toni Laiho d0e34bf013 Translated using Weblate (Finnish)
Currently translated at 100.0% (7156 of 7156 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/fi/
2022-06-30 19:44:04 +02:00
Mark Hämmerling 46a17ff272 Translated using Weblate (German)
Currently translated at 100.0% (7156 of 7156 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-06-30 19:44:04 +02:00
Eric 51cc4b8811 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (7156 of 7156 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/zh_Hans/
2022-06-30 19:44:04 +02:00
Wellington Terumi Uemura 5634dfa6ed Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (7156 of 7156 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/pt_BR/
2022-06-30 19:44:04 +02:00
co8 j 5a8d56f3db Translated using Weblate (Japanese)
Currently translated at 100.0% (7156 of 7156 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/ja/
2022-06-30 19:44:04 +02:00
Ulices 0c5ea8565d Translated using Weblate (Spanish (Mexico))
Currently translated at 100.0% (7156 of 7156 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/es_MX/
2022-06-30 19:44:04 +02:00
Mark Hämmerling 1431bd1143 Translated using Weblate (German)
Currently translated at 100.0% (7156 of 7156 strings)

Translation: KiCad EDA/v6
Translate-URL: https://hosted.weblate.org/projects/kicad/v6/de/
2022-06-30 19:44:03 +02:00
Seth Hillbrand 7a3a7d1af6 Python add param to change UUIDs on fp load
By default, we load all footprints with a new UUID set to allow them to
be added to the board as unique objects.  But when editing footprints,
we want to maintain the same UUID.

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

(cherry picked from commit 802745398a)
2022-06-29 12:10:51 -07:00
Mike Williams 761ddcad21 Schematic: Add shift-space hotkey for consistency with PCB editor
Already in 7.0/master.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/10858
2022-06-29 12:54:18 +00:00
Seth Hillbrand 8aabdcff9c Refresh draw objects when common settings change
Common settings may change colors so make sure that we refresh the draw
objects when the settings change to draw them in the proper colors.
Failing to do this may also cause left over lines on the screen
depending on OpenGL drivers

Fixes https://gitlab.com/kicad/code/kicad/issues/11921
2022-06-28 16:45:55 -07:00
Adam Wahab 29d58ae063 Corrected syntax in kicad2step's help message regarding user-specified origin.
(cherry picked from commit 8456d6cea9)
2022-06-28 16:24:44 -07:00
Seth Hillbrand 90ef84b958 Fix ERC error missing on stacked pins
Stacked pins are not connected, so they should be flagged as such.  This
checks for stacked pins that are not part of different symbols

Fixes https://gitlab.com/kicad/code/kicad/issues/11926
2022-06-28 15:03:52 -07:00
Seth Hillbrand 9cebea5f11 Correct SWIG call for board design settings
Use the backend call rather than rely on the naming of internal
variables

Fixes https://gitlab.com/kicad/code/kicad/issues/11924
2022-06-28 14:02:56 -07:00
Wayne Stambaugh b7b955e37b Eeschema: fix project rescue bug.
When a rescue library already existed, the disabled writing of legacy
symbol library table entries prevented the rescue library from being
updated.

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

(cherry picked from commit 4e7b5b9784)
2022-06-28 16:14:47 -04:00
Mark Roszko 87d4249d9f Match vcpkg baseline of master 2022-06-25 13:22:44 +00:00
Mark Roszko 8bf5240d60 Fix windows build 2022-06-25 13:21:54 +00:00
jean-pierre charras 20bebeb543 Gen Drill map: Re-add Gerber option but only using X2 format.
Only the X2 format allows the TF.FileFunction option, mandatory to
avoid mistakes about this file that is not a standard Gerber file.
2022-06-23 14:20:32 +02:00
jean-pierre charras 1f4b288664 gen drill maps: remove unusable format (HPGL and GERBER) for map files.
Especially, on a regular basis, map files in gerber format create problems
for board house.
From Master branch.
2022-06-22 11:29:27 +02:00
Seth Hillbrand 5cf346c233 Unify symbol browser/editor unit display
Fixes https://gitlab.com/kicad/code/kicad/issues/11881

(cherry picked from commit aeef5b00a8)
2022-06-21 16:23:27 -07:00
Seth Hillbrand 617755f991 Treat all units equally when converting to string
Excessive trucation in mils can lead to data loss when round-tripping
values.  Better to keep decimal count consistent between units

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

(cherry picked from commit 67d9729311)
2022-06-21 15:30:24 -07:00
Seth Hillbrand 45329ceafa Push wxString allocation to smaller context
Prevents creation of new wxString on stack for each clearance check

(cherry picked from commit 4043dca613)
2022-06-21 10:30:42 -07:00
Seth Hillbrand 69858ab4c0 Remove shared wxString instance in DRC
Threaded DRC access will write to this string, re-allocating the memory
without any synchronization between threads using the string.  Comment
adding this listed performance as a reason for using shared strings.
Measured performance does not seem noticeably different in either case,
even with high-error count boards.  If there is a case where the
performance is limiting, we can replace these wxStrings with
std::wstring and utilize fmt

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

(cherry picked from commit 5327b10064)
2022-06-21 10:27:21 -07:00
Seth Hillbrand c53a1e00f6 Fix one missing commit for MSVC
(cherry picked from commit 8f1b2acdc6)
2022-06-21 10:08:02 -07:00
Seth Hillbrand 178a36fc66 Patch pybind11 for MSVC
Re-comit of earlier ef38642bf1 after updating pybind11 to 2.9.2

(cherry picked from commit c483c58276)
2022-06-21 10:08:02 -07:00
Seth Hillbrand 8ce38d3820 Update pybind11 to 2.9.2
Fixes https://gitlab.com/kicad/code/kicad/-/issues/10729

(cherry picked from commit 8d003804e0)
2022-06-21 10:08:02 -07:00
Mark Roszko e0802dcd26 Walk vcpkg config forwards for wx 3.1.7 2022-06-20 03:21:18 +00:00
Wayne Stambaugh c8a1c5c707 Begin version 6.0.7 development. 2022-06-17 21:13:23 -04:00
291 changed files with 23256 additions and 16058 deletions
@@ -36,9 +36,9 @@ string( REGEX MATCH
if( CMAKE_MATCH_COUNT EQUAL 3 )
# Match slot 0 is the full string, so we want slots 1 & 2
set( KICAD_MAJOR_MINOR_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}" )
set( KICAD_MAJOR_MINOR_VERSION_TUPLE "{ ${CMAKE_MATCH_1}, ${CMAKE_MATCH_2} }" )
set( KICAD_MAJOR_MINOR_PATCH_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" )
set( KICAD_MAJOR_MINOR_PATCH_TUPLE "{ ${CMAKE_MATCH_1}, ${CMAKE_MATCH_2}, ${CMAKE_MATCH_3} }" )
set( KICAD_MAJOR_VERSION "${CMAKE_MATCH_1}" )
set( KICAD_MINOR_VERSION "${CMAKE_MATCH_2}" )
@@ -67,7 +67,7 @@ set( _wvh_new_version_text
#define KICAD_MINOR_VERSION \"${KICAD_MINOR_VERSION}\"
#define KICAD_PATCH_VERSION \"${KICAD_PATCH_VERSION}\"
#define KICAD_MAJOR_MINOR_VERSION \"${KICAD_MAJOR_MINOR_VERSION}\"
#define KICAD_MAJOR_MINOR_VERSION_TUPLE ${KICAD_MAJOR_MINOR_VERSION_TUPLE}
#define KICAD_MAJOR_MINOR_PATCH_TUPLE ${KICAD_MAJOR_MINOR_PATCH_TUPLE}
#define KICAD_WIN32_RC_PRODVER ${KICAD_WIN32_RC_PRODVER}
#define KICAD_WIN32_RC_PRODVER_STR \"${KICAD_WIN32_RC_PRODVER_STR}\"
#define KICAD_WIN32_RC_FILEVER ${KICAD_WIN32_RC_FILEVER}
+4
View File
@@ -293,6 +293,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
# Find wxWidgets multilib base libraries.
find_library(WX_base${_DBG}
NAMES
wxbase32${_UCD}${_DBG}
wxbase31${_UCD}${_DBG}
wxbase30${_UCD}${_DBG}
wxbase29${_UCD}${_DBG}
@@ -307,6 +308,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
foreach(LIB net odbc xml)
find_library(WX_${LIB}${_DBG}
NAMES
wxbase32${_UCD}${_DBG}_${LIB}
wxbase31${_UCD}${_DBG}_${LIB}
wxbase30${_UCD}${_DBG}_${LIB}
wxbase29${_UCD}${_DBG}_${LIB}
@@ -323,6 +325,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
# Find wxWidgets monolithic library.
find_library(WX_mono${_DBG}
NAMES
wx${_PF}${_UNV}32${_UCD}${_DBG}
wx${_PF}${_UNV}31${_UCD}${_DBG}
wx${_PF}${_UNV}30${_UCD}${_DBG}
wx${_PF}${_UNV}29${_UCD}${_DBG}
@@ -340,6 +343,7 @@ if(wxWidgets_FIND_STYLE STREQUAL "win32")
stc ribbon propgrid webview)
find_library(WX_${LIB}${_DBG}
NAMES
wx${_PF}${_UNV}32${_UCD}${_DBG}_${LIB}
wx${_PF}${_UNV}31${_UCD}${_DBG}_${LIB}
wx${_PF}${_UNV}30${_UCD}${_DBG}_${LIB}
wx${_PF}${_UNV}29${_UCD}${_DBG}_${LIB}
+1 -1
View File
@@ -37,7 +37,7 @@
# KiCad.
#
# Note: This version string should follow the semantic versioning system
set( KICAD_SEMANTIC_VERSION "6.0.6" )
set( KICAD_SEMANTIC_VERSION "6.0.7" )
# Default the version to the semantic version.
# This is overridden by the git repository tag though (if using git)
+3 -3
View File
@@ -619,8 +619,8 @@ set( TMP_DIR "${CMAKE_CURRENT_BINARY_DIR}/tmp" )
# generate logs is useful only if you have problems
set( CREATE_LOG_FILES true )
set( BITMAP_INFO_FILE "${CMAKE_SOURCE_DIR}/include/bitmaps/bitmap_info.h" )
set( BITMAP_INFO_TEMPLATE "${CMAKE_SOURCE_DIR}/include/bitmaps/bitmap_info.h.in" )
set( BITMAP_INFO_FILE "${CMAKE_SOURCE_DIR}/common/bitmap_info.cpp" )
set( BITMAP_INFO_TEMPLATE "${CMAKE_SOURCE_DIR}/include/bitmaps/bitmap_info.cpp.in" )
set( BITMAP_INFO_LIST "" )
set( ALL_PNGS "" )
@@ -739,7 +739,7 @@ function( bitmap_dir pngWidth pngHeight bmapList )
png2png( ${tmpFile} ${pngPath} )
set( bitmapInfo
" { BITMAPS::${bmn}, wxT( \"${pngFile}\" ), ${pngHeight}, wxT( \"${theme}\" ) },\n"
" aBitmapInfoCache[BITMAPS::${bmn}].emplace_back( BITMAPS::${bmn}, wxT( \"${pngFile}\" ), ${pngHeight}, wxT( \"${theme}\" ) );\n"
)
set( BITMAP_INFO_LIST "${BITMAP_INFO_LIST}${bitmapInfo}" )
+1
View File
@@ -315,6 +315,7 @@ set( COMMON_SRCS
bin_mod.cpp
bitmap.cpp
bitmap_base.cpp
bitmap_info.cpp
bitmap_store.cpp
board_printout.cpp
build_version.cpp
+3 -8
View File
@@ -226,22 +226,17 @@ wxString StringFromValue( EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol,
if( value_to_print != 0.0 && fabs( value_to_print ) <= 0.0001 )
{
len = sprintf( buf, "%.10f", value_to_print );
len = snprintf( buf, sizeof( buf ) - 1, "%.10f", value_to_print );
while( --len > 0 && buf[len] == '0' )
buf[len] = '\0';
if( buf[len]=='.' || buf[len]==',' )
if( len >= 0 && ( buf[len]=='.' || buf[len]==',' ) )
buf[len] = '\0';
else
++len;
}
else
{
if( aUnits == EDA_UNITS::MILS )
len = sprintf( buf, "%.7g", value_to_print );
else
len = sprintf( buf, "%.10g", value_to_print );
snprintf( buf, sizeof( buf ) - 1, "%.10g", value_to_print );
}
wxString stringValue( buf, wxConvUTF8 );
File diff suppressed because it is too large Load Diff
+6 -7
View File
@@ -101,7 +101,7 @@ BITMAP_STORE::BITMAP_STORE()
{
wxFileName path( PATHS::GetStockDataPath() + wxT( "/resources" ), IMAGE_ARCHIVE );
wxLogTrace( traceBitmaps, wxT( "Loading bitmaps from " ) + path.GetFullPath() );
wxLogTrace( traceBitmaps, "Loading bitmaps from " + path.GetFullPath() );
m_archive = std::make_unique<ASSET_ARCHIVE>( path.GetFullPath() );
@@ -148,8 +148,8 @@ wxImage BITMAP_STORE::getImage( BITMAPS aBitmapId, int aHeight )
if( count < 0 )
{
wxLogTrace( traceBitmaps, wxT( "Bitmap for %d, %d, %s has an info tag with file %s," )
wxT( "but that file could not be found in the archive!" ),
wxLogTrace( traceBitmaps, "Bitmap for %d, %d, %s has an info tag with file %s,"
"but that file could not be found in the archive!",
aBitmapId, aHeight, m_theme );
data = s_imageNotFound;
count = sizeof( s_imageNotFound );
@@ -204,7 +204,7 @@ wxString BITMAP_STORE::computeBitmapName( BITMAPS aBitmapId, int aHeight )
{
if( !m_bitmapInfoCache.count( aBitmapId ) )
{
wxLogTrace( traceBitmaps, wxT( "No bitmap info available for %d" ), aBitmapId );
wxLogTrace( traceBitmaps, "No bitmap info available for %d", aBitmapId );
return wxEmptyString;
}
@@ -224,7 +224,7 @@ wxString BITMAP_STORE::computeBitmapName( BITMAPS aBitmapId, int aHeight )
if( fn.IsEmpty() )
{
wxLogTrace( traceBitmaps, wxT( "No bitmap found matching ID %d, height %d, theme %s" ),
wxLogTrace( traceBitmaps, "No bitmap found matching ID %d, height %d, theme %s",
aBitmapId, aHeight, m_theme );
return m_bitmapInfoCache.at( aBitmapId ).begin()->filename;
}
@@ -235,6 +235,5 @@ wxString BITMAP_STORE::computeBitmapName( BITMAPS aBitmapId, int aHeight )
void BITMAP_STORE::buildBitmapInfoCache()
{
for( const BITMAP_INFO& entry : g_BitmapInfo )
m_bitmapInfoCache[entry.id].emplace_back( entry );
BuildBitmapInfo( m_bitmapInfoCache );
}
+4
View File
@@ -116,6 +116,10 @@ void BOARD_PRINTOUT::DrawPage( const wxString& aLayerName, int aPageNum, int aPa
{
for( int i = 0; i < LAYER_ID_COUNT; ++i )
dstSettings->SetLayerColor( i, COLOR4D::BLACK );
// In B&W mode, draw the background only in wxhite, because any other color
// will be replaced by a black background
dstSettings->SetBackgroundColor( COLOR4D::WHITE );
}
else // color enabled
{
+7
View File
@@ -25,6 +25,7 @@
#include <dialog_shim.h>
#include <ignore.h>
#include <kiway_player.h>
#include <kiway.h>
#include <pgm_base.h>
#include <tool/tool_manager.h>
#include <kiplatform/ui.h>
@@ -122,6 +123,9 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl
if( kiwayHolder )
SetKiway( this, &kiwayHolder->Kiway() );
if( HasKiway() )
Kiway().SetBlockingDialog( this );
Bind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this );
Bind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this );
@@ -143,6 +147,9 @@ DIALOG_SHIM::~DIALOG_SHIM()
if( IsQuasiModal() )
EndQuasiModal( wxID_CANCEL );
if( HasKiway() )
Kiway().SetBlockingDialog( nullptr );
if( m_qmodal_parent_disabler )
delete m_qmodal_parent_disabler; // usually NULL by now
}
+1 -1
View File
@@ -106,7 +106,7 @@ bool SHADER::Link()
// Check the Link state
GLint tmp;
glGetObjectParameterivARB( programNumber, GL_OBJECT_LINK_STATUS_ARB, &tmp );
glGetProgramiv( programNumber, GL_LINK_STATUS, &tmp );
isShaderLinked = !!tmp;
#ifdef DEBUG
+14 -1
View File
@@ -50,7 +50,7 @@ int KIWAY::m_kiface_version[KIWAY_FACE_COUNT];
KIWAY::KIWAY( PGM_BASE* aProgram, int aCtlBits, wxFrame* aTop ):
m_program( aProgram ), m_ctl( aCtlBits ), m_top( nullptr )
m_program( aProgram ), m_ctl( aCtlBits ), m_top( nullptr ), m_blockingDialog( wxID_NONE )
{
SetTop( aTop ); // hook player_destroy_handler() into aTop.
@@ -606,6 +606,19 @@ void KIWAY::ProjectChanged()
}
}
wxWindow* KIWAY::GetBlockingDialog()
{
return wxWindow::FindWindowById( m_blockingDialog );
}
void KIWAY::SetBlockingDialog( wxWindow* aWin )
{
if( !aWin )
m_blockingDialog = wxID_NONE;
else
m_blockingDialog = aWin->GetId();
}
bool KIWAY::ProcessEvent( wxEvent& aEvent )
{
+5
View File
@@ -96,7 +96,12 @@ static struct PGM_SINGLE_TOP : public PGM_BASE
KIWAY_PLAYER* frame = (KIWAY_PLAYER*) App().GetTopWindow();
#endif
if( frame )
{
if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
frame->OpenProjectFiles( std::vector<wxString>( 1, aFileName ) );
}
}
}
+7
View File
@@ -177,6 +177,13 @@ int COMMON_CONTROL::ShowPlayer( const TOOL_EVENT& aEvent )
if( wxWindow::FindFocus() != editor )
editor->SetFocus();
// If the player is currently blocked, focus the user attention on the correct window
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
{
blocking_win->Raise();
blocking_win->SetFocus();
}
return 0;
}
+22 -1
View File
@@ -206,7 +206,8 @@ TOOL_MANAGER::TOOL_MANAGER() :
m_warpMouseAfterContextMenu( true ),
m_menuActive( false ),
m_menuOwner( -1 ),
m_activeState( nullptr )
m_activeState( nullptr ),
m_shuttingDown( false )
{
m_actionMgr = new ACTION_MANAGER( this );
}
@@ -313,6 +314,9 @@ VECTOR2D TOOL_MANAGER::GetCursorPosition() const
bool TOOL_MANAGER::RunAction( const TOOL_ACTION& aAction, bool aNow, void* aParam )
{
if( m_shuttingDown )
return true;
bool handled = false;
TOOL_EVENT event = aAction.MakeEvent();
@@ -446,10 +450,22 @@ bool TOOL_MANAGER::runTool( TOOL_BASE* aTool )
void TOOL_MANAGER::ShutdownAllTools()
{
m_shuttingDown = true;
// Create a temporary list of tools to iterate over since when the tools shutdown
// they remove themselves from the list automatically (invalidating the iterator)
ID_LIST tmpList = m_activeTools;
// Make sure each tool knows that it is shutting down, so that loops get shut down
// at the dispatcher
for( auto id : tmpList )
{
if( m_toolIdIndex.count( id ) == 0 )
continue;
m_toolIdIndex[id]->shutdown = true;
}
for( auto id : tmpList )
{
ShutdownTool( id );
@@ -949,6 +965,11 @@ TOOL_MANAGER::ID_LIST::iterator TOOL_MANAGER::finishTool( TOOL_STATE* aState )
bool TOOL_MANAGER::ProcessEvent( const TOOL_EVENT& aEvent )
{
// Once the tool manager is shutting down, don't start
// activating more tools
if( m_shuttingDown )
return true;
bool handled = processEvent( aEvent );
TOOL_STATE* activeTool = GetCurrentToolState();
+3
View File
@@ -167,6 +167,9 @@ int CVPCB_CONTROL::ShowFootprintViewer( const TOOL_EVENT& aEvent )
}
else
{
if( wxWindow* blocking_win = fpframe->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
if( fpframe->IsIconized() )
fpframe->Iconize( false );
+1 -4
View File
@@ -49,10 +49,7 @@ void SCH_EDIT_FRAME::mapExistingAnnotation( std::map<wxString, wxString>& aMap )
curr_full_uuid.push_back( symbol->m_Uuid );
wxString ref = symbol->GetRef( curr_sheetpath );
if( symbol->GetUnitCount() > 1 )
ref << LIB_SYMBOL::SubReference( symbol->GetUnitSelection( curr_sheetpath ) );
wxString ref = symbol->GetRef( curr_sheetpath, true );
if( symbol->IsAnnotated( curr_sheetpath ) )
aMap[ curr_full_uuid.AsString() ] = ref;
+15 -2
View File
@@ -2714,8 +2714,21 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph
{
case SCH_PIN_T:
{
if( !pins.empty() )
has_other_connections = true;
// 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 );
for( SCH_PIN* other_pin : pins )
{
if( other_pin->GetParent() != pin->GetParent()
|| other_pin->GetPosition() != pin->GetPosition() )
{
has_other_connections = true;
break;
}
}
}
pins.emplace_back( static_cast<SCH_PIN*>( item ) );
@@ -308,7 +308,7 @@ bool DIALOG_LIB_SYMBOL_PROPERTIES::TransferDataFromWindow()
return false;
// We need to keep the name and the value the same at the moment!
wxString newName = m_fields->at( VALUE_FIELD ).GetText();
wxString newName = EscapeString( m_fields->at( VALUE_FIELD ).GetText(), CTX_LIBID );
wxString oldName = m_libEntry->GetName();
if( oldName != newName )
+13 -2
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2010-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2010-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
@@ -196,6 +196,14 @@ void DIALOG_SCH_FIND::OnReplaceWithEnter( wxCommandEvent& aEvent )
void DIALOG_SCH_FIND::OnOptions( wxCommandEvent& aEvent )
{
updateFlags();
m_findDirty = true;
}
void DIALOG_SCH_FIND::updateFlags()
{
// Rebuild the search flags in m_findReplaceData from dialog settings
int flags = 0;
if( m_radioForward->GetValue() )
@@ -223,12 +231,13 @@ void DIALOG_SCH_FIND::OnOptions( wxCommandEvent& aEvent )
flags |= FR_REPLACE_REFERENCES;
m_findReplaceData->SetFlags( flags );
m_findDirty = true;
}
void DIALOG_SCH_FIND::OnFind( wxCommandEvent& aEvent )
{
updateFlags(); // Ensure search flags are up to date
int index = m_comboFind->FindString( m_comboFind->GetValue(), true );
if( index == wxNOT_FOUND )
@@ -250,6 +259,8 @@ void DIALOG_SCH_FIND::OnFind( wxCommandEvent& aEvent )
void DIALOG_SCH_FIND::OnReplace( wxCommandEvent& aEvent )
{
updateFlags(); // Ensure search flags are up to date
int index = m_comboReplace->FindString( m_comboReplace->GetValue(), true );
if( index == wxNOT_FOUND )
+4 -1
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2010-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2010-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
@@ -75,6 +75,9 @@ protected:
void OnFind( wxCommandEvent& aEvent ) override;
void OnReplace( wxCommandEvent& aEvent ) override;
// Rebuild the search flags from dialog settings
void updateFlags();
SCH_EDIT_FRAME* m_frame;
SCH_EDITOR_CONTROL* m_editorControl;
wxFindReplaceData* m_findReplaceData;
+35 -17
View File
@@ -669,13 +669,13 @@ void LEGACY_RESCUER::OpenRescueLibrary()
wxFileName fn = GetRescueLibraryFileName( m_schematic );
std::unique_ptr<SYMBOL_LIB> rescue_lib = std::make_unique<SYMBOL_LIB>( SCH_LIB_TYPE::LT_EESCHEMA,
fn.GetFullPath() );
fn.GetFullPath() );
m_rescue_lib = std::move( rescue_lib );
m_rescue_lib->EnableBuffering();
// If a rescue library already exists copy the contents of that library so we do not
// lose an previous rescues.
// lose any previous rescues.
SYMBOL_LIB* rescueLib = m_prj->SchLibs()->FindLibrary( fn.GetName() );
if( rescueLib )
@@ -810,6 +810,27 @@ void SYMBOL_LIB_TABLE_RESCUER::OpenRescueLibrary()
{
m_pi.set( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
(*m_properties)[ SCH_LEGACY_PLUGIN::PropBuffering ] = "";
wxFileName fn = GetRescueLibraryFileName( m_schematic );
// If a rescue library already exists copy the contents of that library so we do not
// lose any previous rescues.
if( m_prj->SchSymbolLibTable()->HasLibrary( fn.GetName() ) )
{
std::vector<LIB_SYMBOL*> symbols;
try
{
m_prj->SchSymbolLibTable()->LoadSymbolLib( symbols, fn.GetName() );
}
catch( ... /* IO_ERROR */ )
{
return;
}
for( LIB_SYMBOL* symbol : symbols )
AddSymbol( symbol );
}
}
@@ -818,21 +839,21 @@ bool SYMBOL_LIB_TABLE_RESCUER::WriteRescueLibrary( wxWindow *aParent )
wxString msg;
wxFileName fn = GetRescueLibraryFileName( m_schematic );
try
{
m_pi->SaveLibrary( fn.GetFullPath() );
}
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Failed to save rescue library %s." ), fn.GetFullPath() );
DisplayErrorMessage( aParent, msg, ioe.What() );
return false;
}
// If the rescue library already exists in the symbol library table no need save it to add
// it to the table.
if( !m_prj->SchSymbolLibTable()->HasLibrary( fn.GetName() ) )
{
try
{
m_pi->SaveLibrary( fn.GetFullPath() );
}
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Failed to save rescue library %s." ), fn.GetFullPath() );
DisplayErrorMessage( aParent, msg, ioe.What() );
return false;
}
wxString uri = wxT( "${KIPRJMOD}/" ) + fn.GetFullName();
wxString libNickname = fn.GetName();
@@ -880,10 +901,7 @@ void SYMBOL_LIB_TABLE_RESCUER::AddSymbol( LIB_SYMBOL* aNewSymbol )
try
{
if( !m_prj->SchSymbolLibTable()->HasLibrary( fn.GetName() ) )
m_pi->SaveSymbol( fn.GetFullPath(), new LIB_SYMBOL( *aNewSymbol ), m_properties.get() );
else
m_prj->SchSymbolLibTable()->SaveSymbol( fn.GetName(), new LIB_SYMBOL( *aNewSymbol ) );
m_pi->SaveSymbol( fn.GetFullPath(), new LIB_SYMBOL( *aNewSymbol ), m_properties.get() );
}
catch( ... /* IO_ERROR */ )
{
@@ -27,6 +27,7 @@
#include <convert_to_biu.h>
#include <ki_exception.h>
#include <math/util.h>
#include <wx/log.h>
@@ -43,7 +44,12 @@ ALTIUM_SCH_RECORD ReadRecord( const std::map<wxString, wxString>& aProps )
constexpr int Altium2KiCadUnit( const int val, const int frac )
{
return Mils2iu( val ) * 10 + Mils2iu( frac ) / 10000; // TODO: correct, rounding issues?
constexpr double int_limit = ( std::numeric_limits<int>::max() - 10 ) / 2.54;
double dbase = 10 * Mils2iu( val );
double dfrac = Mils2iu( frac ) / 10000.0;
return KiROUND( Clamp<double>( -int_limit, ( dbase + dfrac ) / 10.0, int_limit ) ) * 10;
}
+3 -3
View File
@@ -134,7 +134,7 @@ public:
int CompareRef( const SCH_REFERENCE& item ) const
{
return m_ref.compare( item.m_ref );
return m_ref.CmpNoCase( item.m_ref );
}
int CompareLibName( const SCH_REFERENCE& item ) const
@@ -168,7 +168,7 @@ private:
friend class SCH_REFERENCE_LIST;
/// Symbol reference prefix, without number (for IC1, this is IC) )
UTF8 m_ref; // it's private, use the accessors please
wxString m_ref; // it's private, use the accessors please
SCH_SYMBOL* m_rootSymbol; ///< The symbol associated the reference object.
LIB_SYMBOL* m_libPart; ///< The source symbol from a library.
wxPoint m_symbolPos; ///< The physical position of the symbol in schematic
@@ -454,7 +454,7 @@ public:
printf( " [%-2d] ref:%-8s num:%-3d lib_part:%s\n",
i,
schref.m_ref.c_str(),
schref.m_ref.ToStdString().c_str(),
schref.m_numRef,
TO_UTF8( schref.GetLibPart()->GetName() ) );
}
+5
View File
@@ -225,6 +225,11 @@ public:
{
return type_tree->end( m_rect );
}
bool empty()
{
return type_tree->Count() == 0;
}
};
EE_TYPE OfType( KICAD_T aType ) const
+31 -3
View File
@@ -838,9 +838,10 @@ void SCH_SCREEN::Print( const RENDER_SETTINGS* aSettings )
void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
{
// Ensure links are up to date, even if a library was reloaded for some reason:
std::vector< SCH_ITEM* > junctions;
std::vector< SCH_ITEM* > bitmaps;
std::vector< SCH_ITEM* > other;
std::vector<SCH_ITEM*> junctions;
std::vector<SCH_ITEM*> bitmaps;
std::vector<SCH_SYMBOL*> symbols;
std::vector<SCH_ITEM*> other;
for( SCH_ITEM* item : Items() )
{
@@ -853,6 +854,21 @@ void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
bitmaps.push_back( item );
else
other.push_back( item );
// Where the symbols overlap each other, we need to plot the text items a second
// time to get them on top of the overlapping element. This collection is in addition
// to the symbols already collected in `other`
if( item->Type() == SCH_SYMBOL_T )
{
for( SCH_ITEM* sym : m_rtree.Overlapping( SCH_SYMBOL_T, item->GetBoundingBox() ) )
{
if( sym != item )
{
symbols.push_back( static_cast<SCH_SYMBOL*>( item ) );
break;
}
}
}
}
/// Sort to ensure plot-order consistency with screen drawing
@@ -882,6 +898,18 @@ void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
item->Plot( aPlotter );
}
// After plotting the symbols as a group above (in `other`), we need to overplot the pins
// and symbols to ensure that they are always visible
for( const SCH_SYMBOL* sym :symbols )
{
aPlotter->SetCurrentLineWidth( std::max( sym->GetPenWidth(), defaultPenWidth ) );
for( SCH_FIELD field : sym->GetFields() )
field.Plot( aPlotter );
sym->PlotPins( aPlotter );
}
for( const SCH_ITEM* item : junctions )
{
aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
+29
View File
@@ -1912,6 +1912,35 @@ void SCH_SYMBOL::Plot( PLOTTER* aPlotter ) const
}
void SCH_SYMBOL::PlotPins( PLOTTER* aPlotter ) const
{
if( m_part )
{
LIB_PINS libPins;
m_part->GetPins( libPins, GetUnit(), GetConvert() );
// Copy the source to stay const
LIB_SYMBOL tempSymbol( *m_part );
LIB_PINS tempPins;
tempSymbol.GetPins( tempPins, GetUnit(), GetConvert() );
TRANSFORM transform = GetTransform();
// Copy the pin info from the symbol to the temp pins
for( unsigned i = 0; i < tempPins.size(); ++ i )
{
SCH_PIN* symbolPin = GetPin( libPins[ i ] );
LIB_PIN* tempPin = tempPins[ i ];
tempPin->SetName( symbolPin->GetShownName() );
tempPin->SetType( symbolPin->GetType() );
tempPin->SetShape( symbolPin->GetShape() );
tempPin->Plot( aPlotter, m_pos, false, transform);
}
}
}
bool SCH_SYMBOL::HasBrightenedPins()
{
for( const auto& pin : m_pins )
+8
View File
@@ -650,6 +650,14 @@ public:
void Plot( PLOTTER* aPlotter ) const override;
/**
* Plot just the symbol pins. This is separated to match the GAL display order. The pins are
* ALSO plotted with the symbol group. This replotting allows us to ensure that they are shown above
* other elements in the schematic
* @param aPlotter
*/
void PlotPins( PLOTTER* aPlotter ) const;
EDA_ITEM* Clone() const override;
#if defined(DEBUG)
+10
View File
@@ -1528,6 +1528,11 @@ void SIM_PLOT_FRAME::onProbe( wxCommandEvent& event )
if( m_schematicFrame == nullptr )
return;
wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simProbe );
m_schematicFrame->Raise();
}
@@ -1540,6 +1545,11 @@ void SIM_PLOT_FRAME::onTune( wxCommandEvent& event )
if( m_schematicFrame == nullptr )
return;
wxWindow* blocking_dialog = m_schematicFrame->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
m_schematicFrame->GetToolManager()->RunAction( EE_ACTIONS::simTune );
m_schematicFrame->Raise();
}
@@ -1119,6 +1119,9 @@ void SYMBOL_EDIT_FRAME::CommonSettingsChanged( bool aEnvVarsChanged, bool aTextV
GetCanvas()->GetGAL()->SetAxesColor( m_colorSettings->GetColor( LAYER_SCHEMATIC_GRID_AXES ) );
GetCanvas()->GetGAL()->DrawGrid();
GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL );
GetCanvas()->Refresh();
RecreateToolbars();
if( aEnvVarsChanged )
@@ -1166,6 +1169,7 @@ void SYMBOL_EDIT_FRAME::RebuildView()
GetCanvas()->GetView()->HideDrawingSheet();
GetCanvas()->GetView()->ClearHiddenFlags();
GetCanvas()->GetView()->UpdateAllItems( KIGFX::ALL );
GetCanvas()->Refresh();
}
+5 -1
View File
@@ -460,7 +460,11 @@ void SYMBOL_VIEWER_FRAME::onUpdateUnitChoice( wxUpdateUIEvent& aEvent )
m_unitChoice->Clear();
for( int ii = 0; ii < unit_count; ii++ )
m_unitChoice->Append( wxString::Format( _( "Unit %c" ), 'A' + ii ) );
{
wxString sub = LIB_SYMBOL::SubReference( ii + 1, false );
wxString unit = wxString::Format( _( "Unit %s" ), sub );
m_unitChoice->Append( unit );
}
}
+3
View File
@@ -112,6 +112,9 @@ bool BACK_ANNOTATE::FetchNetlistFromPCB( std::string& aNetlist )
frame->OpenProjectFiles( std::vector<wxString>( 1, fn.GetFullPath() ) );
}
if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
m_frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_PCB_GET_NETLIST, aNetlist );
return true;
}
+2 -1
View File
@@ -646,7 +646,8 @@ TOOL_ACTION EE_ACTIONS::toggleHiddenFields( "eeschema.EditorControl.showHiddenFi
_( "Show Hidden Fields" ), _( "Toggle display of hidden text fields" ) );
TOOL_ACTION EE_ACTIONS::toggleForceHV( "eeschema.EditorControl.forceHVLines",
AS_GLOBAL, 0, "",
AS_GLOBAL,
MD_SHIFT + ' ', "",
_( "Force H/V Wires and Buses" ), _( "Switch H & V only mode for new wires and buses" ),
BITMAPS::lines90 );
+3
View File
@@ -482,6 +482,9 @@ int EE_INSPECTION_TOOL::RunSimulation( const TOOL_EVENT& aEvent )
if( !simFrame )
return -1;
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
simFrame->Show( true );
// On Windows, Raise() does not bring the window on screen, when iconized
+5
View File
@@ -348,6 +348,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
{
symbol->SetPosition( (wxPoint)cursorPos );
m_view->Update( symbol );
m_frame->SetMsgPanel( symbol );
}
else if( symbol && evt->IsAction( &ACTIONS::doDelete ) )
{
@@ -570,6 +571,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
m_view->ClearPreview();
m_view->AddToPreview( image->Clone() );
m_view->RecacheAllItems(); // Bitmaps are cached in Opengl
m_frame->SetMsgPanel( image );
}
else if( image && evt->IsAction( &ACTIONS::doDelete ) )
{
@@ -775,6 +777,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
previewItem->SetPosition( (wxPoint)cursorPos );
m_view->ClearPreview();
m_view->AddToPreview( previewItem->Clone() );
m_frame->SetMsgPanel( previewItem );
}
else if( evt->Category() == TC_COMMAND )
{
@@ -1031,6 +1034,7 @@ int SCH_DRAWING_TOOLS::TwoClickPlace( const TOOL_EVENT& aEvent )
{
m_view->AddToPreview( aChild->Clone() );
} );
m_frame->SetMsgPanel( item );
};
auto cleanup =
@@ -1420,6 +1424,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
sizeSheet( sheet, cursorPos );
m_view->ClearPreview();
m_view->AddToPreview( sheet->Clone() );
m_frame->SetMsgPanel( sheet );
}
else if( evt->IsClick( BUT_RIGHT ) )
{
+6
View File
@@ -1394,6 +1394,9 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR,
true );
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
editor->LoadSymbolFromSchematic( symbol );
editor->Show( true );
@@ -1404,6 +1407,9 @@ int SCH_EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
auto editor = (SYMBOL_EDIT_FRAME*) m_frame->Kiway().Player( FRAME_SCH_SYMBOL_EDITOR,
true );
if( wxWindow* blocking_win = editor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
editor->LoadSymbol( symbol->GetLibId(), symbol->GetUnit(), symbol->GetConvert() );
editor->Show( true );
+11
View File
@@ -765,6 +765,9 @@ int SCH_EDITOR_CONTROL::SimProbe( const TOOL_EVENT& aEvent )
if( !simFrame ) // Defensive coding; shouldn't happen.
return 0;
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
// Deactivate other tools; particularly important if another PICKER is currently running
Activate();
@@ -912,7 +915,12 @@ int SCH_EDITOR_CONTROL::SimTune( const TOOL_EVENT& aEvent )
KIWAY_PLAYER* simFrame = m_frame->Kiway().Player( FRAME_SIMULATOR, false );
if( simFrame )
{
if( wxWindow* blocking_win = simFrame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
static_cast<SIM_PLOT_FRAME*>( simFrame )->AddTuner( symbol );
}
// We do not really want to keep a symbol selected in schematic,
// so clear the current selection
@@ -1986,6 +1994,9 @@ int SCH_EDITOR_CONTROL::EditWithSymbolEditor( const TOOL_EVENT& aEvent )
if( symbolEditor )
{
if( wxWindow* blocking_win = symbolEditor->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
if( aEvent.IsAction( &EE_ACTIONS::editWithLibEdit ) )
symbolEditor->LoadSymbolFromSchematic( symbol );
else if( aEvent.IsAction( &EE_ACTIONS::editLibSymbolWithLibEdit ) )
+6 -1
View File
@@ -518,6 +518,11 @@ int SYMBOL_EDITOR_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent )
return 0;
}
wxWindow* blocking_dialog = schframe->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
wxCHECK( libSymbol->GetLibId().IsValid(), 0 );
SCH_SYMBOL* symbol = new SCH_SYMBOL( *libSymbol, libId, &schframe->GetCurrentSheet(),
@@ -529,7 +534,7 @@ int SYMBOL_EDITOR_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent )
symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
schframe->Raise();
schframe->GetToolManager()->RunAction( EE_ACTIONS::placeSymbol, true, symbol );
schframe->GetToolManager()->RunAction( EE_ACTIONS::placeSymbol, false, symbol );
}
return 0;
@@ -1,8 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 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 as published by the
@@ -22,25 +21,10 @@
* This file is auto-generated by CMake when MAINTAIN_PNGS is on. Do not edit by hand!
*/
#ifndef KICAD_BITMAP_INFO_H
#define KICAD_BITMAP_INFO_H
#include <vector>
#include <bitmaps/bitmaps_list.h>
#include <bitmaps/bitmap_info.h>
#include <wx/string.h> // wxT
struct BITMAP_INFO
void BuildBitmapInfo( std::unordered_map<BITMAPS, std::vector<BITMAP_INFO>>& aBitmapInfoCache )
{
BITMAPS id;
wxString filename;
int height;
wxString theme;
};
const std::vector<BITMAP_INFO> g_BitmapInfo = {
${BITMAP_INFO_LIST}
};
#endif // KICAD_BITMAP_INFO_H
File diff suppressed because it is too large Load Diff
+44 -44
View File
@@ -24,7 +24,7 @@
#ifndef GL_UTILS_H
#define GL_UTILS_H
#include <gal/opengl/kiglew.h> // Must be included first
#include <gal/opengl/kiglew.h> // Must be included first
#include <wx/glcanvas.h>
#include <wx/utils.h>
@@ -45,62 +45,63 @@ public:
/// Windows would include <wglext.h> and call wglSwapIntervalEXT
#if defined( __linux__ ) && !defined( KICAD_USE_EGL )
Display *dpy = glXGetCurrentDisplay();
GLXDrawable drawable = glXGetCurrentDrawable();
std::string vendor( reinterpret_cast<const char*>( glGetString( GL_VENDOR ) ) );
bool is_mesa = ( vendor.find( "Mesa" ) != std::string::npos );
if( !is_mesa && glXSwapIntervalEXT && glXQueryDrawable && dpy && drawable )
if( Display* dpy = glXGetCurrentDisplay() )
{
GLXDrawable drawable = glXGetCurrentDrawable();
std::string exts( glXQueryExtensionsString( dpy, DefaultScreen( dpy ) ) );
if( aVal < 0 )
if( glXSwapIntervalEXT && glXQueryDrawable && drawable
&& exts.find( "GLX_EXT_swap_control" ) != std::string::npos )
{
if( exts.find( "GLX_EXT_swap_control_tear" ) == std::string::npos )
if( aVal < 0 )
{
aVal = 0;
}
else
{
// Even though the extensions might be available,
// we need to be sure that late/adaptive swaps are
// enabled on the drawable.
unsigned lateSwapsEnabled = 0;
glXQueryDrawable( dpy, drawable, GLX_LATE_SWAPS_TEAR_EXT, &lateSwapsEnabled );
if( !lateSwapsEnabled )
if( exts.find( "GLX_EXT_swap_control_tear" ) == std::string::npos )
{
aVal = 0;
}
else
{
// Even though the extensions might be available,
// we need to be sure that late/adaptive swaps are
// enabled on the drawable.
unsigned lateSwapsEnabled = 0;
glXQueryDrawable( dpy, drawable, GLX_LATE_SWAPS_TEAR_EXT,
&lateSwapsEnabled );
if( !lateSwapsEnabled )
{
aVal = 0;
}
}
}
unsigned clampedInterval;
glXSwapIntervalEXT( dpy, drawable, aVal );
glXQueryDrawable( dpy, drawable, GLX_SWAP_INTERVAL_EXT, &clampedInterval );
return clampedInterval;
}
unsigned clampedInterval;
glXSwapIntervalEXT( dpy, drawable, aVal );
glXQueryDrawable( dpy, drawable, GLX_SWAP_INTERVAL_EXT, &clampedInterval );
if( glXSwapIntervalMESA && glXGetSwapIntervalMESA
&& exts.find( "GLX_MESA_swap_control" ) != std::string::npos )
{
if( aVal < 0 )
aVal = 0;
return clampedInterval;
}
glXSwapIntervalMESA( aVal );
return glXGetSwapIntervalMESA();
}
if( glXSwapIntervalMESA &&glXGetSwapIntervalMESA )
{
if( aVal < 0 )
aVal = 0;
if( aVal > 0 && glXSwapIntervalSGI
&& exts.find( "GLX_SGI_swap_control" ) != std::string::npos )
{
if( glXSwapIntervalSGI( aVal ) )
glXSwapIntervalSGI( 1 );
glXSwapIntervalMESA( aVal );
return glXGetSwapIntervalMESA();
}
if( glXSwapIntervalSGI )
{
if( aVal < 1 )
aVal = 1;
if( glXSwapIntervalSGI( aVal ) )
glXSwapIntervalSGI( 1 );
return 1;
return 1;
}
}
return std::numeric_limits<int>::max();
@@ -111,4 +112,3 @@ public:
};
#endif /* GL_CONTEXT_MANAGER_H */
+2 -7
View File
@@ -27,13 +27,12 @@
#include <unordered_map>
#include <eda_rect.h>
#include <wx/string.h>
// First some utility classes and functions
/// Equality test for "const char*" type used in very specialized KEYWORD_MAP below
struct iequal_to : std::binary_function< const char*, const char*, bool >
struct iequal_to
{
bool operator()( const char* x, const char* y ) const
{
@@ -77,7 +76,7 @@ struct fnv_1a
/// Hash function for wxString, counterpart of std::string hash
struct WXSTRING_HASH : std::unary_function<wxString, std::size_t>
struct WXSTRING_HASH
{
std::size_t operator()( const wxString& aString ) const
{
@@ -128,9 +127,5 @@ struct WXSTRING_HASH : std::unary_function<wxString, std::size_t>
*/
typedef std::unordered_map< const char*, int, fnv_1a, iequal_to > KEYWORD_MAP;
/// Map a C string to an EDA_RECT.
/// The key is the classname of the derived wxformbuilder dialog.
typedef std::unordered_map< std::string, EDA_RECT > RECT_MAP;
#endif // HASHTABLES_H_
+9
View File
@@ -392,6 +392,13 @@ public:
bool ProcessEvent( wxEvent& aEvent ) override;
/**
* Gets the window pointer to the blocking dialog (to send it signals)
* @return Pointer to blocking dialog window or null if none
*/
wxWindow* GetBlockingDialog();
void SetBlockingDialog( wxWindow* aWin );
private:
/// Get the [path &] name of the DSO holding the requested FACE_T.
const wxString dso_search_path( FACE_T aFaceId );
@@ -426,6 +433,8 @@ private:
wxFrame* m_top; // Usually m_top is the Project manager
wxWindowID m_blockingDialog;
// An array to store the window ID of PLAYER frames which were run.
// A non empty name means only a PLAYER was run at least one time.
// Empty entries are represented by wxID_NONE.
+9
View File
@@ -56,6 +56,15 @@ public:
return *m_kiway;
}
/**
* Safety check before asking for the Kiway reference
* @return true if kiway is non-null
*/
bool HasKiway() const
{
return m_kiway != nullptr;
}
/**
* Return a reference to the #PROJECT associated with this #KIWAY.
*/
+3
View File
@@ -578,6 +578,9 @@ private:
///< Pointer to the state object corresponding to the currently executed tool.
TOOL_STATE* m_activeState;
///< True if the tool manager is shutting down (don't process additional events)
bool m_shuttingDown;
};
#endif // __TOOL_MANAGER_H
+10
View File
@@ -183,6 +183,11 @@ void KICAD_MANAGER_FRAME::ImportNonKiCadProject( const wxString& aWindowTitle,
{
KIWAY_PLAYER* schframe = Kiway().Player( FRAME_SCH, true );
wxWindow* blocking_dialog = schframe->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
packet = StrPrintf( "%d\n%s", aSchFileType, TO_UTF8( schCopy.GetFullPath() ) );
schframe->Kiway().ExpressMail( FRAME_SCH, MAIL_IMPORT_FILE, packet, this );
@@ -203,6 +208,11 @@ void KICAD_MANAGER_FRAME::ImportNonKiCadProject( const wxString& aWindowTitle,
{
KIWAY_PLAYER* pcbframe = Kiway().Player( FRAME_PCB_EDITOR, true );
wxWindow* blocking_dialog = pcbframe->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
if( !pcbframe->IsVisible() )
pcbframe->Show( true );
+20 -9
View File
@@ -45,8 +45,8 @@
#include <wx/zipstrm.h>
const std::tuple<int, int> PLUGIN_CONTENT_MANAGER::m_kicad_version =
KICAD_MAJOR_MINOR_VERSION_TUPLE;
const std::tuple<int, int, int> PLUGIN_CONTENT_MANAGER::m_kicad_version =
KICAD_MAJOR_MINOR_PATCH_TUPLE;
class THROWING_ERROR_HANDLER : public nlohmann::json_schema::error_handler
@@ -510,19 +510,30 @@ void PLUGIN_CONTENT_MANAGER::preparePackage( PCM_PACKAGE& aPackage )
// Determine compatibility
ver.compatible = true;
auto parse_major_minor = []( const wxString& version )
auto parse_version_tuple = []( const wxString& version, int deflt )
{
wxStringTokenizer tokenizer( version, wxT( "." ) );
int ver_major = wxAtoi( tokenizer.GetNextToken() );
int ver_minor = wxAtoi( tokenizer.GetNextToken() );
return std::tuple<int, int>( ver_major, ver_minor );
int ver_major = deflt;
int ver_minor = deflt;
int ver_patch = deflt;
wxStringTokenizer tokenizer( version, "." );
ver_major = wxAtoi( tokenizer.GetNextToken() );
if( tokenizer.HasMoreTokens() )
ver_minor = wxAtoi( tokenizer.GetNextToken() );
if( tokenizer.HasMoreTokens() )
ver_patch = wxAtoi( tokenizer.GetNextToken() );
return std::tuple<int, int, int>( ver_major, ver_minor, ver_patch );
};
if( parse_major_minor( ver.kicad_version ) > m_kicad_version )
if( parse_version_tuple( ver.kicad_version, 0 ) > m_kicad_version )
ver.compatible = false;
if( ver.kicad_version_max
&& parse_major_minor( ver.kicad_version_max.get() ) < m_kicad_version )
&& parse_version_tuple( ver.kicad_version_max.get(), 999 ) < m_kicad_version )
ver.compatible = false;
#ifdef __WXMSW__
+1 -1
View File
@@ -313,7 +313,7 @@ private:
STRING_TUPLE_LIST m_repository_list; // (id, name, url) tuples
// Using sorted map to keep order of entries in installed list stable
std::map<wxString, PCM_INSTALLATION_ENTRY> m_installed;
const static std::tuple<int, int> m_kicad_version;
const static std::tuple<int, int, int> m_kicad_version;
};
#endif // PCM_H_
+1 -1
View File
@@ -49,7 +49,7 @@ void kimathLogDebug( const char* aFormatString, ... );
* result is: lower <= value <= upper
*</p>
*/
template <typename T> inline const T& Clamp( const T& lower, const T& value, const T& upper )
template <typename T> inline constexpr T Clamp( const T& lower, const T& value, const T& upper )
{
if( value < lower )
return lower;
+36 -1
View File
@@ -3,6 +3,7 @@
*
* Copyright (c) 2005 Michael Niedermayer <michaelni@gmx.at>
* Copyright (C) CERN
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@@ -29,6 +30,11 @@
#include <math/util.h>
#include <wx/log.h>
#ifdef _MSC_VER
#include <windows.h>
#include <intrin.h>
#endif
// Fix compatibility with wxWidgets version < 3.1.4
#ifndef wxASCII_STR
#define wxASCII_STR(s) wxString::FromAscii(s)
@@ -65,13 +71,42 @@ int rescale( int aNumerator, int aValue, int aDenominator )
template<>
int64_t rescale( int64_t aNumerator, int64_t aValue, int64_t aDenominator )
{
#ifdef __SIZEOF_INT128__
#if defined( _M_X64 ) && ( _MSC_VER >= 1920 )
int64_t productHi;
uint64_t productLo = static_cast<uint64_t>( _mul128( aNumerator, aValue, &productHi ) );
int64_t r = ( ( productHi < 0 ) ^ ( aDenominator < 0 ) ) ? -aDenominator / 2 : aDenominator / 2;
uint64_t rLo = static_cast<uint64_t>( r );
int64_t rHi = r < 0 ? -1ll : 0ll;
productLo += rLo;
productHi += rHi + ( productLo < rLo );
__try
{
int64_t remainder;
int64_t result = _div128( productHi, productLo, aDenominator, &remainder );
return result;
}
__except( ( GetExceptionCode() == EXCEPTION_INT_OVERFLOW ) ? EXCEPTION_EXECUTE_HANDLER
: EXCEPTION_CONTINUE_SEARCH )
{
kimathLogDebug( "Overflow in rescale (%lld * %lld + %lld) / %lld", aNumerator, aValue, r,
aDenominator );
}
return 0;
#elif defined( __SIZEOF_INT128__ )
__int128_t numerator = (__int128_t) aNumerator * (__int128_t) aValue;
if( ( numerator < 0 ) ^ ( aDenominator < 0 ) )
return ( numerator - aDenominator / 2 ) / aDenominator;
else
return ( numerator + aDenominator / 2 ) / aDenominator;
#else
int64_t r = 0;
int64_t sign = ( ( aNumerator < 0 ) ? -1 : 1 ) * ( aDenominator < 0 ? -1 : 1 ) *
+9 -6
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2019 Jean_Pierre Charras <jp.charras at wanadoo.fr>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-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
@@ -92,7 +92,7 @@ int DIALOG_GENDRILL::m_ZerosFormat = EXCELLON_WRITER::DECIMAL_FORMAT;
bool DIALOG_GENDRILL::m_MinimalHeader = false; // Only for Excellon format
bool DIALOG_GENDRILL::m_Mirror = false; // Only for Excellon format
bool DIALOG_GENDRILL::m_Merge_PTH_NPTH = false; // Only for Excellon format
int DIALOG_GENDRILL::m_mapFileType = 1;
int DIALOG_GENDRILL::m_mapFileType = 4; // The last choice in m_Choice_Drill_Map
int DIALOG_GENDRILL::m_drillFileType = 0;
bool DIALOG_GENDRILL::m_UseRouteModeForOvalHoles = true; // Use G00 route mode to "drill" oval holes
@@ -116,6 +116,10 @@ void DIALOG_GENDRILL::initDialog()
m_drillOriginIsAuxAxis = m_plotOpts.GetUseAuxOrigin();
// Ensure validity of m_mapFileType
if( m_mapFileType < 0 || m_mapFileType >= (int)m_Choice_Drill_Map->GetCount() )
m_mapFileType = m_Choice_Drill_Map->GetCount() - 1; // last item in list = default = PDF
InitDisplayParams();
}
@@ -368,11 +372,10 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles( bool aGenDrill, bool aGenMap )
m_pcbEditFrame->ClearMsgPanel();
WX_TEXT_CTRL_REPORTER reporter( m_messagesBox );
const PLOT_FORMAT filefmt[6] = {
const PLOT_FORMAT filefmt[] = {
// Keep these format ids in the same order than m_Choice_Drill_Map choices
PLOT_FORMAT::HPGL,
PLOT_FORMAT::POST,
PLOT_FORMAT::GERBER,
PLOT_FORMAT::GERBER, // Only X2 format because we need the .FileFunction attribute
PLOT_FORMAT::DXF,
PLOT_FORMAT::SVG,
PLOT_FORMAT::PDF
@@ -381,7 +384,7 @@ void DIALOG_GENDRILL::GenDrillAndMapFiles( bool aGenDrill, bool aGenMap )
unsigned choice = (unsigned) m_Choice_Drill_Map->GetSelection();
if( choice >= arrayDim( filefmt ) )
choice = 1;
choice = arrayDim( filefmt )-1; // Last choice = PDF
// Create output directory if it does not exist (also transform it in absolute form).
// Bail if it fails.
+6 -7
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// C++ code generated with wxFormBuilder (version 3.10.0)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -79,11 +79,11 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
bMiddleSizer->Add( sbSizer6, 1, wxEXPAND|wxALL, 5 );
wxString m_Choice_Drill_MapChoices[] = { _("HPGL"), _("PostScript"), _("Gerber"), _("DXF"), _("SVG"), _("PDF") };
wxString m_Choice_Drill_MapChoices[] = { _("PostScript"), _("Gerber X2"), _("DXF"), _("SVG"), _("PDF") };
int m_Choice_Drill_MapNChoices = sizeof( m_Choice_Drill_MapChoices ) / sizeof( wxString );
m_Choice_Drill_Map = new wxRadioBox( this, wxID_ANY, _("Map File Format"), wxDefaultPosition, wxDefaultSize, m_Choice_Drill_MapNChoices, m_Choice_Drill_MapChoices, 1, wxRA_SPECIFY_COLS );
m_Choice_Drill_Map->SetSelection( 1 );
m_Choice_Drill_Map->SetToolTip( _("Creates a drill map in PS, HPGL or other formats") );
m_Choice_Drill_Map->SetSelection( 4 );
m_Choice_Drill_Map->SetToolTip( _("Creates a drill map in PDF or other formats") );
bMiddleSizer->Add( m_Choice_Drill_Map, 0, wxALL|wxEXPAND, 5 );
@@ -133,7 +133,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
bLeftSizer->Add( fgSizer1, 0, wxEXPAND, 5 );
bmiddlerSizer->Add( bLeftSizer, 1, wxEXPAND, 5 );
bmiddlerSizer->Add( bLeftSizer, 0, wxEXPAND, 5 );
wxBoxSizer* bRightBoxSizer;
bRightBoxSizer = new wxBoxSizer( wxVERTICAL );
@@ -193,7 +193,7 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
bRightBoxSizer->Add( sbSizerHoles, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
bmiddlerSizer->Add( bRightBoxSizer, 1, wxEXPAND|wxTOP, 5 );
bmiddlerSizer->Add( bRightBoxSizer, 0, wxEXPAND|wxTOP, 5 );
bMainSizer->Add( bmiddlerSizer, 0, wxEXPAND|wxTOP, 2 );
@@ -231,7 +231,6 @@ DIALOG_GENDRILL_BASE::DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id, con
this->SetSizer( bMainSizer );
this->Layout();
bMainSizer->Fit( this );
this->Centre( wxBOTH );
+12 -7
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="15" />
<FileVersion major="1" minor="16" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
@@ -14,6 +14,7 @@
<property name="file">dialog_gendrill_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">dialog_gendrill_base</property>
@@ -25,6 +26,7 @@
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
@@ -45,11 +47,12 @@
<property name="minimum_size"></property>
<property name="name">DIALOG_GENDRILL_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="size">643,558</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title">Generate Drill Files</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
@@ -206,6 +209,7 @@
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
@@ -717,7 +721,7 @@
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices">&quot;HPGL&quot; &quot;PostScript&quot; &quot;Gerber&quot; &quot;DXF&quot; &quot;SVG&quot; &quot;PDF&quot;</property>
<property name="choices">&quot;PostScript&quot; &quot;Gerber X2&quot; &quot;DXF&quot; &quot;SVG&quot; &quot;PDF&quot;</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
@@ -749,13 +753,13 @@
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">1</property>
<property name="selection">4</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxRA_SPECIFY_COLS</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Creates a drill map in PS, HPGL or other formats</property>
<property name="tooltip">Creates a drill map in PDF or other formats</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
@@ -770,7 +774,7 @@
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bLeftSizer</property>
@@ -1121,7 +1125,7 @@
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP</property>
<property name="proportion">1</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bRightBoxSizer</property>
@@ -1873,6 +1877,7 @@
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
+4 -3
View File
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// C++ code generated with wxFormBuilder (version 3.10.0)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -74,7 +74,7 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM
wxButton* m_sdbSizerApply;
wxButton* m_sdbSizerCancel;
// Virtual event handlers, overide them in your derived class
// Virtual event handlers, override them in your derived class
virtual void onCloseDlg( wxCloseEvent& event ) { event.Skip(); }
virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
virtual void onFileFormatSelection( wxCommandEvent& event ) { event.Skip(); }
@@ -88,7 +88,8 @@ class DIALOG_GENDRILL_BASE : public DIALOG_SHIM
public:
DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generate Drill Files"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_GENDRILL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generate Drill Files"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 643,558 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_GENDRILL_BASE();
};
+41 -37
View File
@@ -782,11 +782,19 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
// Local overrides take precedence over everything *except* board min clearance
if( aConstraintType == CLEARANCE_CONSTRAINT || aConstraintType == HOLE_CLEARANCE_CONSTRAINT )
{
int override = 0;
int override_val = 0;
int overrideA = 0;
int overrideB = 0;
if( ac && !b_is_non_copper )
overrideA = ac->GetLocalClearanceOverrides( nullptr );
if( bc && !a_is_non_copper )
overrideB = bc->GetLocalClearanceOverrides( nullptr );
if( overrideA > 0 || overrideB > 0 )
{
int overrideA = ac->GetLocalClearanceOverrides( nullptr );
wxString msg;
if( overrideA > 0 )
{
@@ -795,13 +803,8 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
EscapeHTML( a->GetSelectMenuText( UNITS ) ),
REPORT_VALUE( overrideA ) ) )
override = ac->GetLocalClearanceOverrides( &m_msg );
override_val = ac->GetLocalClearanceOverrides( &msg );
}
}
if( bc && !a_is_non_copper )
{
int overrideB = bc->GetLocalClearanceOverrides( nullptr );
if( overrideB > 0 )
{
@@ -810,41 +813,41 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
EscapeHTML( b->GetSelectMenuText( UNITS ) ),
EscapeHTML( REPORT_VALUE( overrideB ) ) ) )
if( overrideB > override )
override = bc->GetLocalClearanceOverrides( &m_msg );
if( overrideB > override_val )
override_val = bc->GetLocalClearanceOverrides( &msg );
}
}
if( override )
{
if( aConstraintType == CLEARANCE_CONSTRAINT )
if( override_val )
{
if( override < m_designSettings->m_MinClearance )
if( aConstraintType == CLEARANCE_CONSTRAINT )
{
override = m_designSettings->m_MinClearance;
m_msg = _( "board minimum" );
if( override_val < m_designSettings->m_MinClearance )
{
override_val = m_designSettings->m_MinClearance;
msg = _( "board minimum" );
REPORT( "" )
REPORT( wxString::Format( _( "Board minimum clearance: %s." ),
REPORT_VALUE( override ) ) )
REPORT( "" )
REPORT( wxString::Format( _( "Board minimum clearance: %s." ),
REPORT_VALUE( override_val ) ) )
}
}
}
else
{
if( override < m_designSettings->m_HoleClearance )
else
{
override = m_designSettings->m_HoleClearance;
m_msg = _( "board minimum hole" );
if( override_val < m_designSettings->m_HoleClearance )
{
override_val = m_designSettings->m_HoleClearance;
msg = _( "board minimum hole" );
REPORT( "" )
REPORT( wxString::Format( _( "Board minimum hole clearance: %s." ),
REPORT_VALUE( override ) ) )
REPORT( "" )
REPORT( wxString::Format( _( "Board minimum hole clearance: %s." ),
REPORT_VALUE( override_val ) ) )
}
}
}
constraint.SetName( m_msg );
constraint.m_Value.SetMin( override );
return constraint;
constraint.SetName( msg );
constraint.m_Value.SetMin( override_val );
return constraint;
}
}
}
@@ -879,10 +882,10 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
wxString min = wxT( "<i>" ) + _( "undefined" ) + wxT( "</i>" );
wxString opt = wxT( "<i>" ) + _( "undefined" ) + wxT( "</i>" );
wxString max = wxT( "<i>" ) + _( "undefined" ) + wxT( "</i>" );
wxString msg;
if( implicit )
{
wxString msg;
opt = StringFromValue( UNITS, c->constraint.m_Value.Opt(), true );
switch( c->constraint.m_Type )
@@ -1108,6 +1111,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
int localA = ac ? ac->GetLocalClearance( nullptr ) : 0;
int localB = bc ? bc->GetLocalClearance( nullptr ) : 0;
int clearance = global;
wxString msg;
if( localA > 0 )
{
@@ -1117,7 +1121,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
REPORT_VALUE( localA ) ) )
if( localA > clearance )
clearance = ac->GetLocalClearance( &m_msg );
clearance = ac->GetLocalClearance( &msg );
}
if( localB > 0 )
@@ -1128,13 +1132,13 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
REPORT_VALUE( localB ) ) )
if( localB > clearance )
clearance = bc->GetLocalClearance( &m_msg );
clearance = bc->GetLocalClearance( &msg );
}
if( localA > global || localB > global )
{
constraint.SetParentRule( nullptr );
constraint.SetName( m_msg );
constraint.SetName( msg );
constraint.m_Value.SetMin( clearance );
return constraint;
}
-1
View File
@@ -233,7 +233,6 @@ protected:
REPORTER* m_reporter;
PROGRESS_REPORTER* m_progressReporter;
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
std::shared_ptr<KIGFX::VIEW_OVERLAY> m_debugOverlay;
};
-2
View File
@@ -132,8 +132,6 @@ protected:
std::unordered_map<const DRC_RULE*, int> m_stats;
bool m_isRuleDriven = true;
bool m_enabled = true;
wxString m_msg; // Allocating strings gets expensive enough to want to avoid it
};
#endif // DRC_TEST_PROVIDER__H
@@ -123,20 +123,21 @@ bool DRC_TEST_PROVIDER_ANNULAR_WIDTH::Run()
if( fail_min || fail_max )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ANNULAR_WIDTH );
wxString msg;
if( fail_min )
m_msg.Printf( _( "(%s min annular width %s; actual %s)" ),
msg.Printf( _( "(%s min annular width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), v_min ),
MessageTextFromValue( userUnits(), annularWidth ) );
if( fail_max )
m_msg.Printf( _( "(%s max annular width %s; actual %s)" ),
msg.Printf( _( "(%s max annular width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), v_max ),
MessageTextFromValue( userUnits(), annularWidth ) );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() );
@@ -307,13 +307,14 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
if( trackShape->Collide( otherShape.get(), clearance - m_drcEpsilon, &actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
wxString msg;
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetItems( track, other );
drce->SetViolatingRule( constraint.GetParentRule() );
@@ -353,14 +354,16 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackAgainstItem( PCB_TRACK* track,
std::max( 0, clearance - m_drcEpsilon ),
&actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
wxString msg;
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetItems( track, other );
drce->SetViolatingRule( constraint.GetParentRule() );
@@ -441,13 +444,14 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem
&actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
wxString msg;
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetItems( aItem, zone );
drce->SetViolatingRule( constraint.GetParentRule() );
@@ -486,13 +490,14 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testItemAgainstZones( BOARD_ITEM* aItem
&actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
wxString msg;
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetItems( aItem, zone );
drce->SetViolatingRule( constraint.GetParentRule() );
@@ -650,12 +655,13 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
&& testShorting )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_SHORTING_ITEMS );
wxString msg;
m_msg.Printf( _( "(nets %s and %s)" ),
msg.Printf( _( "(nets %s and %s)" ),
pad->GetNetname(),
otherPad->GetNetname() );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetItems( pad, otherPad );
reportViolation( drce, otherPad->GetPosition() );
@@ -674,13 +680,14 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
&actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_CLEARANCE );
wxString msg;
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetItems( pad, other );
drce->SetViolatingRule( constraint.GetParentRule() );
@@ -702,13 +709,14 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
&actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
wxString msg;
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetItems( pad, other );
drce->SetViolatingRule( constraint.GetParentRule() );
@@ -724,13 +732,14 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
&actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
wxString msg;
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetItems( pad, other );
drce->SetViolatingRule( constraint.GetParentRule() );
@@ -749,13 +758,14 @@ bool DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadAgainstItem( PAD* pad, SHAPE* pa
&actual, &pos ) )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_HOLE_CLEARANCE );
wxString msg;
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetItems( pad, otherVia );
drce->SetViolatingRule( constraint.GetParentRule() );
@@ -986,13 +996,14 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
else
{
drce = DRC_ITEM::Create( DRCE_CLEARANCE );
wxString msg;
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), zone2zoneClearance ),
MessageTextFromValue( userUnits(), conflict.second ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
}
drce->SetItems( zoneRef, zoneToTest );
@@ -210,12 +210,13 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
if( clearance > 0 )
{
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
wxString msg;
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetViolatingRule( constraint.GetParentRule() );
}
@@ -237,12 +238,13 @@ bool DRC_TEST_PROVIDER_COURTYARD_CLEARANCE::testCourtyardClearances()
if( clearance > 0 )
{
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
wxString msg;
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), clearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetViolatingRule( constraint.GetParentRule() );
}
@@ -459,13 +459,14 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
if ( val.HasMax() && totalUncoupled > val.Max() )
{
auto drce = DRC_ITEM::Create( DRCE_DIFF_PAIR_UNCOUPLED_LENGTH_TOO_LONG );
wxString msg;
m_msg = wxString::Format( _( "(%s maximum uncoupled length: %s; actual: %s)" ),
msg = wxString::Format( _( "(%s maximum uncoupled length: %s; actual: %s)" ),
maxUncoupledConstraint->GetParentRule()->m_Name,
MessageTextFromValue( userUnits(), val.Max() ),
MessageTextFromValue( userUnits(), totalUncoupled ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
auto pit = it.second.itemsP.begin();
auto nit = it.second.itemsN.begin();
@@ -495,22 +496,23 @@ bool test::DRC_TEST_PROVIDER_DIFF_PAIR_COUPLING::Run()
{
auto val = gapConstraint->GetValue();
auto drcItem = DRC_ITEM::Create( DRCE_DIFF_PAIR_GAP_OUT_OF_RANGE );
wxString msg;
m_msg = drcItem->GetErrorText() + wxT( " (" ) +
msg = drcItem->GetErrorText() + wxT( " (" ) +
gapConstraint->GetParentRule()->m_Name + wxS( " " );
if( val.HasMin() )
m_msg += wxString::Format( _( "minimum gap: %s; " ),
msg += wxString::Format( _( "minimum gap: %s; " ),
MessageTextFromValue( userUnits(), val.Min() ) );
if( val.HasMax() )
m_msg += wxString::Format( _( "maximum gap: %s; " ),
msg += wxString::Format( _( "maximum gap: %s; " ),
MessageTextFromValue( userUnits(), val.Max() ) );
m_msg += wxString::Format( _( "actual: %s)" ),
msg += wxString::Format( _( "actual: %s)" ),
MessageTextFromValue( userUnits(), cpair.computedGap ) );
drcItem->SetErrorMessage( m_msg );
drcItem->SetErrorMessage( msg );
drcItem->AddItem( cpair.parentP );
drcItem->AddItem( cpair.parentN );
+3 -2
View File
@@ -85,11 +85,12 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
if( constraint.m_DisallowFlags )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_ALLOWED_ITEMS );
wxString msg;
m_msg.Printf( drcItem->GetErrorText() + wxS( " (%s)" ),
msg.Printf( drcItem->GetErrorText() + wxS( " (%s)" ),
constraint.GetName() );
drcItem->SetErrorMessage( m_msg );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() );
@@ -97,12 +97,13 @@ bool DRC_TEST_PROVIDER_EDGE_CLEARANCE::testAgainstEdge( BOARD_ITEM* item, SHAPE*
// Only report clearance info if there is any; otherwise it's just a straight collision
if( minClearance > 0 )
{
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
wxString msg;
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), minClearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
}
drce->SetItems( edge->m_Uuid, item->m_Uuid );
+8 -6
View File
@@ -156,23 +156,24 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkPad( PAD* aPad )
if( fail_min || fail_max )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_DRILL_OUT_OF_RANGE );
wxString msg;
if( fail_min )
{
m_msg.Printf( _( "(%s min width %s; actual %s)" ),
msg.Printf( _( "(%s min width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), holeMinor ) );
}
else
{
m_msg.Printf( _( "(%s max width %s; actual %s)" ),
msg.Printf( _( "(%s max width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), holeMajor ) );
}
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
drcItem->SetItems( aPad );
drcItem->SetViolatingRule( constraint.GetParentRule() );
@@ -221,23 +222,24 @@ void DRC_TEST_PROVIDER_HOLE_SIZE::checkVia( PCB_VIA* via, bool aExceedMicro, boo
if( fail_min || fail_max )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( errorCode );
wxString msg;
if( fail_min )
{
m_msg.Printf( _( "(%s min width %s; actual %s)" ),
msg.Printf( _( "(%s min width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), via->GetDrillValue() ) );
}
else
{
m_msg.Printf( _( "(%s max width %s; actual %s)" ),
msg.Printf( _( "(%s max width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintValue ),
MessageTextFromValue( userUnits(), via->GetDrillValue() ) );
}
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
drcItem->SetItems( via );
drcItem->SetViolatingRule( constraint.GetParentRule() );
@@ -309,13 +309,14 @@ bool DRC_TEST_PROVIDER_HOLE_TO_HOLE::testHoleAgainstHole( BOARD_ITEM* aItem, SHA
if( minClearance >= 0 && actual < minClearance )
{
std::shared_ptr<DRC_ITEM> drce = DRC_ITEM::Create( DRCE_DRILLED_HOLES_TOO_CLOSE );
wxString msg;
m_msg.Printf( _( "(%s min %s; actual %s)" ),
msg.Printf( _( "(%s min %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), minClearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
drce->SetItems( aItem, aOther );
drce->SetViolatingRule( constraint.GetParentRule() );
+15 -10
View File
@@ -116,13 +116,14 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
if( m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_FOOTPRINT ) )
break;
m_msg.Printf( _( "Missing footprint %s (%s)" ),
wxString msg;
msg.Printf( _( "Missing footprint %s (%s)" ),
component->GetReference(),
component->GetValue() );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_MISSING_FOOTPRINT );
drcItem->SetErrorMessage( m_msg );
drcItem->SetErrorMessage( msg );
reportViolation( drcItem, wxPoint() );
}
else
@@ -140,31 +141,34 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
if( !pcb_netname.IsEmpty() && sch_net.GetPinName().IsEmpty() )
{
m_msg.Printf( _( "No corresponding pin found in schematic." ) );
wxString msg;
msg.Printf( _( "No corresponding pin found in schematic." ) );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
drcItem->SetErrorMessage( m_msg );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( pad );
reportViolation( drcItem, footprint->GetPosition() );
}
else if( pcb_netname.IsEmpty() && !sch_net.GetNetName().IsEmpty() )
{
m_msg.Printf( _( "Pad missing net given by schematic (%s)." ),
wxString msg;
msg.Printf( _( "Pad missing net given by schematic (%s)." ),
sch_net.GetNetName() );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
drcItem->SetErrorMessage( m_msg );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( pad );
reportViolation( drcItem, footprint->GetPosition() );
}
else if( pcb_netname != sch_net.GetNetName() )
{
m_msg.Printf( _( "Pad net (%s) doesn't match net given by schematic (%s)." ),
wxString msg;
msg.Printf( _( "Pad net (%s) doesn't match net given by schematic (%s)." ),
pcb_netname,
sch_net.GetNetName() );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
drcItem->SetErrorMessage( m_msg );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( pad );
reportViolation( drcItem, footprint->GetPosition() );
}
@@ -179,11 +183,12 @@ void DRC_TEST_PROVIDER_LVS::testFootprints( NETLIST& aNetlist )
if( !footprint->FindPadByNumber( sch_net.GetPinName() ) )
{
m_msg.Printf( _( "No pad found for pin %s in schematic." ),
wxString msg;
msg.Printf( _( "No pad found for pin %s in schematic." ),
sch_net.GetPinName() );
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_NET_CONFLICT );
drcItem->SetErrorMessage( m_msg );
drcItem->SetErrorMessage( msg );
drcItem->SetItems( footprint );
reportViolation( drcItem, footprint->GetPosition() );
}
@@ -114,23 +114,24 @@ void DRC_TEST_PROVIDER_MATCHED_LENGTH::checkLengths( DRC_CONSTRAINT& aConstraint
if( ( minViolation || maxViolation ) )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_LENGTH_OUT_OF_RANGE );
wxString msg;
if( minViolation )
{
m_msg.Printf( _( "(%s min length: %s; actual: %s)" ),
msg.Printf( _( "(%s min length: %s; actual: %s)" ),
aConstraint.GetName(),
MessageTextFromValue( userUnits(), minLen ),
MessageTextFromValue( userUnits(), ent.total ) );
}
else if( maxViolation )
{
m_msg.Printf( _( "(%s max length: %s; actual: %s)" ),
msg.Printf( _( "(%s max length: %s; actual: %s)" ),
aConstraint.GetName(),
MessageTextFromValue( userUnits(), maxLen ),
MessageTextFromValue( userUnits(), ent.total ) );
}
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
for( auto offendingTrack : ent.items )
drcItem->AddItem( offendingTrack );
@@ -158,15 +159,16 @@ void DRC_TEST_PROVIDER_MATCHED_LENGTH::checkSkews( DRC_CONSTRAINT& aConstraint,
if( aConstraint.GetValue().HasMax() && abs( skew ) > aConstraint.GetValue().Max() )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_SKEW_OUT_OF_RANGE );
wxString msg;
m_msg.Printf( _( "(%s max skew: %s; actual: %s; average net length: %s; actual: %s)" ),
msg.Printf( _( "(%s max skew: %s; actual: %s; average net length: %s; actual: %s)" ),
aConstraint.GetName(),
MessageTextFromValue( userUnits(), aConstraint.GetValue().Max() ),
MessageTextFromValue( userUnits(), skew ),
MessageTextFromValue( userUnits(), avgLength ),
MessageTextFromValue( userUnits(), ent.total ) );
drcItem->SetErrorMessage( drcItem->GetErrorText() + " " + m_msg );
drcItem->SetErrorMessage( drcItem->GetErrorText() + " " + msg );
for( BOARD_CONNECTED_ITEM* offendingTrack : ent.items )
drcItem->SetItems( offendingTrack );
@@ -187,13 +189,14 @@ void DRC_TEST_PROVIDER_MATCHED_LENGTH::checkViaCounts( DRC_CONSTRAINT& aConstrai
if( aConstraint.GetValue().HasMax() && ent.viaCount > aConstraint.GetValue().Max() )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TOO_MANY_VIAS );
wxString msg;
m_msg.Printf( _( "(%s max count: %d; actual: %d)" ),
msg.Printf( _( "(%s max count: %d; actual: %d)" ),
aConstraint.GetName(),
aConstraint.GetValue().Max(),
ent.viaCount );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
for( auto offendingTrack : ent.items )
drcItem->SetItems( offendingTrack );
+6 -4
View File
@@ -112,10 +112,11 @@ void DRC_TEST_PROVIDER_MISC::testOutline()
else
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_INVALID_OUTLINE );
wxString msg;
m_msg.Printf( _( "(no edges found on Edge.Cuts layer)" ) );
msg.Printf( _( "(no edges found on Edge.Cuts layer)" ) );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
drcItem->SetItems( m_board );
reportViolation( drcItem, m_board->GetBoundingBox().Centre() );
@@ -199,10 +200,11 @@ void DRC_TEST_PROVIDER_MISC::testDisabledLayers()
if( badLayer != UNDEFINED_LAYER )
{
std::shared_ptr<DRC_ITEM>drcItem = DRC_ITEM::Create( DRCE_DISABLED_LAYER_ITEM );
wxString msg;
m_msg.Printf( _( "(layer %s)" ), LayerName( badLayer ) );
msg.Printf( _( "(layer %s)" ), LayerName( badLayer ) );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
drcItem->SetItems( item );
reportViolation( drcItem, item->GetPosition() );
@@ -228,12 +228,14 @@ bool DRC_TEST_PROVIDER_SILK_CLEARANCE::Run()
if( minClearance > 0 )
{
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
wxString msg;
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetParentRule()->m_Name,
MessageTextFromValue( userUnits(), minClearance ),
MessageTextFromValue( userUnits(), actual ) );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
}
drcItem->SetItems( aRefItem->parent, aTestItem->parent );
@@ -157,12 +157,14 @@ bool DRC_TEST_PROVIDER_SILK_TO_MASK::Run()
if( minClearance > 0 )
{
m_msg.Printf( _( "(%s clearance %s; actual %s)" ),
wxString msg;
msg.Printf( _( "(%s clearance %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), minClearance ),
MessageTextFromValue( userUnits(), actual ) );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + m_msg );
drce->SetErrorMessage( drce->GetErrorText() + wxS( " " ) + msg );
}
drce->SetItems( aRefItem->parent, aTestItem->parent );
+4 -3
View File
@@ -128,23 +128,24 @@ bool DRC_TEST_PROVIDER_TRACK_WIDTH::Run()
if( fail_min || fail_max )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_TRACK_WIDTH );
wxString msg;
if( fail_min )
{
m_msg.Printf( _( "(%s min width %s; actual %s)" ),
msg.Printf( _( "(%s min width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintWidth ),
MessageTextFromValue( userUnits(), actual ) );
}
else
{
m_msg.Printf( _( "(%s max width %s; actual %s)" ),
msg.Printf( _( "(%s max width %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintWidth ),
MessageTextFromValue( userUnits(), actual ) );
}
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() );
+17 -16
View File
@@ -114,26 +114,27 @@ bool DRC_TEST_PROVIDER_VIA_DIAMETER::Run()
constraintDiameter = constraint.Value().Max();
}
if( fail_min )
{
m_msg.Printf( _( "(%s min diameter %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintDiameter ),
MessageTextFromValue( userUnits(), actual ) );
}
else if( fail_max )
{
m_msg.Printf( _( "(%s max diameter %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintDiameter ),
MessageTextFromValue( userUnits(), actual ) );
}
if( fail_min || fail_max )
{
std::shared_ptr<DRC_ITEM> drcItem = DRC_ITEM::Create( DRCE_VIA_DIAMETER );
wxString msg;
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + m_msg );
if( fail_min )
{
msg.Printf( _( "(%s min diameter %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintDiameter ),
MessageTextFromValue( userUnits(), actual ) );
}
else if( fail_max )
{
msg.Printf( _( "(%s max diameter %s; actual %s)" ),
constraint.GetName(),
MessageTextFromValue( userUnits(), constraintDiameter ),
MessageTextFromValue( userUnits(), actual ) );
}
drcItem->SetErrorMessage( drcItem->GetErrorText() + wxS( " " ) + msg );
drcItem->SetItems( item );
drcItem->SetViolatingRule( constraint.GetParentRule() );
+47 -26
View File
@@ -44,6 +44,7 @@
#include <pcbplot.h>
#include <gendrill_file_writer_base.h>
#include <pcb_painter.h>
#include <pcb_shape.h>
/* Conversion utilities - these will be used often in there... */
@@ -91,6 +92,12 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
EDA_RECT bbbox = m_pcb->GetBoardEdgesBoundingBox();
m_pcb->SetVisibleLayers( visibleLayers );
// Some formats cannot be used to generate a document like the map files
// Currently HPGL (old format not very used)
if( aFormat == PLOT_FORMAT::HPGL )
aFormat = PLOT_FORMAT::PDF;
// Calculate the scale for the format type, scale 1 in HPGL, drawing on
// an A4 sheet in PS, + text description of symbols
switch( aFormat )
@@ -101,17 +108,6 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
plotter->SetGerberCoordinatesFormat( 5 ); // format x.5 unit = mm
break;
case PLOT_FORMAT::HPGL: // Scale for HPGL format.
{
HPGL_PLOTTER* hpgl_plotter = new HPGL_PLOTTER;
plotter = hpgl_plotter;
hpgl_plotter->SetPenNumber( plot_opts.GetHPGLPenNum() );
hpgl_plotter->SetPenSpeed( plot_opts.GetHPGLPenSpeed() );
plotter->SetPageSettings( page_info );
plotter->SetViewport( offset, IU_PER_MILS / 10, scale, false );
}
break;
default:
wxASSERT( false );
KI_FALLTHROUGH;
@@ -191,30 +187,55 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
return false;
}
plotter->ClearHeaderLinesList();
// For the Gerber X2 format we need to set the "FileFunction" to Drillmap
// and set a few other options.
if( plotter->GetPlotterType() == PLOT_FORMAT::GERBER )
{
GERBER_PLOTTER* gbrplotter = static_cast <GERBER_PLOTTER*> ( plotter );
gbrplotter->DisableApertMacros( false );
gbrplotter->UseX2format( true ); // Mandatory
gbrplotter->UseX2NetAttributes( false ); // net attributes hace no meaning here
// Attributes are added using X2 format
AddGerberX2Header( gbrplotter, m_pcb, false );
wxString text;
// Add the TF.FileFunction
text = "%TF.FileFunction,Drillmap*%";
gbrplotter->AddLineToHeader( text );
// Add the TF.FilePolarity
text = wxT( "%TF.FilePolarity,Positive*%" );
gbrplotter->AddLineToHeader( text );
}
plotter->StartPlot();
// Draw items on edge layer (not all, only items useful for drill map
// Draw items on edge layer.
// Not all, only items useful for drill map, i.e. board outlines.
BRDITEMS_PLOTTER itemplotter( plotter, m_pcb, plot_opts );
itemplotter.SetLayerSet( Edge_Cuts );
for( auto PtStruct : m_pcb->Drawings() )
// Use attributes of a drawing layer (we are not really draw the Edge.Cuts layer)
itemplotter.SetLayerSet( Dwgs_User );
for( BOARD_ITEM* item : m_pcb->Drawings() )
{
switch( PtStruct->Type() )
if( item->GetLayer() != Edge_Cuts )
continue;
switch( item->Type() )
{
case PCB_SHAPE_T:
itemplotter.PlotPcbShape( (PCB_SHAPE*) PtStruct );
{
PCB_SHAPE dummy_shape( *static_cast<PCB_SHAPE*>( item ) );
dummy_shape.SetLayer( Dwgs_User );
itemplotter.PlotPcbShape( &dummy_shape );
}
break;
case PCB_TEXT_T:
itemplotter.PlotPcbText( (PCB_TEXT*) PtStruct );
break;
case PCB_DIM_ALIGNED_T:
case PCB_DIM_CENTER_T:
case PCB_DIM_ORTHOGONAL_T:
case PCB_DIM_LEADER_T:
case PCB_TARGET_T:
case PCB_MARKER_T: // do not draw
default:
break;
}
+6 -1
View File
@@ -732,6 +732,11 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& aEvent )
return;
}
wxWindow* blocking_dialog = pcbframe->Kiway().GetBlockingDialog();
if( blocking_dialog )
blocking_dialog->Close( true );
toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
BOARD_COMMIT commit( pcbframe );
@@ -768,7 +773,7 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& aEvent )
commit.Push( wxT( "Insert footprint" ) );
pcbframe->Raise();
toolMgr->RunAction( PCB_ACTIONS::placeFootprint, true, newFootprint );
toolMgr->RunAction( PCB_ACTIONS::placeFootprint, false, newFootprint );
newFootprint->ClearFlags();
}
+12 -3
View File
@@ -1726,8 +1726,17 @@ void PCB_PLUGIN::format( const PAD* aPad, int aNestLevel ) const
m_out->Print( 0, " (width %s)",
FormatInternalUnits( primitive->GetWidth() ).c_str() );
if( primitive->IsFilled() )
m_out->Print( 0, " (fill yes)" );
// The filled flag represents if a solid fill is present on circles,
// rectangles and polygons
if( ( primitive->GetShape() == SHAPE_T::POLY )
|| ( primitive->GetShape() == SHAPE_T::RECT )
|| ( primitive->GetShape() == SHAPE_T::CIRCLE ) )
{
if( primitive->IsFilled() )
m_out->Print( 0, " (fill yes)" );
else
m_out->Print( 0, " (fill none)" );
}
m_out->Print( 0, ")" );
}
@@ -2040,7 +2049,7 @@ void PCB_PLUGIN::format( const ZONE* aZone, int aNestLevel ) const
if( aZone->GetIsRuleArea() )
{
m_out->Print( aNestLevel + 1,
"(keepout (tracks %s) (vias %s) (pads %s ) (copperpour %s) "
"(keepout (tracks %s) (vias %s) (pads %s) (copperpour %s) "
"(footprints %s))\n",
aZone->GetDoNotAllowTracks() ? "not_allowed" : "allowed",
aZone->GetDoNotAllowVias() ? "not_allowed" : "allowed",
+1
View File
@@ -30,6 +30,7 @@
#include <wx/string.h>
#include <wx/xml/xml.h>
#include <wx/wxcrt.h> // for wxFopen
namespace PCAD2KICAD {
+2 -2
View File
@@ -143,10 +143,10 @@ HANDLE_EXCEPTIONS(BOARD::TracksInNetBetweenPoints)
return SaveBoard(filename,self)
def GetNetClasses(self):
return self.GetDesignSettings().m_NetClasses
return self.GetDesignSettings().GetNetClasses()
def GetCurrentNetClassName(self):
return self.GetDesignSettings().m_CurrentNetClassName
return self.GetDesignSettings().GetCurrentNetClassName()
def GetViasDimensionsList(self):
return self.GetDesignSettings().m_ViasDimensionsList
+2 -2
View File
@@ -119,9 +119,9 @@
plug = GetPluginForPath(libname)
return plug.FootprintEnumerate(libname)
def FootprintLoad(libname,name):
def FootprintLoad(libname,name,preserveUUID=False):
plug = GetPluginForPath(libname)
return plug.FootprintLoad(libname,name)
return plug.FootprintLoad(libname,name,preserveUUID)
def FootprintSave(libname,module):
plug = GetPluginForPath(libname)
+25 -17
View File
@@ -102,7 +102,15 @@ public:
*/
bool IsLineCorner( bool aAllowLockedSegs = false ) const
{
if( m_linkedItems.Size() != 2 || m_linkedItems.Count( SEGMENT_T | ARC_T ) != 2 )
if( m_linkedItems.Size() == 2 && m_linkedItems.Count( SEGMENT_T | ARC_T ) == 2 )
{
LINKED_ITEM* seg1 = static_cast<LINKED_ITEM*>( m_linkedItems[0] );
LINKED_ITEM* seg2 = static_cast<LINKED_ITEM*>( m_linkedItems[1] );
// joints between segments of different widths are not considered trivial.
return seg1->Width() == seg2->Width();
}
else if( m_linkedItems.Size() > 2 && m_linkedItems.Count( SEGMENT_T | ARC_T ) == 2 )
{
if( !aAllowLockedSegs )
{
@@ -113,8 +121,10 @@ public:
else if( ( m_linkedItems.Size() - m_linkedItems.Count( SEGMENT_T | ARC_T ) )
== m_linkedItems.Count( VIA_T ) )
{
const VIA* via = nullptr;
bool hasNonVirtualVia = false;
const LINKED_ITEM* seg1 = nullptr;
const LINKED_ITEM* seg2 = nullptr;
const VIA* via = nullptr;
bool hasNonVirtualVia = false;
for( const ITEM* item : m_linkedItems.CItems() )
{
@@ -123,28 +133,26 @@ public:
via = static_cast<const VIA*>( item );
hasNonVirtualVia = !via->IsVirtual();
if( hasNonVirtualVia )
break;
}
else if( item->Kind() == SEGMENT_T || item->Kind() == ARC_T )
{
if( !seg1 )
seg1 = static_cast<const LINKED_ITEM*>( item );
else
seg2 = static_cast<const LINKED_ITEM*>( item );
}
}
assert( via );
if( !via || hasNonVirtualVia )
return false;
}
else
{
return false;
assert ( seg1 && seg2 );
return seg1->Width() == seg2->Width();
}
}
auto seg1 = static_cast<LINKED_ITEM*>( m_linkedItems[0] );
auto seg2 = static_cast<LINKED_ITEM*>( m_linkedItems[1] );
// joints between segments of different widths are not considered trivial.
return seg1->Width() == seg2->Width();
return false;
}
bool IsNonFanoutVia() const
+4
View File
@@ -687,6 +687,10 @@ int BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB( const TOOL_EVENT& aEvent )
if( frame )
{
std::string payload;
if( wxWindow* blocking_win = frame->Kiway().GetBlockingDialog() )
blocking_win->Close( true );
m_frame->Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_UPDATE, payload, m_frame );
}
return 0;
+12 -4
View File
@@ -703,7 +703,9 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_frame->SetMsgPanel( board() );
if( selection().Empty() )
m_frame->SetMsgPanel( board() );
return 0;
}
@@ -1151,7 +1153,9 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_view->Remove( &preview );
m_frame->SetMsgPanel( board() );
if( selection().Empty() )
m_frame->SetMsgPanel( board() );
return 0;
}
@@ -1727,7 +1731,9 @@ bool DRAWING_TOOL::drawSegment( const std::string& aTool, PCB_SHAPE** aGraphic,
m_view->Remove( &twoPointAsst );
m_view->Remove( &preview );
m_frame->SetMsgPanel( board() );
if( selection().Empty() )
m_frame->SetMsgPanel( board() );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_controls->SetAutoPan( false );
@@ -1996,7 +2002,9 @@ bool DRAWING_TOOL::drawArc( const std::string& aTool, PCB_SHAPE** aGraphic, bool
preview.Remove( graphic );
m_view->Remove( &arcAsst );
m_view->Remove( &preview );
m_frame->SetMsgPanel( board() );
if( selection().Empty() )
m_frame->SetMsgPanel( board() );
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
m_controls->SetAutoPan( false );
+2
View File
@@ -1493,6 +1493,8 @@ void PCB_POINT_EDITOR::updateItem() const
}
getView()->Update( item );
frame()->SetMsgPanel( item );
}
+29 -5
View File
@@ -797,12 +797,12 @@ bool PCB_SELECTION_TOOL::selectMultiple()
* Left > Right : Select objects that are fully enclosed by selection
* Right > Left : Select objects that are crossed by selection
*/
bool windowSelection = width >= 0 ? true : false;
bool greedySelection = width >= 0 ? false : true;
if( view->IsMirroredX() )
windowSelection = !windowSelection;
greedySelection = !greedySelection;
m_frame->GetCanvas()->SetCurrentCursor( windowSelection ? KICURSOR::SELECT_WINDOW
m_frame->GetCanvas()->SetCurrentCursor( !greedySelection ? KICURSOR::SELECT_WINDOW
: KICURSOR::SELECT_LASSO );
if( evt->IsCancelInteractive() || evt->IsActivate() )
@@ -853,13 +853,37 @@ bool PCB_SELECTION_TOOL::selectMultiple()
selectionRect.Normalize();
GENERAL_COLLECTOR collector;
std::set<BOARD_ITEM*> group_items;
for( PCB_GROUP* group : board()->Groups() )
{
// The currently entered group does not get limited
if( m_enteredGroup == group )
continue;
std::unordered_set<BOARD_ITEM*>& newset = group->GetItems();
// If we are not greedy and have selected the whole group, add just one item
// to allow it to be promoted to the group later
if( !greedySelection && selectionRect.Contains( group->GetBoundingBox() )
&& newset.size() )
{
collector.Append( *newset.begin() );
}
for( BOARD_ITEM* group_item : newset )
group_items.emplace( group_item );
}
for( auto it = candidates.begin(), it_end = candidates.end(); it != it_end; ++it )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it->first );
if( item && Selectable( item ) && item->HitTest( selectionRect, windowSelection ) )
if( item && Selectable( item ) && item->HitTest( selectionRect, !greedySelection )
&& ( greedySelection || !group_items.count( item ) ) )
{
collector.Append( item );
}
}
// Apply the stateful filter
@@ -2546,7 +2570,7 @@ void PCB_SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector
for( int i = 0; i < aCollector.GetCount(); ++i )
{
BOARD_ITEM* item = aCollector[i];
double area;
double area = 0.0;
if( ( item->Type() == PCB_ZONE_T || item->Type() == PCB_FP_ZONE_T )
&& static_cast<ZONE*>( item )->HitTestForEdge( where, MAX_SLOP * pixel / 2 ) )
@@ -66,16 +66,16 @@ static const std::vector<ALTIUM_TO_KICAD_UNIT_FRAC_CASE> altium_to_kicad_unit_fr
// Decimal Places
{ "0", "1", 0 },
{ "0", "10", 0 },
{ "0", "100", 2 },
{ "0", "1000", 25 },
{ "0", "10000", 254 },
{ "1", "10000", 2794 },
{ "0", "100", 0 },
{ "0", "1000", 30 },
{ "0", "10000", 250 },
{ "1", "10000", 2790 },
{ "0", "-1", 0 },
{ "0", "-10", 0 },
{ "0", "-100", -2 },
{ "0", "-1000", -25 },
{ "0", "-10000", -254 },
{ "-1", "-10000", -2794 },
{ "0", "-100", 0 },
{ "0", "-1000", -30 },
{ "0", "-10000", -250 },
{ "-1", "-10000", -2790 },
// Edge Cases
// Clamp bigger values
// imperial rounded units as input
+18 -9
View File
@@ -7,13 +7,18 @@
cmake_minimum_required(VERSION 3.4)
# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
# The `cmake_minimum_required(VERSION 3.4...3.22)` syntax does not work with
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
# the behavior using the following workaround:
if(${CMAKE_VERSION} VERSION_LESS 3.18)
if(${CMAKE_VERSION} VERSION_LESS 3.22)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
else()
cmake_policy(VERSION 3.18)
cmake_policy(VERSION 3.22)
endif()
# Avoid infinite recursion if tests include this as a subdirectory
if(DEFINED PYBIND11_MASTER_PROJECT)
return()
endif()
# Extract project version from source
@@ -45,13 +50,8 @@ if(NOT pybind11_FIND_QUIETLY)
message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
endif()
# Avoid infinite recursion if tests include this as a subdirectory
if(DEFINED PYBIND11_MASTER_PROJECT)
set(PYBIND11_TEST OFF)
endif()
# Check if pybind11 is being used directly or via add_subdirectory
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR AND NOT DEFINED PYBIND11_MASTER_PROJECT)
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
### Warn if not an out-of-source builds
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
set(lines
@@ -80,6 +80,8 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR AND NOT DEFINED PYBIND11_MASTER_
endif()
set(pybind11_system "")
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
else()
set(PYBIND11_MASTER_PROJECT OFF)
set(pybind11_system SYSTEM)
@@ -89,6 +91,9 @@ endif()
option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT})
option(PYBIND11_NOPYTHON "Disable search for Python" OFF)
set(PYBIND11_INTERNALS_VERSION
""
CACHE STRING "Override the ABI version, may be used to enable the unstable ABI.")
cmake_dependent_option(
USE_PYTHON_INCLUDE_DIR
@@ -183,6 +188,10 @@ if(NOT TARGET pybind11_headers)
target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
cxx_right_angle_brackets)
if(NOT "${PYBIND11_INTERNALS_VERSION}" STREQUAL "")
target_compile_definitions(
pybind11_headers INTERFACE "PYBIND11_INTERNALS_VERSION=${PYBIND11_INTERNALS_VERSION}")
endif()
else()
# It is invalid to install a target twice, too.
set(PYBIND11_INSTALL OFF)
+7 -18
View File
@@ -3,7 +3,7 @@
**pybind11 — Seamless operability between C++11 and Python**
|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |CI| |Build status|
|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions| |CI| |Build status|
|Repology| |PyPI package| |Conda-forge| |Python Versions|
@@ -13,19 +13,6 @@
.. start
.. warning::
Combining older versions of pybind11 (< 2.6.0) with Python 3.9.0 will
trigger undefined behavior that typically manifests as crashes during
interpreter shutdown (but could also destroy your data. **You have been
warned.**)
We recommend that you update to the latest patch release of Python (3.9.1),
which includes a `fix <https://github.com/python/cpython/pull/22670>`_
that resolves this problem. If you do use Python 3.9.0, please update to
the latest version of pybind11 (2.6.0 or newer), which includes a temporary
workaround specifically when Python 3.9.0 is detected at runtime.
**pybind11** is a lightweight header-only library that exposes C++ types
in Python and vice versa, mainly to create Python bindings of existing
@@ -110,7 +97,7 @@ goodies:
transparently applied to all entries of one or more NumPy array
arguments.
- Python’s slice-based access and assignment operations can be
- Python's slice-based access and assignment operations can be
supported with just a few lines of code.
- Everything is contained in just a few header files; there is no need
@@ -119,7 +106,7 @@ goodies:
- Binaries are generally smaller by a factor of at least 2 compared to
equivalent bindings generated by Boost.Python. A recent pybind11
conversion of PyRosetta, an enormous Boost.Python binding project,
`reported <http://graylab.jhu.edu/RosettaCon2016/PyRosetta-4.pdf>`_
`reported <https://graylab.jhu.edu/Sergey/2016.RosettaCon/PyRosetta-4.pdf>`_
a binary size reduction of **5.4x** and compile time reduction by
**5.8x**.
@@ -147,9 +134,9 @@ About
This project was created by `Wenzel
Jakob <http://rgl.epfl.ch/people/wjakob>`_. Significant features and/or
improvements to the code were contributed by Jonas Adler, Lori A. Burns,
Sylvain Corlay, Eric Cousineau, Ralf Grosse-Kunstleve, Trent Houliston, Axel
Sylvain Corlay, Eric Cousineau, Aaron Gokaslan, Ralf Grosse-Kunstleve, Trent Houliston, Axel
Huebl, @hulucc, Yannick Jadoul, Sergey Lyskov Johan Mabille, Tomasz Miąsko,
Dean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim
Dean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim
Schellart, Henry Schreiner, Ivan Smirnov, Boris Staletic, and Patrick Stewart.
We thank Google for a generous financial contribution to the continuous
@@ -189,3 +176,5 @@ to the terms and conditions of this license.
:target: https://repology.org/project/python:pybind11/versions
.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pybind11.svg
:target: https://pypi.org/project/pybind11/
.. |GitHub Discussions| image:: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github
:target: https://github.com/pybind/pybind11/discussions
+1 -2
View File
@@ -18,6 +18,5 @@ ALIASES += "endrst=\endverbatim"
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = NO
PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS \
PY_MAJOR_VERSION=3 \
PREDEFINED = PY_MAJOR_VERSION=3 \
PYBIND11_NOINLINE
+3 -1
View File
@@ -26,7 +26,9 @@ The following Python snippet demonstrates the intended usage from the Python sid
def __int__(self):
return 123
from example import print
print(A())
To register the necessary conversion routines, it is necessary to add an
@@ -44,7 +46,7 @@ type is explicitly allowed.
* function signatures and declares a local variable
* 'value' of type inty
*/
PYBIND11_TYPE_CASTER(inty, _("inty"));
PYBIND11_TYPE_CASTER(inty, const_name("inty"));
/**
* Conversion part 1 (Python->C++): convert a PyObject into a inty
+3 -3
View File
@@ -52,7 +52,7 @@ can be mapped *and* if the numpy array is writeable (that is
the passed variable will be transparently carried out directly on the
``numpy.ndarray``.
This means you can can write code such as the following and have it work as
This means you can write code such as the following and have it work as
expected:
.. code-block:: cpp
@@ -112,7 +112,7 @@ example:
.. code-block:: python
a = MyClass()
m = a.get_matrix() # flags.writeable = True, flags.owndata = False
m = a.get_matrix() # flags.writeable = True, flags.owndata = False
v = a.view_matrix() # flags.writeable = False, flags.owndata = False
c = a.copy_matrix() # flags.writeable = True, flags.owndata = True
# m[5,6] and v[5,6] refer to the same element, c[5,6] does not.
@@ -203,7 +203,7 @@ adding the ``order='F'`` option when creating an array:
.. code-block:: python
myarray = np.array(source, order='F')
myarray = np.array(source, order="F")
Such an object will be passable to a bound function accepting an
``Eigen::Ref<MatrixXd>`` (or similar column-major Eigen type).
+90 -90
View File
@@ -75,96 +75,96 @@ The following basic data types are supported out of the box (some may require
an additional extension header to be included). To pass other data structures
as arguments and return values, refer to the section on binding :ref:`classes`.
+------------------------------------+---------------------------+-------------------------------+
| Data type | Description | Header file |
+====================================+===========================+===============================+
| ``int8_t``, ``uint8_t`` | 8-bit integers | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``int16_t``, ``uint16_t`` | 16-bit integers | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``int32_t``, ``uint32_t`` | 32-bit integers | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``int64_t``, ``uint64_t`` | 64-bit integers | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``ssize_t``, ``size_t`` | Platform-dependent size | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``float``, ``double`` | Floating point types | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``bool`` | Two-state Boolean type | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``char`` | Character literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``char16_t`` | UTF-16 character literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``char32_t`` | UTF-32 character literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``wchar_t`` | Wide character literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``const char *`` | UTF-8 string literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``const char16_t *`` | UTF-16 string literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``const char32_t *`` | UTF-32 string literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``const wchar_t *`` | Wide string literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::string`` | STL dynamic UTF-8 string | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::u16string`` | STL dynamic UTF-16 string | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::u32string`` | STL dynamic UTF-32 string | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::wstring`` | STL dynamic wide string | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::string_view``, | STL C++17 string views | :file:`pybind11/pybind11.h` |
| ``std::u16string_view``, etc. | | |
+------------------------------------+---------------------------+-------------------------------+
| ``std::pair<T1, T2>`` | Pair of two custom types | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::tuple<...>`` | Arbitrary tuple of types | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::reference_wrapper<...>`` | Reference type wrapper | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::complex<T>`` | Complex numbers | :file:`pybind11/complex.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::array<T, Size>`` | STL static array | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::vector<T>`` | STL dynamic array | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::deque<T>`` | STL double-ended queue | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::valarray<T>`` | STL value array | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::list<T>`` | STL linked list | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::map<T1, T2>`` | STL ordered map | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::unordered_map<T1, T2>`` | STL unordered map | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::set<T>`` | STL ordered set | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::unordered_set<T>`` | STL unordered set | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::optional<T>`` | STL optional type (C++17) | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::experimental::optional<T>`` | STL optional type (exp.) | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::variant<...>`` | Type-safe union (C++17) | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::filesystem::path<T>`` | STL path (C++17) [#]_ | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::function<...>`` | STL polymorphic function | :file:`pybind11/functional.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::chrono::duration<...>`` | STL time duration | :file:`pybind11/chrono.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``std::chrono::time_point<...>`` | STL date/time | :file:`pybind11/chrono.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``Eigen::Matrix<...>`` | Eigen: dense matrix | :file:`pybind11/eigen.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``Eigen::Map<...>`` | Eigen: mapped memory | :file:`pybind11/eigen.h` |
+------------------------------------+---------------------------+-------------------------------+
| ``Eigen::SparseMatrix<...>`` | Eigen: sparse matrix | :file:`pybind11/eigen.h` |
+------------------------------------+---------------------------+-------------------------------+
+------------------------------------+---------------------------+-----------------------------------+
| Data type | Description | Header file |
+====================================+===========================+===================================+
| ``int8_t``, ``uint8_t`` | 8-bit integers | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``int16_t``, ``uint16_t`` | 16-bit integers | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``int32_t``, ``uint32_t`` | 32-bit integers | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``int64_t``, ``uint64_t`` | 64-bit integers | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``ssize_t``, ``size_t`` | Platform-dependent size | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``float``, ``double`` | Floating point types | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``bool`` | Two-state Boolean type | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``char`` | Character literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``char16_t`` | UTF-16 character literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``char32_t`` | UTF-32 character literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``wchar_t`` | Wide character literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``const char *`` | UTF-8 string literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``const char16_t *`` | UTF-16 string literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``const char32_t *`` | UTF-32 string literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``const wchar_t *`` | Wide string literal | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::string`` | STL dynamic UTF-8 string | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::u16string`` | STL dynamic UTF-16 string | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::u32string`` | STL dynamic UTF-32 string | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::wstring`` | STL dynamic wide string | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::string_view``, | STL C++17 string views | :file:`pybind11/pybind11.h` |
| ``std::u16string_view``, etc. | | |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::pair<T1, T2>`` | Pair of two custom types | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::tuple<...>`` | Arbitrary tuple of types | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::reference_wrapper<...>`` | Reference type wrapper | :file:`pybind11/pybind11.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::complex<T>`` | Complex numbers | :file:`pybind11/complex.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::array<T, Size>`` | STL static array | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::vector<T>`` | STL dynamic array | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::deque<T>`` | STL double-ended queue | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::valarray<T>`` | STL value array | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::list<T>`` | STL linked list | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::map<T1, T2>`` | STL ordered map | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::unordered_map<T1, T2>`` | STL unordered map | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::set<T>`` | STL ordered set | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::unordered_set<T>`` | STL unordered set | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::optional<T>`` | STL optional type (C++17) | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::experimental::optional<T>`` | STL optional type (exp.) | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::variant<...>`` | Type-safe union (C++17) | :file:`pybind11/stl.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::filesystem::path<T>`` | STL path (C++17) [#]_ | :file:`pybind11/stl/filesystem.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::function<...>`` | STL polymorphic function | :file:`pybind11/functional.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::chrono::duration<...>`` | STL time duration | :file:`pybind11/chrono.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``std::chrono::time_point<...>`` | STL date/time | :file:`pybind11/chrono.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``Eigen::Matrix<...>`` | Eigen: dense matrix | :file:`pybind11/eigen.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``Eigen::Map<...>`` | Eigen: mapped memory | :file:`pybind11/eigen.h` |
+------------------------------------+---------------------------+-----------------------------------+
| ``Eigen::SparseMatrix<...>`` | Eigen: sparse matrix | :file:`pybind11/eigen.h` |
+------------------------------------+---------------------------+-----------------------------------+
.. [#] ``std::filesystem::path`` is converted to ``pathlib.Path`` and
``os.PathLike`` is converted to ``std::filesystem::path``, but this requires
+16 -16
View File
@@ -36,13 +36,13 @@ everywhere <http://utf8everywhere.org/>`_.
}
);
.. code-block:: python
.. code-block:: pycon
>>> utf8_test('🎂')
>>> utf8_test("🎂")
utf-8 is icing on the cake.
🎂
>>> utf8_charptr('🍕')
>>> utf8_charptr("🍕")
My favorite food is
🍕
@@ -80,7 +80,7 @@ raise a ``UnicodeDecodeError``.
}
);
.. code-block:: python
.. code-block:: pycon
>>> isinstance(example.std_string_return(), str)
True
@@ -114,7 +114,7 @@ conversion has the same overhead as implicit conversion.
}
);
.. code-block:: python
.. code-block:: pycon
>>> str_output()
'Send your résumé to Alice in HR'
@@ -143,7 +143,7 @@ returned to Python as ``bytes``, then one can return the data as a
}
);
.. code-block:: python
.. code-block:: pycon
>>> example.return_bytes()
b'\xba\xd0\xba\xd0'
@@ -160,7 +160,7 @@ encoding, but cannot convert ``std::string`` back to ``bytes`` implicitly.
}
);
.. code-block:: python
.. code-block:: pycon
>>> isinstance(example.asymmetry(b"have some bytes"), str)
True
@@ -229,16 +229,16 @@ character.
m.def("pass_char", [](char c) { return c; });
m.def("pass_wchar", [](wchar_t w) { return w; });
.. code-block:: python
.. code-block:: pycon
>>> example.pass_char('A')
>>> example.pass_char("A")
'A'
While C++ will cast integers to character types (``char c = 0x65;``), pybind11
does not convert Python integers to characters implicitly. The Python function
``chr()`` can be used to convert integers to characters.
.. code-block:: python
.. code-block:: pycon
>>> example.pass_char(0x65)
TypeError
@@ -259,17 +259,17 @@ a combining acute accent). The combining character will be lost if the
two-character sequence is passed as an argument, even though it renders as a
single grapheme.
.. code-block:: python
.. code-block:: pycon
>>> example.pass_wchar('é')
>>> example.pass_wchar("é")
'é'
>>> combining_e_acute = 'e' + '\u0301'
>>> combining_e_acute = "e" + "\u0301"
>>> combining_e_acute
'é'
>>> combining_e_acute == 'é'
>>> combining_e_acute == "é"
False
>>> example.pass_wchar(combining_e_acute)
@@ -278,9 +278,9 @@ single grapheme.
Normalizing combining characters before passing the character literal to C++
may resolve *some* of these issues:
.. code-block:: python
.. code-block:: pycon
>>> example.pass_wchar(unicodedata.normalize('NFC', combining_e_acute))
>>> example.pass_wchar(unicodedata.normalize("NFC", combining_e_acute))
'é'
In some languages (Thai for example), there are `graphemes that cannot be
+92 -4
View File
@@ -9,7 +9,7 @@ that you are already familiar with the basics from :doc:`/classes`.
Overriding virtual functions in Python
======================================
Suppose that a C++ class or interface has a virtual function that we'd like to
Suppose that a C++ class or interface has a virtual function that we'd like
to override from within Python (we'll focus on the class ``Animal``; ``Dog`` is
given as a specific example of how one would do this with traditional C++
code).
@@ -136,7 +136,7 @@ a virtual method call.
u'woof! woof! woof! '
>>> class Cat(Animal):
... def go(self, n_times):
... return "meow! " * n_times
... return "meow! " * n_times
...
>>> c = Cat()
>>> call_go(c)
@@ -159,8 +159,9 @@ Here is an example:
class Dachshund(Dog):
def __init__(self, name):
Dog.__init__(self) # Without this, a TypeError is raised.
Dog.__init__(self) # Without this, a TypeError is raised.
self.name = name
def bark(self):
return "yap!"
@@ -1153,12 +1154,65 @@ error:
>>> class PyFinalChild(IsFinal):
... pass
...
TypeError: type 'IsFinal' is not an acceptable base type
.. note:: This attribute is currently ignored on PyPy
.. versionadded:: 2.6
Binding classes with template parameters
========================================
pybind11 can also wrap classes that have template parameters. Consider these classes:
.. code-block:: cpp
struct Cat {};
struct Dog {};
template <typename PetType>
struct Cage {
Cage(PetType& pet);
PetType& get();
};
C++ templates may only be instantiated at compile time, so pybind11 can only
wrap instantiated templated classes. You cannot wrap a non-instantiated template:
.. code-block:: cpp
// BROKEN (this will not compile)
py::class_<Cage>(m, "Cage");
.def("get", &Cage::get);
You must explicitly specify each template/type combination that you want to
wrap separately.
.. code-block:: cpp
// ok
py::class_<Cage<Cat>>(m, "CatCage")
.def("get", &Cage<Cat>::get);
// ok
py::class_<Cage<Dog>>(m, "DogCage")
.def("get", &Cage<Dog>::get);
If your class methods have template parameters you can wrap those as well,
but once again each instantiation must be explicitly specified:
.. code-block:: cpp
typename <typename T>
struct MyClass {
template <typename V>
T fn(V v);
};
py::class<MyClass<int>>(m, "MyClassT")
.def("fn", &MyClass<int>::fn<std::string>);
Custom automatic downcasters
============================
@@ -1247,7 +1301,7 @@ Accessing the type object
You can get the type object from a C++ class that has already been registered using:
.. code-block:: python
.. code-block:: cpp
py::type T_py = py::type::of<T>();
@@ -1259,3 +1313,37 @@ object, just like ``type(ob)`` in Python.
Other types, like ``py::type::of<int>()``, do not work, see :ref:`type-conversions`.
.. versionadded:: 2.6
Custom type setup
=================
For advanced use cases, such as enabling garbage collection support, you may
wish to directly manipulate the ``PyHeapTypeObject`` corresponding to a
``py::class_`` definition.
You can do that using ``py::custom_type_setup``:
.. code-block:: cpp
struct OwnsPythonObjects {
py::object value = py::none();
};
py::class_<OwnsPythonObjects> cls(
m, "OwnsPythonObjects", py::custom_type_setup([](PyHeapTypeObject *heap_type) {
auto *type = &heap_type->ht_type;
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
type->tp_traverse = [](PyObject *self_base, visitproc visit, void *arg) {
auto &self = py::cast<OwnsPythonObjects&>(py::handle(self_base));
Py_VISIT(self.value.ptr());
return 0;
};
type->tp_clear = [](PyObject *self_base) {
auto &self = py::cast<OwnsPythonObjects&>(py::handle(self_base));
self.value = py::none();
return 0;
};
}));
cls.def(py::init<>());
cls.def_readwrite("value", &OwnsPythonObjects::value);
.. versionadded:: 2.8
+14 -13
View File
@@ -40,15 +40,15 @@ The essential structure of the ``main.cpp`` file looks like this:
}
The interpreter must be initialized before using any Python API, which includes
all the functions and classes in pybind11. The RAII guard class `scoped_interpreter`
all the functions and classes in pybind11. The RAII guard class ``scoped_interpreter``
takes care of the interpreter lifetime. After the guard is destroyed, the interpreter
shuts down and clears its memory. No Python functions can be called after this.
Executing Python code
=====================
There are a few different ways to run Python code. One option is to use `eval`,
`exec` or `eval_file`, as explained in :ref:`eval`. Here is a quick example in
There are a few different ways to run Python code. One option is to use ``eval``,
``exec`` or ``eval_file``, as explained in :ref:`eval`. Here is a quick example in
the context of an executable with an embedded interpreter:
.. code-block:: cpp
@@ -108,7 +108,7 @@ The two approaches can also be combined:
Importing modules
=================
Python modules can be imported using `module_::import()`:
Python modules can be imported using ``module_::import()``:
.. code-block:: cpp
@@ -122,6 +122,7 @@ embedding the interpreter. This makes it easy to import local Python files:
"""calc.py located in the working directory"""
def add(i, j):
return i + j
@@ -133,7 +134,7 @@ embedding the interpreter. This makes it easy to import local Python files:
int n = result.cast<int>();
assert(n == 3);
Modules can be reloaded using `module_::reload()` if the source is modified e.g.
Modules can be reloaded using ``module_::reload()`` if the source is modified e.g.
by an external process. This can be useful in scenarios where the application
imports a user defined data processing script which needs to be updated after
changes by the user. Note that this function does not reload modules recursively.
@@ -143,7 +144,7 @@ changes by the user. Note that this function does not reload modules recursively
Adding embedded modules
=======================
Embedded binary modules can be added using the `PYBIND11_EMBEDDED_MODULE` macro.
Embedded binary modules can be added using the ``PYBIND11_EMBEDDED_MODULE`` macro.
Note that the definition must be placed at global scope. They can be imported
like any other module.
@@ -169,7 +170,7 @@ like any other module.
Unlike extension modules where only a single binary module can be created, on
the embedded side an unlimited number of modules can be added using multiple
`PYBIND11_EMBEDDED_MODULE` definitions (as long as they have unique names).
``PYBIND11_EMBEDDED_MODULE`` definitions (as long as they have unique names).
These modules are added to Python's list of builtins, so they can also be
imported in pure Python files loaded by the interpreter. Everything interacts
@@ -215,9 +216,9 @@ naturally:
Interpreter lifetime
====================
The Python interpreter shuts down when `scoped_interpreter` is destroyed. After
The Python interpreter shuts down when ``scoped_interpreter`` is destroyed. After
this, creating a new instance will restart the interpreter. Alternatively, the
`initialize_interpreter` / `finalize_interpreter` pair of functions can be used
``initialize_interpreter`` / ``finalize_interpreter`` pair of functions can be used
to directly set the state at any time.
Modules created with pybind11 can be safely re-initialized after the interpreter
@@ -229,8 +230,8 @@ global data. All the details can be found in the CPython documentation.
.. warning::
Creating two concurrent `scoped_interpreter` guards is a fatal error. So is
calling `initialize_interpreter` for a second time after the interpreter
Creating two concurrent ``scoped_interpreter`` guards is a fatal error. So is
calling ``initialize_interpreter`` for a second time after the interpreter
has already been initialized.
Do not use the raw CPython API functions ``Py_Initialize`` and
@@ -241,7 +242,7 @@ global data. All the details can be found in the CPython documentation.
Sub-interpreter support
=======================
Creating multiple copies of `scoped_interpreter` is not possible because it
Creating multiple copies of ``scoped_interpreter`` is not possible because it
represents the main Python interpreter. Sub-interpreters are something different
and they do permit the existence of multiple interpreters. This is an advanced
feature of the CPython API and should be handled with care. pybind11 does not
@@ -257,5 +258,5 @@ We'll just mention a couple of caveats the sub-interpreters support in pybind11:
2. Managing multiple threads, multiple interpreters and the GIL can be
challenging and there are several caveats here, even within the pure
CPython API (please refer to the Python docs for details). As for
pybind11, keep in mind that `gil_scoped_release` and `gil_scoped_acquire`
pybind11, keep in mind that ``gil_scoped_release`` and ``gil_scoped_acquire``
do not take sub-interpreters into account.
+100 -12
View File
@@ -56,13 +56,15 @@ at its exception handler.
+--------------------------------------+--------------------------------------+
| :class:`pybind11::buffer_error` | ``BufferError`` |
+--------------------------------------+--------------------------------------+
| :class:`pybind11::import_error` | ``import_error`` |
| :class:`pybind11::import_error` | ``ImportError`` |
+--------------------------------------+--------------------------------------+
| :class:`pybind11::attribute_error` | ``AttributeError`` |
+--------------------------------------+--------------------------------------+
| Any other exception | ``RuntimeError`` |
+--------------------------------------+--------------------------------------+
Exception translation is not bidirectional. That is, *catching* the C++
exceptions defined above above will not trap exceptions that originate from
exceptions defined above will not trap exceptions that originate from
Python. For that, catch :class:`pybind11::error_already_set`. See :ref:`below
<handling_python_exceptions_cpp>` for further details.
@@ -75,9 +77,10 @@ Registering custom translators
If the default exception conversion policy described above is insufficient,
pybind11 also provides support for registering custom exception translators.
To register a simple exception conversion that translates a C++ exception into
a new Python exception using the C++ exception's ``what()`` method, a helper
function is available:
Similar to pybind11 classes, exception translators can be local to the module
they are defined in or global to the entire python session. To register a simple
exception conversion that translates a C++ exception into a new Python exception
using the C++ exception's ``what()`` method, a helper function is available:
.. code-block:: cpp
@@ -87,29 +90,39 @@ This call creates a Python exception class with the name ``PyExp`` in the given
module and automatically converts any encountered exceptions of type ``CppExp``
into Python exceptions of type ``PyExp``.
A matching function is available for registering a local exception translator:
.. code-block:: cpp
py::register_local_exception<CppExp>(module, "PyExp");
It is possible to specify base class for the exception using the third
parameter, a `handle`:
parameter, a ``handle``:
.. code-block:: cpp
py::register_exception<CppExp>(module, "PyExp", PyExc_RuntimeError);
py::register_local_exception<CppExp>(module, "PyExp", PyExc_RuntimeError);
Then `PyExp` can be caught both as `PyExp` and `RuntimeError`.
Then ``PyExp`` can be caught both as ``PyExp`` and ``RuntimeError``.
The class objects of the built-in Python exceptions are listed in the Python
documentation on `Standard Exceptions <https://docs.python.org/3/c-api/exceptions.html#standard-exceptions>`_.
The default base class is `PyExc_Exception`.
The default base class is ``PyExc_Exception``.
When more advanced exception translation is needed, the function
``py::register_exception_translator(translator)`` can be used to register
When more advanced exception translation is needed, the functions
``py::register_exception_translator(translator)`` and
``py::register_local_exception_translator(translator)`` can be used to register
functions that can translate arbitrary exception types (and which may include
additional logic to do so). The function takes a stateless callable (e.g. a
additional logic to do so). The functions takes a stateless callable (e.g. a
function pointer or a lambda function without captured variables) with the call
signature ``void(std::exception_ptr)``.
When a C++ exception is thrown, the registered exception translators are tried
in reverse order of registration (i.e. the last registered translator gets the
first shot at handling the exception).
first shot at handling the exception). All local translators will be tried
before a global translator is tried.
Inside the translator, ``std::rethrow_exception`` should be used within
a try block to re-throw the exception. One or more catch clauses to catch
@@ -168,6 +181,53 @@ section.
with ``-fvisibility=hidden``. Therefore exceptions that are used across ABI boundaries need to be explicitly exported, as exercised in ``tests/test_exceptions.h``.
See also: "Problems with C++ exceptions" under `GCC Wiki <https://gcc.gnu.org/wiki/Visibility>`_.
Local vs Global Exception Translators
=====================================
When a global exception translator is registered, it will be applied across all
modules in the reverse order of registration. This can create behavior where the
order of module import influences how exceptions are translated.
If module1 has the following translator:
.. code-block:: cpp
py::register_exception_translator([](std::exception_ptr p) {
try {
if (p) std::rethrow_exception(p);
} catch (const std::invalid_argument &e) {
PyErr_SetString("module1 handled this")
}
}
and module2 has the following similar translator:
.. code-block:: cpp
py::register_exception_translator([](std::exception_ptr p) {
try {
if (p) std::rethrow_exception(p);
} catch (const std::invalid_argument &e) {
PyErr_SetString("module2 handled this")
}
}
then which translator handles the invalid_argument will be determined by the
order that module1 and module2 are imported. Since exception translators are
applied in the reverse order of registration, which ever module was imported
last will "win" and that translator will be applied.
If there are multiple pybind11 modules that share exception types (either
standard built-in or custom) loaded into a single python instance and
consistent error handling behavior is needed, then local translators should be
used.
Changing the previous example to use ``register_local_exception_translator``
would mean that when invalid_argument is thrown in the module2 code, the
module2 translator will always handle it, while in module1, the module1
translator will do the same.
.. _handling_python_exceptions_cpp:
Handling exceptions from Python in C++
@@ -265,6 +325,34 @@ Alternately, to ignore the error, call `PyErr_Clear
Any Python error must be thrown or cleared, or Python/pybind11 will be left in
an invalid state.
Chaining exceptions ('raise from')
==================================
In Python 3.3 a mechanism for indicating that exceptions were caused by other
exceptions was introduced:
.. code-block:: py
try:
print(1 / 0)
except Exception as exc:
raise RuntimeError("could not divide by zero") from exc
To do a similar thing in pybind11, you can use the ``py::raise_from`` function. It
sets the current python error indicator, so to continue propagating the exception
you should ``throw py::error_already_set()`` (Python 3 only).
.. code-block:: cpp
try {
py::eval("print(1 / 0"));
} catch (py::error_already_set &e) {
py::raise_from(e, PyExc_RuntimeError, "could not divide by zero");
throw py::error_already_set();
}
.. versionadded:: 2.8
.. _unraisable_exceptions:
Handling unraisable exceptions
+55 -7
View File
@@ -120,7 +120,7 @@ targeted arguments can be passed through the :class:`cpp_function` constructor:
.. code-block:: cpp
class_<MyClass>(m, "MyClass")
.def_property("data"
.def_property("data",
py::cpp_function(&MyClass::getData, py::return_value_policy::copy),
py::cpp_function(&MyClass::setData)
);
@@ -232,7 +232,7 @@ is equivalent to the following pseudocode:
});
The only requirement is that ``T`` is default-constructible, but otherwise any
scope guard will work. This is very useful in combination with `gil_scoped_release`.
scope guard will work. This is very useful in combination with ``gil_scoped_release``.
See :ref:`gil`.
Multiple guards can also be specified as ``py::call_guard<T1, T2, T3...>``. The
@@ -272,7 +272,7 @@ And used in Python as usual:
.. code-block:: pycon
>>> print_dict({'foo': 123, 'bar': 'hello'})
>>> print_dict({"foo": 123, "bar": "hello"})
key=foo, value=123
key=bar, value=hello
@@ -306,8 +306,9 @@ The class ``py::args`` derives from ``py::tuple`` and ``py::kwargs`` derives
from ``py::dict``.
You may also use just one or the other, and may combine these with other
arguments as long as the ``py::args`` and ``py::kwargs`` arguments are the last
arguments accepted by the function.
arguments. Note, however, that ``py::kwargs`` must always be the last argument
of the function, and ``py::args`` implies that any further arguments are
keyword-only (see :ref:`keyword_only_arguments`).
Please refer to the other examples for details on how to iterate over these,
and on how to cast their entries into C++ objects. A demonstration is also
@@ -366,6 +367,8 @@ like so:
py::class_<MyClass>("MyClass")
.def("myFunction", py::arg("arg") = static_cast<SomeType *>(nullptr));
.. _keyword_only_arguments:
Keyword-only arguments
======================
@@ -377,10 +380,11 @@ argument in a function definition:
def f(a, *, b): # a can be positional or via keyword; b must be via keyword
pass
f(a=1, b=2) # good
f(b=2, a=1) # good
f(1, b=2) # good
f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given
f(1, b=2) # good
f(1, 2) # TypeError: f() takes 1 positional argument but 2 were given
Pybind11 provides a ``py::kw_only`` object that allows you to implement
the same behaviour by specifying the object between positional and keyword-only
@@ -396,6 +400,15 @@ feature does *not* require Python 3 to work.
.. versionadded:: 2.6
As of pybind11 2.9, a ``py::args`` argument implies that any following arguments
are keyword-only, as if ``py::kw_only()`` had been specified in the same
relative location of the argument list as the ``py::args`` argument. The
``py::kw_only()`` may be included to be explicit about this, but is not
required. (Prior to 2.9 ``py::args`` may only occur at the end of the argument
list, or immediately before a ``py::kwargs`` argument at the end).
.. versionadded:: 2.9
Positional-only arguments
=========================
@@ -565,3 +578,38 @@ prefers earlier-defined overloads to later-defined ones.
.. versionadded:: 2.6
The ``py::prepend()`` tag.
Binding functions with template parameters
==========================================
You can bind functions that have template parameters. Here's a function:
.. code-block:: cpp
template <typename T>
void set(T t);
C++ templates cannot be instantiated at runtime, so you cannot bind the
non-instantiated function:
.. code-block:: cpp
// BROKEN (this will not compile)
m.def("set", &set);
You must bind each instantiated function template separately. You may bind
each instantiation with the same name, which will be treated the same as
an overloaded function:
.. code-block:: cpp
m.def("set", &set<int>);
m.def("set", &set<std::string>);
Sometimes it's more clear to bind them with separate names, which is also
an option:
.. code-block:: cpp
m.def("setInt", &set<int>);
m.def("setString", &set<std::string>);
+1 -1
View File
@@ -84,7 +84,7 @@ could be realized as follows (important changes highlighted):
});
}
The ``call_go`` wrapper can also be simplified using the `call_guard` policy
The ``call_go`` wrapper can also be simplified using the ``call_guard`` policy
(see :ref:`call_policies`) which yields the same result:
.. code-block:: cpp
+35 -10
View File
@@ -171,6 +171,31 @@ template parameter, and it ensures that non-conforming arguments are converted
into an array satisfying the specified requirements instead of trying the next
function overload.
There are several methods on arrays; the methods listed below under references
work, as well as the following functions based on the NumPy API:
- ``.dtype()`` returns the type of the contained values.
- ``.strides()`` returns a pointer to the strides of the array (optionally pass
an integer axis to get a number).
- ``.flags()`` returns the flag settings. ``.writable()`` and ``.owndata()``
are directly available.
- ``.offset_at()`` returns the offset (optionally pass indices).
- ``.squeeze()`` returns a view with length-1 axes removed.
- ``.view(dtype)`` returns a view of the array with a different dtype.
- ``.reshape({i, j, ...})`` returns a view of the array with a different shape.
``.resize({...})`` is also available.
- ``.index_at(i, j, ...)`` gets the count from the beginning to a given index.
There are also several methods for getting references (described below).
Structured types
================
@@ -233,8 +258,8 @@ by the compiler. The result is returned as a NumPy array of type
.. code-block:: pycon
>>> x = np.array([[1, 3],[5, 7]])
>>> y = np.array([[2, 4],[6, 8]])
>>> x = np.array([[1, 3], [5, 7]])
>>> y = np.array([[2, 4], [6, 8]])
>>> z = 3
>>> result = vectorized_func(x, y, z)
@@ -345,21 +370,21 @@ The returned proxy object supports some of the same methods as ``py::array`` so
that it can be used as a drop-in replacement for some existing, index-checked
uses of ``py::array``:
- ``r.ndim()`` returns the number of dimensions
- ``.ndim()`` returns the number of dimensions
- ``r.data(1, 2, ...)`` and ``r.mutable_data(1, 2, ...)``` returns a pointer to
- ``.data(1, 2, ...)`` and ``r.mutable_data(1, 2, ...)``` returns a pointer to
the ``const T`` or ``T`` data, respectively, at the given indices. The
latter is only available to proxies obtained via ``a.mutable_unchecked()``.
- ``itemsize()`` returns the size of an item in bytes, i.e. ``sizeof(T)``.
- ``.itemsize()`` returns the size of an item in bytes, i.e. ``sizeof(T)``.
- ``ndim()`` returns the number of dimensions.
- ``.ndim()`` returns the number of dimensions.
- ``shape(n)`` returns the size of dimension ``n``
- ``.shape(n)`` returns the size of dimension ``n``
- ``size()`` returns the total number of elements (i.e. the product of the shapes).
- ``.size()`` returns the total number of elements (i.e. the product of the shapes).
- ``nbytes()`` returns the number of bytes used by the referenced elements
- ``.nbytes()`` returns the number of bytes used by the referenced elements
(i.e. ``itemsize()`` times ``size()``).
.. seealso::
@@ -378,7 +403,7 @@ In Python 2, the syntactic sugar ``...`` is not available, but the singleton
.. code-block:: python
a = # a NumPy array
a = ... # a NumPy array
b = a[0, ..., 0]
The function ``py::ellipsis()`` function can be used to perform the same
+36 -1
View File
@@ -20,6 +20,40 @@ Available types include :class:`handle`, :class:`object`, :class:`bool_`,
Be sure to review the :ref:`pytypes_gotchas` before using this heavily in
your C++ API.
.. _instantiating_compound_types:
Instantiating compound Python types from C++
============================================
Dictionaries can be initialized in the :class:`dict` constructor:
.. code-block:: cpp
using namespace pybind11::literals; // to bring in the `_a` literal
py::dict d("spam"_a=py::none(), "eggs"_a=42);
A tuple of python objects can be instantiated using :func:`py::make_tuple`:
.. code-block:: cpp
py::tuple tup = py::make_tuple(42, py::none(), "spam");
Each element is converted to a supported Python type.
A `simple namespace`_ can be instantiated using
.. code-block:: cpp
using namespace pybind11::literals; // to bring in the `_a` literal
py::object SimpleNamespace = py::module_::import("types").attr("SimpleNamespace");
py::object ns = SimpleNamespace("spam"_a=py::none(), "eggs"_a=42);
Attributes on a namespace can be modified with the :func:`py::delattr`,
:func:`py::getattr`, and :func:`py::setattr` functions. Simple namespaces can
be useful as lightweight stand-ins for class instances.
.. _simple namespace: https://docs.python.org/3/library/types.html#types.SimpleNamespace
.. _casting_back_and_forth:
Casting back and forth
@@ -30,7 +64,7 @@ types to Python, which can be done using :func:`py::cast`:
.. code-block:: cpp
MyClass *cls = ..;
MyClass *cls = ...;
py::object obj = py::cast(cls);
The reverse direction uses the following syntax:
@@ -132,6 +166,7 @@ Keyword arguments are also supported. In Python, there is the usual call syntax:
def f(number, say, to):
... # function code
f(1234, say="hello", to=some_instance) # keyword call in Python
In C++, the same call can be made using:
+6 -6
View File
@@ -28,7 +28,7 @@ Capturing standard output from ostream
Often, a library will use the streams ``std::cout`` and ``std::cerr`` to print,
but this does not play well with Python's standard ``sys.stdout`` and ``sys.stderr``
redirection. Replacing a library's printing with `py::print <print>` may not
redirection. Replacing a library's printing with ``py::print <print>`` may not
be feasible. This can be fixed using a guard around the library function that
redirects output to the corresponding Python streams:
@@ -62,11 +62,11 @@ This method respects flushes on the output streams and will flush if needed
when the scoped guard is destroyed. This allows the output to be redirected in
real time, such as to a Jupyter notebook. The two arguments, the C++ stream and
the Python output, are optional, and default to standard output if not given. An
extra type, `py::scoped_estream_redirect <scoped_estream_redirect>`, is identical
extra type, ``py::scoped_estream_redirect <scoped_estream_redirect>``, is identical
except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful with
`py::call_guard`, which allows multiple items, but uses the default constructor:
``py::call_guard``, which allows multiple items, but uses the default constructor:
.. code-block:: py
.. code-block:: cpp
// Alternative: Call single function using call guard
m.def("noisy_func", &call_noisy_function,
@@ -74,7 +74,7 @@ except for defaulting to ``std::cerr`` and ``sys.stderr``; this can be useful wi
py::scoped_estream_redirect>());
The redirection can also be done in Python with the addition of a context
manager, using the `py::add_ostream_redirect() <add_ostream_redirect>` function:
manager, using the ``py::add_ostream_redirect() <add_ostream_redirect>`` function:
.. code-block:: cpp
@@ -103,7 +103,7 @@ arguments to disable one of the streams if needed.
Evaluating Python expressions from strings and files
====================================================
pybind11 provides the `eval`, `exec` and `eval_file` functions to evaluate
pybind11 provides the ``eval``, ``exec`` and ``eval_file`` functions to evaluate
Python expressions and statements. The following example illustrates how they
can be used.
+1
View File
@@ -77,6 +77,7 @@ segmentation fault).
.. code-block:: python
from example import Parent
print(Parent().get_child())
The problem is that ``Parent::get_child()`` returns a pointer to an instance of

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