Compare commits

...

316 Commits

Author SHA1 Message Date
Wayne Stambaugh 59f308850e Tag release version 7.0.9. 2023-11-05 08:16:47 -05:00
jean-pierre charras e775a7581a pcb_calculator, MICROSTRIP::calcSynthesize(): fix incorrect init of a variable
It was initialized before other calculations, thus using a bad value.
From master branch
2023-11-01 17:31:16 +01:00
Wayne Stambaugh ec99e10b31 Tag stable version 7.0.9 release candidate 2. 2023-10-31 16:27:24 -04:00
Seth Hillbrand 240d7921ba Allow multiple strong drivers with same name
Multiple labels with the same name are allowed (and expected) so ensure
that we use a structure that allows duplicate names

(cherry picked from commit de0736863b)
2023-10-31 11:53:56 -07:00
Seth Hillbrand 9ac006b114 Don't use KiROUND when we should trunc
When calculating the viewport extents, we only need the maximum size
that can be represented.  Anything larger should be truncated.  We do
this in many other places (wx_view_controls, ruler_item,
ds_proxy_view_item, etc) and this brings pcb_selection_tool into
alignment with this, avoiding an unneeded warning message

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

(cherry picked from commit 6d957e9d65)
2023-10-30 09:43:45 -07:00
Seth Hillbrand c3fef1cae2 Update translations 2023-10-30 09:43:40 -07:00
Wellington Terumi Uemura ca1c99a0d1 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (8023 of 8023 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pt_BR/
2023-10-30 17:42:13 +01:00
Mert Gülsoy 06ae7a20df Translated using Weblate (Turkish)
Currently translated at 61.4% (4929 of 8023 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/tr/
2023-10-30 17:42:13 +01:00
Wellington Terumi Uemura f536ecdc00 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (8023 of 8023 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pt_BR/
2023-10-30 17:42:13 +01:00
ZbeeGin a4bdd38367 Translated using Weblate (Polish)
Currently translated at 100.0% (8023 of 8023 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pl/
2023-10-30 17:42:13 +01:00
Arend-Jan van Hilten 6fb6d3e444 Translated using Weblate (Dutch)
Currently translated at 83.9% (6736 of 8023 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/nl/
2023-10-30 17:42:13 +01:00
Toni Laiho a3952c37bf Translated using Weblate (Finnish)
Currently translated at 99.7% (8006 of 8023 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-10-30 17:42:13 +01:00
dsa-t c24ee72fe3 Translated using Weblate (Russian)
Currently translated at 99.9% (8022 of 8023 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ru/
2023-10-30 17:42:13 +01:00
Wayne Stambaugh f988b807c4 Don't show integer overflow errors in release builds.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15529

(cherry picked from commit bfd3e71a88)
2023-10-30 10:09:35 -04:00
Alex Shvartzkop cb1a596b10 kicad manager: make extension change warning for Rename case-insensitive. 2023-10-29 22:01:50 +03:00
jean-pierre charras c41cd75b62 kicad manager: fix broken Rename file command.
From master branch.
2023-10-29 18:38:32 +01:00
Ian McInerney 0df48f3002 PCM: Fix use of variable after it was moved into the cache
(cherry picked from commit c52fb23d4f)
2023-10-29 13:40:08 +00:00
Jeff Young 2d58184080 We don't want to do collision testing against virtual vias.
(Which means they had better not have a hole.)

(cherry picked from commit f1efae1e05)
2023-10-25 18:51:14 +01:00
Jeff Young 1ef6e69d83 Don't run DRC checks against reference images.
fixes https://gitlab.com/kicad/code/kicad/-/issues/15932
2023-10-25 18:51:14 +01:00
jean-pierre charras dbd4af16c6 Gerber place files: do not quote strings (fields, pad name, pad function ...)
Double quotes have no special meaning, so adding them modify the texts
Fixes #15944
https://gitlab.com/kicad/code/kicad/-/issues/15944
2023-10-25 09:13:59 +02:00
Alex Shvartzkop 2263535d3a Add Python API compatibility for GetEffectiveTextShape. 2023-10-25 00:03:28 +03:00
Seth Hillbrand 3ce4a5bf7f Fix missing random sim command 2023-10-24 13:57:44 -07:00
Alex Shvartzkop f62c3431ff Semi-fix schematic text properties dialog on wx 3.2.3.
Based on https://gitlab.com/kicad/code/kicad/-/commit/d9b5257b9e90c53d1cba39499c76ea917344128f
2023-10-24 23:30:31 +03:00
Seth Hillbrand a652084922 Update translations 2023-10-24 12:11:15 -07:00
김랑기 ed30599db8 Translated using Weblate (Korean)
Currently translated at 99.6% (7993 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ko/
2023-10-24 21:09:50 +02:00
ZbeeGin d8752970e9 Translated using Weblate (Polish)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pl/
2023-10-24 21:09:50 +02:00
rtyuionoop 57a4c93cf5 Translated using Weblate (Vietnamese)
Currently translated at 14.8% (1189 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/vi/
2023-10-24 21:09:50 +02:00
Tokita, Hiroshi a116f5783d Translated using Weblate (Japanese)
Currently translated at 99.9% (8021 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ja/
2023-10-24 21:09:50 +02:00
Jan Straka 2730098c42 Translated using Weblate (Czech)
Currently translated at 91.7% (7364 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/cs/
2023-10-24 21:09:49 +02:00
Luc 836d17359f Translated using Weblate (German)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/de/
2023-10-24 21:09:49 +02:00
Marine Biologist a4406bb137 Translated using Weblate (Turkish)
Currently translated at 61.4% (4928 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/tr/
2023-10-24 21:09:49 +02:00
Wellington Terumi Uemura bbb67b415a Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pt_BR/
2023-10-24 21:09:49 +02:00
dsa-t 0842360dbb Translated using Weblate (Russian)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ru/
2023-10-24 21:09:49 +02:00
Tokita, Hiroshi e58b23a54b Translated using Weblate (Japanese)
Currently translated at 99.9% (8021 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ja/
2023-10-24 21:09:49 +02:00
ZbeeGin 72342bd8a5 Translated using Weblate (Polish)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pl/
2023-10-24 21:09:49 +02:00
Wellington Terumi Uemura fa77fc3310 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pt_BR/
2023-10-24 21:09:49 +02:00
Alex Shvartzkop 53fe2a7203 Set UNPACK_ALIGNMENT properly for RGB bitmaps.
(cherry picked from commit 00904e8e23)
2023-10-24 06:59:53 +03:00
Alex Shvartzkop 480dfafb4f Fix variable shadowing.
(cherry picked from commit 0e4553b1fa)
2023-10-24 04:26:02 +03:00
Alex Shvartzkop f5e13c5ceb Fix up ccc29e9776 for masked images.
(cherry picked from commit 977912dcd5)
2023-10-24 04:00:30 +03:00
Alex Shvartzkop eadc902f84 Don't draw PCB bitmaps on layers not visible in high-contrast mode.
(cherry picked from commit e6cf5e5e01)
2023-10-24 03:42:54 +03:00
Alex Shvartzkop b461a3b64d OpenGL: Improve logic when bitmap cache memory is exhausted.
Don't remove the front entry, as it will likely be needed for the next bitmap.
Instead, implement neuristics based on access times.

(cherry picked from commit 71d0c7f6af)
2023-10-24 03:42:45 +03:00
Alex Shvartzkop 75c758e5f4 Improve bitmap caching performance.
(cherry picked from commit ccc29e9776)
2023-10-24 03:42:24 +03:00
Jeff Young 05912b0381 Check vias before holes as we assume any hole is non-pushable.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15840

(cherry picked from commit fb84f4592b)
2023-10-23 23:53:55 +01:00
Seth Hillbrand fb387a2c09 Don't leave deleted items in group
We filter out ref/value text in copies so we need to remove them from
the copied group (if any) as well

Fixes https://gitlab.com/kicad/code/kicad/-/issues/15930
2023-10-23 13:34:15 -07:00
Seth Hillbrand 1380feef72 Compare bus local names
When running ERC, we want to check if bus members exist in the bus and
this should be done using m_local_name (i.e. the name it take from the
parent bus) not the resolved name as this will change depending on
connections
2023-10-23 12:54:31 -07:00
Seth Hillbrand 6c91a3022e Fix stdlib assertion
The assertion checks if an element has been added to vector.  Since we
are merely manipulating the allocated data, the number of elements does
not change and the assertion check fails.  Using the pointer to the
allocated data is a cleaner/clearer way of accomplishing this
2023-10-23 12:54:31 -07:00
Alex Shvartzkop e55989120e NanoSVG: parse 'class' attribute before 'style'.
(cherry picked from commit 64a64f5216)
2023-10-23 21:30:16 +03:00
Alex Shvartzkop 14f12ccf51 Add ngspice lib paths for when running from build dir.
(cherry picked from commit 71fb1afe4c)
2023-10-23 21:29:11 +03:00
jean-pierre charras 82a1b02b4a Plotters (especially DXF) add more precision when plotting arcs (and others)
- in DXF coordinates were using 6 digits for coordinate mantissa:
this is not enough for coord in inches. Now use 16 digits
- Arc( VECTOR2I& aCentre, EDA_ANGLE& aStartAngle, EDA_ANGLE& aEndAngle, ...)
was using integers for coord.
This creates significant errors for start point and end points of the arc.
Now the center is given in double, and its position is calculated from angle end points
(and radius) to do not generate a position error for these end points
(previously the error could be 20 ... 50 nm)
From master branch
Fixes #15056 https://gitlab.com/kicad/code/kicad/-/issues/15056
2023-10-23 17:59:31 +02:00
Jeff Young e99a2fbc56 Score initializing is done by LIB_TREE_NODE::ResetScore().
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15875

(cherry picked from commit bc0fe74f72)
2023-10-23 13:28:14 +01:00
Alex Shvartzkop d3d23d18fb Fix footprints being difficult to select in high-contrast modes.
(regression)

(cherry picked from commit 97901c9ac5)
2023-10-23 06:10:23 +03:00
Alex Shvartzkop cbf1b2af47 HPGL plotting: fix random lines connecting to circles.
(cherry picked from commit 45791ff8d6)
2023-10-22 13:56:21 +03:00
Alex Shvartzkop 4f5fca4e67 HPGL plotting: write rects as polygons to prevent always filling.
(cherry picked from commit d9c123b1ec)
2023-10-22 13:55:54 +03:00
Alex Shvartzkop e0158a8ed7 DXF plotting: write zero-sized rects and circles as points.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15862

(cherry picked from commit 3e82e59c24)
2023-10-22 13:55:54 +03:00
Alex Shvartzkop 40e7ba67d1 PDF plotting: fix zero-sized or too thick rectangles.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15862

(cherry picked from commit 843bd4f79c)
2023-10-22 13:22:42 +03:00
Wayne Stambaugh e664605c90 Fix false positive DRC footprint parity test.
This fix removed the Euclidean normalization test and replaced it with an
arc center X and Y coordinate differential check.  The error epsilon was
increased to 200nm due to the arc center position calculation code using
the near 100nm position.

https://gitlab.com/kicad/code/kicad/-/issues/15917
2023-10-21 12:37:17 -04:00
Jeff Young 5a51a6b179 Make offset-zone check multi-layer aware.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15916

(cherry picked from commit b97d8ddef4)
2023-10-21 15:09:37 +01:00
Jeff Young eb7929ccb6 Fix layer handling for create similar zone.
(cherry picked from commit f18ce8c6de)
2023-10-20 22:22:27 +01:00
Jeff Young e85eec2e6b Don't leave deleted items in a group.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15797

(cherry picked from commit 14d5a404b2)
2023-10-19 17:52:00 +01:00
Alex Shvartzkop 121394c0c0 vcpkg: Lock glm at 0.9.9.8#2
Version 2023-06-08 changed the default order of quaternion
values from xyzw to wxyz, which we don't support.

Fixes animations in the 3D viewer.

(cherry picked from commit a52ee04fc7)
2023-10-16 14:55:57 +03:00
jean-pierre charras 5ad74d58f8 pcb_calculator/transline/stripline: add missing conv from log to db.
From master branch
Fixes #15873
https://gitlab.com/kicad/code/kicad/-/issues/15873
2023-10-16 10:35:22 +02:00
Ian McInerney afe2516d57 Fix casing for gerber wildcards
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15877

(Cherry-picked from 55caa9c1e8)
2023-10-15 19:54:05 +01:00
Jeff Young ccf6e78cd5 It is legal to have nullptr zones in the m_CopperZoneRTreeCache.
(Though we might want to re-think this strategy....)

Fixes https://gitlab.com/kicad/code/kicad/-/issues/15853
2023-10-14 22:35:06 +01:00
Jeff Young fef91fc8b9 Fix merge breakage. 2023-10-14 15:33:00 +01:00
Jeff Young 4156587abe Don't assume an error location for PAD::GetEffectivePolygon().
While ERROR_INSIDE was good for plotting, 3D generation, etc., it's
not good for generating router hulls.

Also reverts part of the change to always use polygons for PNS::SOLIDs.  A single shape in a SHAPE_COMPOUND will be faster (and
more accurate).

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

(cherry picked from commit 62d959ed0e)
2023-10-14 15:33:00 +01:00
Jon Evans 629eccaf09 PNS: Allow for approximation error in hull clearance
Also revert to using exact hulls for non-compound shapes

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

(cherry picked from commit 96f9f2c658)
2023-10-14 15:33:00 +01:00
Jeff Young f89803eb64 Don't turn an empty string into a '0'.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15871

(cherry picked from commit 0b06a1376b)
2023-10-14 15:33:00 +01:00
Jeff Young da12746a3a Clear selection before deleting board layers.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15866

(cherry picked from commit 8d3047d6eb)
2023-10-14 15:33:00 +01:00
Jeff Young b023019b0d Include solder mask in STEP export stackup height.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15632

(cherry picked from commit b4986030da)
2023-10-14 15:33:00 +01:00
Jeff Young 1fdaa1083e Honour custom layer names for Layer_Top and Layer_Bottom.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15835

(cherry picked from commit da5f5536c8)
2023-10-14 15:33:00 +01:00
Jeff Young 2f8e846b9e Adjust colours in appropriate direction depending on background.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15841

(cherry picked from commit 3f0067cbaa)
2023-10-14 15:33:00 +01:00
Alex Shvartzkop e42db52d14 Fix a crash when using length tuning tools.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15874

(cherry picked from commit 61bdee027b)
2023-10-14 16:54:16 +03:00
Alex Shvartzkop d4ec455ce0 Fix loading thru-hole pads when drill token is missing.
(cherry picked from commit f7ed9cc5c7)
2023-10-14 15:52:57 +03:00
Alex Shvartzkop 0547c7ba91 Fix loading legacy (until 2009) schematic files.
(cherry picked from commit b87496b834)
2023-10-14 15:45:20 +03:00
Alex Shvartzkop 8f4b809599 Fix the insufficient privileges message in symbol remap dialog.
(cherry picked from commit 7b94ecdc01)
2023-10-14 15:44:52 +03:00
jean-pierre charras 8432fb4fea Pcbnew: when adding layers, do not change via layers.
Via layers are not defined by a LSET, and the code that used the new LSET
broke the Via start and/or end layers (for blind/buried vias)
From master branch
Fixes #15856
https://gitlab.com/kicad/code/kicad/-/issues/15856
2023-10-14 08:56:19 +02:00
Marek Roszko 84df2c86ae Fix ambiguous cast 2023-10-13 19:26:16 -04:00
Mark Roszko 49ced23ba8 Reduce the boost dependencies in vcpkg 2023-10-13 17:03:57 +00:00
jean-pierre charras 00bf2ca36f Pcbnew: rename ZONE* m_SolderMask to m_SolderMaskBridges
(It is a container to build bridges on solder mask layers by DRC, not real zone)
Disable also this special zone selection by adding it in
PCB_SELECTION_TOOL::itemPassesFilter
Do not display the outlines of this very special zone used by DRC
to show layer mask bridges created by DRC to show these bridges.
From Master branch
Fixes #15847
https://gitlab.com/kicad/code/kicad/-/issues/15847
2023-10-13 17:15:37 +02:00
Marek Roszko b92861c7e3 Bump the wxpython in vcpkg to fix build 2023-10-13 07:51:27 -04:00
Mark Roszko a189102628 Move vcpkg forwards for curl and wx 2023-10-12 23:22:28 +00:00
jean-pierre charras 58a6eb653b protect protect RC_ITEM::SetItems() against null pointer.
Fixes #15865
https://gitlab.com/kicad/code/kicad/-/issues/15865
2023-10-12 14:56:56 +02:00
Alex Shvartzkop 9159f5a004 Restore fill polygons on proper layers when flipping zones.
(cherry picked from commit 0ea85ec9f5)
2023-10-12 02:45:05 +03:00
jean-pierre charras f1c570d793 OPENGL_GAL: ensure 0 sized rect with thickness is shown (already shown by Cairo)
From master branch
Fixes #15850
https://gitlab.com/kicad/code/kicad/-/issues/15850
2023-10-11 20:08:15 +02:00
Marek Roszko 832af39f34 Unbind ACTION_MENU events in destructor
(cherry picked from commit d801037c93)
2023-10-11 00:17:03 +00:00
Seth Hillbrand 9260f58803 Fix memory leak in connection graph
When generating virtual connections to represent bus aliases, we need to
store the pointers for future deletion otherwise we will leak the memory
2023-10-06 09:14:07 -07:00
Seth Hillbrand 1a5c515e45 Improve pin-pin iteration in ERC checks
Rather than generating expensive classes to store in a set to check for
duplicate checks, we avoid double-checking elements in the vector.  For
large schematics this results in a substantial speed increase
2023-10-06 09:14:07 -07:00
jean-pierre charras 87c8688f70 genDrillMapFile: reduce the pen width used to plot oval shapes (better look)
From master branch
2023-10-06 09:33:57 +02:00
Alex Shvartzkop d13179f9e4 EAGLE PCB: fix a regression causing polygons not being imported.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15829

(cherry picked from commit bf29b25190)
2023-10-06 01:16:43 +03:00
Seth Hillbrand 75de21314c Protect against subgraph loops
Optimize the subgraph processing to avoid repeated loops when multiple
items belong to the same subgraph.
2023-10-05 08:39:56 -07:00
Jeff Young 239f8e0905 Pull fixes back from master.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15813
2023-10-04 19:25:28 +01:00
Jeff Young f4ac624bb3 Make sure sorts are deterministic. 2023-10-04 18:52:39 +01:00
Jeff Young 2be0b98135 Make sure sort is deterministic.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15336

(cherry picked from commit 0d51729537)
2023-10-04 18:51:59 +01:00
Jeff Young 36c5719535 Fix logic screw-up in earlier commit.
(cherry picked from commit f2c0f4c87f)
2023-10-04 18:51:37 +01:00
Jeff Young 1f870bf76c Handle justification when hit-testing fields.
This steals the algo used in SCH_PAINTER to get the right coords
for the text.

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

(cherry picked from commit 6fbbf981f0)
2023-10-04 18:51:33 +01:00
Jeff Young d5cc334e20 Clear render caches before plotting.
Also fixes a bug where text variables in LIB_TEXT weren't getting
expanded when plotting.

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

(cherry picked from commit 003acbd686)
2023-10-04 18:49:56 +01:00
Jeff Young fd98188ee4 Use netclass values when reaching netclass entry.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15774

(cherry picked from commit 904bdc3c66)
2023-10-04 18:49:03 +01:00
Jeff Young c3446f9c2d Handle flipped state when checkging item against viewport.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15768

(cherry picked from commit 3c1478367f)
2023-10-04 18:48:42 +01:00
Marek Roszko e6e29b6c4c Unbind events in DIALOG_PCM destructor
Maybe fixes KICAD-KR


(cherry picked from commit b00871ad77)
2023-10-02 00:20:46 +00:00
Marek Roszko 6096b5c4d8 Unbind event handlers in the DIALOG_SHIM destructor to prevent late event crashes
Fixes KICAD-1XF


(cherry picked from commit 3a567a3ae1)
2023-10-01 21:55:36 +00:00
jean-pierre charras 838eadd47f Eeschema: fix a crash when loading a schematic if a symbol in a sheet has
a lib_name containing {slash} instead of /
(related to commits #2f51d22b and b2bf28f5)
From master branch.
Fixes #15791
https://gitlab.com/kicad/code/kicad/-/issues/15791
2023-10-01 10:08:33 +02:00
jean-pierre charras afb43531e8 Eeschema: fix a crash when loading a schematic if a symbol in a sheet has
a lib_id containing {slash} instead of /
(related to commit #2f51d22b)
Fixes #15791
https://gitlab.com/kicad/code/kicad/-/issues/15791
2023-09-30 18:25:18 +02:00
Jon Evans 3533e8b119 DbLib: support columns with numeric data
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15662

(cherry picked from commit 6f9af10912)
2023-09-30 10:27:34 -04:00
Jeff Young 0e6ad13db8 Fix missing part of cherry-pick. 2023-09-30 14:12:54 +01:00
Jeff Young 0d725fcc2c Fix errors in calculating tuning length.
Fix mismatched parameter passing in TOPOLOGY::followTrivialPath()
and TOPOLOGY::AssembleTrivialPath().
Fix logic error in PNS::JOINT::IsLineCorner().
Handle VVIAs in PNS::JOINT::IsNonFanoutVia().

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

(cherry picked from commit be532e96d6)
2023-09-30 13:37:00 +01:00
Jeff Young 7e747085d3 Handle read-only libraries when saving symbol from canvas.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15519

(cherry picked from commit 1fd3f4e375)
2023-09-30 13:36:13 +01:00
Jeff Young f1376396c2 Use original event position if it's available.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15623

(cherry picked from commit e962615407)
2023-09-30 13:35:48 +01:00
Jeff Young 4eb9281f4d Tidy up shutdown of APPEARANCE_CONTROLS.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15024

(cherry picked from commit c2c71facb1)
2023-09-30 13:35:22 +01:00
Jeff Young c895816cb0 Fix arg parsing in ExecuteFile.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15326

(cherry picked from commit 0f94b467ba)
2023-09-30 13:34:26 +01:00
Jeff Young 9f814c0f6a Repair standalone application 3D plugin path resolution.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15322

(cherry picked from commit 04214983cf)
2023-09-30 13:34:09 +01:00
Jeff Young e14aef9bd5 Correct path of pcb drawing sheet file on saveAs.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15551

(cherry picked from commit 722a90213c)
2023-09-30 13:31:16 +01:00
Jeff Young 2b106a2b34 Handle flipped horiz/vert justifications in FIELDS_GRID_TABLE.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15677

(cherry picked from commit 6f62565093)
2023-09-30 13:27:28 +01:00
Jeff Young f6494d2980 Implement printing and plotting for directive-specific label shapes.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15650

(cherry picked from commit 394ab8ccb1)
2023-09-30 13:26:59 +01:00
Jeff Young 78a6c1a909 Smarten the UpdateAllItemsConditionally() tests in SetActiveLayer().
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15329

(cherry picked from commit 5842e9c57e)
2023-09-30 13:26:18 +01:00
Jeff Young c858643100 Collect comment lines into following spice unit.
This can't distinguish a header block comment in front of a file
with multiple spice units, and so will include that into the first
unit only.

Also fixes the pin assignments reference textbox to use a
fixed-width font as many .subckt's contain ASCII graphics for
pin definitions (not that it helps any with the test case from
the given bug).

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

(cherry picked from commit ede542f911)
2023-09-30 13:25:44 +01:00
Jeff Young 17b0bdc9fe Check value-follows-name case in symbol Save As.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15647

(cherry picked from commit 849a4656c8)
2023-09-30 13:24:32 +01:00
Jeff Young 2e0cdebb0c Do full high-contrast update of vias & pads if netnames are shown.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15657

(cherry picked from commit c7f69503c0)
2023-09-30 13:22:17 +01:00
Jeff Young a5f8955d78 Don't import Altium objects to disabled layers.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15586

(cherry picked from commit 962f79334f)
2023-09-30 13:21:16 +01:00
Jeff Young 0eca698a39 Update symbol editor's title bar when renaming the canvas symbol.
(cherry picked from commit 7d1dbb77c3)
2023-09-30 13:19:40 +01:00
Jeff Young 16f259da81 Only update value on rename if it previously matched the symbol name.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15621

(cherry picked from commit ee724f6a2b)
2023-09-30 13:18:53 +01:00
Jeff Young c3ee477a1b Apply DC voltage source exception to current sources.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15626

(cherry picked from commit 4a59f0de43)
2023-09-30 13:18:17 +01:00
Jeff Young 33da35db04 Fix typo in arguments list to EvalRules().
Also fixes a bug where we weren't clearing the previous tabs from
the notebook.

(cherry picked from commit 31e30a5f56)
2023-09-30 13:16:39 +01:00
John Beard 533be1ec70 Port EDA_SHAPE arc tests to FP_SHAPE
These tests apply only to v7, since FP_SHAPE is removed
in master. But this checks that arcs in footprints get the
same winding treatment as EDA_SHAPE arcs (using the 0-suffix
functions).
2023-09-30 12:11:50 +00:00
John Beard b64573f5d4 Add regression test for arc winding
While the bug has been fixes, the winding handling in the
SetArcGeometry() function isn't tested. This adds a regression
test on EDA_SHAPE, which is where the logic now lives.

Relates-To: https://gitlab.com/kicad/code/kicad/-/issues/15694
Cherry-Pick: fb12db5f2c
2023-09-30 12:11:50 +00:00
John Beard 1d6caa9a35 Fix winding of FP_SHAPE arcs
Implement "0" versions of some arc calculations and fix some
initialisation bugs in the handling of FP_SHAPE arcs. Also
set m_endsSwapped.

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/15694
2023-09-30 12:11:50 +00:00
Mark Roszko c74b0943f3 StartPlot can fail and leave a broken file handle
Related #15782
2023-09-29 23:54:49 +00:00
Marek Roszko bb579294a0 Don't search when board is null (during board changes)
(cherry picked from commit 98685b37ff)
2023-09-29 23:53:02 +00:00
Josue Huaroto ad9f5f4dd7 Extend boundary size of PCB_VIEW
(cherry picked from commit 156288bfcf)
2023-09-29 12:12:03 -07:00
Josue Huaroto bf2e34f32e Change variable substitution for paths in Windows.
(cherry picked from commit 74695b0995)
2023-09-29 12:10:07 -07:00
Seth Hillbrand bd57957df7 Revise method of selecting footprints in contrast
When working in high contrast mode, we want to be able to select a
footprint with only elements in, e.g. silk and fab layers.

The previous design for footprint IsOnLayer had one behavior of every
other element and a different behavior for footprints.  This leads to
multiple bugs as new features use the overloaded IsOnLayer expecting it
to report if the element exists on a layer or not.

For footprints, we need a different routine to determine whether or not
to select the footprint when clicking on it.  IsOnLayer will report if
the footprint has any elements on a specific layer but we don't want to
use the bbox for a hittest because large footprints with through hole
pads will exist on every layer and have an enormous bbox.  Instead, we
filter footprints based on the hittest of each element.  This behaves in
a more logical fashion, allowing you to select a footprint by clicking
on a visible element of that footprint.

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

(cherry picked from commit f3d65b5156)
2023-09-29 12:09:11 -07:00
Seth Hillbrand 093db600ff Fix cherry-pick issue with file locking 2023-09-29 11:15:59 -07:00
Seth Hillbrand 131013f291 Fix Portuguese(Brasil) translation naming
On case-sensitive systems, the country code needs to be capitalized for
the language to be correctly identified between two dialects.  Since
`br` was not capitalized, we fell back on european portuguese for Linux
and MacOS

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

(cherry picked from commit 2be87e4527)
2023-09-29 11:10:37 -07:00
Josue Huaroto 909d199379 Save flip board status in custom preset
(cherry picked from commit 2d54bc42cb)
2023-09-29 11:07:49 -07:00
Seth Hillbrand 5f16f4ab99 Focus back to the main window after dialog
Mouse actions would focus the window but we explicitly set it here to
allow keyboard shortcuts

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

(cherry picked from commit b2ef620ea6)
2023-09-29 11:06:44 -07:00
Seth Hillbrand fff95fa4e6 Disable non-KiCad import for project-mode
Adds warning if project schematic contains data

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

(cherry picked from commit b837aa823c)
2023-09-29 11:05:49 -07:00
Seth Hillbrand a38327a39c Ensure that layer names are unique when importing
Altium allows duplicate layer names but KiCad prefers to have unique
names for each layer.  This enforces a unique name for each layer when
importing

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

(cherry picked from commit c772d116b2)
2023-09-29 11:03:21 -07:00
Seth Hillbrand 686048dcce Be smarter about releasing lockfiles
If KiCad crashes or exits without deleting the lockfile, don't show the
warning message unless we are not the one who locked it or there are
other KiCad instances running locally.

This should catch 99% of the cases where the message is shown
incorrectly.  There may be some corner cases where the lock file is
created on a network drive using two different machines with the same
name and same user but these cases should be (famous last words)
sufficiently rare as to not be observed in practice

(cherry picked from commit 7fe83993cf)
2023-09-29 11:02:42 -07:00
Seth Hillbrand 330c0f86de Set pinmap after updating pins
When duplicating and existing symbol, we must set the pins before
setting the lib symbol as the lib symbol will generate a pin map that
will be broken by the shift to new pins

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

(cherry picked from commit 12ebb2bbfa)
2023-09-29 17:59:24 +00:00
Seth Hillbrand 83317f1b80 Don't destroy the pin cache in symbols
SCH_PIN pointers are used through KiCad and removing them without a
global refresh risks crashes.  A safer approach is to simply reuse the
SCH_PIN structures, updating the data to the revised library

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

(cherry picked from commit bdb7b99fc8)
2023-09-29 17:59:24 +00:00
Wayne Stambaugh a416eb2cf6 Fix schematic editor crash when updating symbols.
Some how symbol names that still have escaped '/' character get mixed with
symbol names that have '/' characters now that it is no longer an invalid
LIB_ID character.  This was causing derived symbols to loose the link to
the parent symbol.  This fix replaces any instances of "{slash}" with "/"
to convert symbol names to the proper escaping.

Thanks to JP for the inspiration for the fix.

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

Manually cherry picked from commit 2f51d22b3a.
2023-09-29 12:53:33 -04:00
Wayne Stambaugh 2959c94bd3 Begin version 7.0.9 development. 2023-09-29 12:26:05 -04:00
Wayne Stambaugh 063d9c8305 Tag release version 7.0.8. 2023-09-29 12:17:59 -04:00
Seth Hillbrand 5e97608fa5 Update translations 2023-09-29 08:58:00 -07:00
dsa-t 50dca2d02b Translated using Weblate (Russian)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ru/
2023-09-29 17:57:18 +02:00
Seth Hillbrand cd3785744c Update translations 2023-09-28 12:06:05 -07:00
Seth Hillbrand 357810a5d5 Revert "Translated using Weblate (Russian)"
This reverts commit 62044c2731.
2023-09-28 12:05:50 -07:00
Seth Hillbrand 1b71bc115d Revert "Translated using Weblate (Russian)"
This reverts commit 23ddb99026.
2023-09-28 12:05:50 -07:00
Seth Hillbrand de40286e81 Revert "Translated using Weblate (Russian)"
This reverts commit e7aa95d53d.
2023-09-28 12:05:49 -07:00
Seth Hillbrand 8d0ff95760 Revert "Translated using Weblate (Russian)"
This reverts commit a8bcf8c9e4.
2023-09-28 12:05:49 -07:00
Seth Hillbrand ffddf9fec3 Revert "Translated using Weblate (Russian)"
This reverts commit 3a35d96130.
2023-09-28 12:05:47 -07:00
Seth Hillbrand 3a35d96130 Translated using Weblate (Russian)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ru/
2023-09-28 20:59:28 +02:00
Marcel Hecko 8add678d87 Translated using Weblate (Slovak)
Currently translated at 65.1% (5223 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/sk/
2023-09-28 20:59:28 +02:00
xXx a8bcf8c9e4 Translated using Weblate (Russian)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ru/
2023-09-28 20:59:28 +02:00
Hubert Hu 090374a1dc Translated using Weblate (Chinese (Simplified))
Currently translated at 99.8% (8012 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/zh_Hans/
2023-09-28 20:59:28 +02:00
xXx e7aa95d53d Translated using Weblate (Russian)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ru/
2023-09-28 20:59:28 +02:00
Toni Laiho f6ccf18cf5 Translated using Weblate (Finnish)
Currently translated at 99.8% (8006 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/fi/
2023-09-28 20:59:28 +02:00
Marine Biologist 4542ce8c70 Translated using Weblate (Turkish)
Currently translated at 61.3% (4919 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/tr/
2023-09-28 20:59:28 +02:00
Henrik Kauhanen f80287bc27 Translated using Weblate (Swedish)
Currently translated at 99.9% (8015 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/sv/
2023-09-28 20:59:28 +02:00
ZbeeGin e10ab74917 Translated using Weblate (Polish)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pl/
2023-09-28 20:59:28 +02:00
xXx 23ddb99026 Translated using Weblate (Russian)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ru/
2023-09-28 20:59:27 +02:00
Henrik Kauhanen efbac9e128 Translated using Weblate (Swedish)
Currently translated at 99.9% (8015 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/sv/
2023-09-28 20:59:27 +02:00
xXx 62044c2731 Translated using Weblate (Russian)
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ru/
2023-09-28 20:59:27 +02:00
Wellington Terumi Uemura 7d1a38d46f Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (8022 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pt_BR/
2023-09-28 20:59:27 +02:00
ZbeeGin d885bc14e1 Translated using Weblate (Polish)
Currently translated at 99.9% (8017 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pl/
2023-09-28 20:59:27 +02:00
Eryk Michalak 886937a3ea Translated using Weblate (Polish)
Currently translated at 99.9% (8017 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pl/
2023-09-28 20:59:27 +02:00
Tokita, Hiroshi 99eff43ab4 Translated using Weblate (Japanese)
Currently translated at 99.9% (8021 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ja/
2023-09-28 20:59:27 +02:00
Mark Hämmerling 880269780d Translated using Weblate (German)
Currently translated at 99.9% (8021 of 8022 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/de/
2023-09-28 20:59:27 +02:00
Marek Roszko 7f1b891679 Save 470KB by not re-initializing lineTypeNames over a thousand cpp files it leaks into
I saved a bunch of money on my car insurance by switching to Extern


(cherry picked from commit 9deff07ca6)
2023-09-25 02:31:46 +00:00
Wayne Stambaugh ceced2a9a4 Tag stable version 7.0.8 release candidate 1. 2023-09-20 16:53:58 -04:00
Seth Hillbrand d3a8cb84a6 Make LIB_TREE_NODE sort irreflexive
std::sort requires explicit ordering of all elements.  It does not allow
for equality in its output

(cherry picked from commit 5c1b15f8e3)
2023-09-20 13:48:43 -07:00
Seth Hillbrand 6b43bb8fe3 Fix crash in incremental update and bus conn
We store our connectivity dirty flag with the SCH_ITEM but we generate
SCH_CONNECTION based on the SCH_ITEM and the SCH_SHEET_PATH.  For this
reason, we need to avoid clearing the connectivity dirty flag until
we've finished processing all instances of the SCH_ITEM in the graph

This also means that we need to allow getting the SCH_CONNECTION pointer
even when the connectivity is still dirty (getting SCH_CONNECTION
happens based on SCH_ITEM and SCH_SHEET_PATH, not just SCH_ITEM)

(cherry picked from commit 7d12e1c4f5)
2023-09-19 16:07:40 -07:00
jean-pierre charras a74cffac39 PANEL_SETUP_BOARD_STACKUP: save the m_HasDielectricConstrains BOARD_STACKUP member.
This member was not saved in the board stackup data.
From master branch.
Fixes #15690
https://gitlab.com/kicad/code/kicad/-/issues/15690
2023-09-19 18:05:42 +02:00
Marco Ciampa 83d2891cef Updated Italian translation 2023-09-19 11:32:43 +02:00
Seth Hillbrand 0faad370f9 Fix some stale pointers in incremental updates
Shared pointers contained stale references to the temporary graph.  When
merging, we need to ensure all references are updated to the final graph

(cherry picked from commit b52c43b933)
2023-09-18 21:27:22 -07:00
Seth Hillbrand 23fab89131 Properly handle incremental bus connections
- Incremental extraction needs the newly created items.  The modified
  items are already set in the connection graph but the newly created
  items don't exist yet, so we need to add those explicitly
- Bus parents need to ensure that the bus children exist because we
  iterate on the updates from the top of the graph down

(cherry picked from commit 9fc45eb08c)
2023-09-18 21:26:58 -07:00
jean-pierre charras 48189172ea Eeschema: fix crash if using ${FOOTPRINT_NAME} or ${FOOTPRINT_LIBRARY} as values
in fields, if no footprint defined for the symbol.
From master branch
Fixes #15676
https://gitlab.com/kicad/code/kicad/-/issues/15676
2023-09-18 09:33:25 +02:00
jean-pierre charras 0c9eda44d4 French translation update 2023-09-16 10:21:41 +02:00
Seth Hillbrand f0a9ce3ab4 Update translations 2023-09-15 15:58:04 -07:00
Li Yidong ea5878a0c9 Translated using Weblate (Chinese (Traditional))
Currently translated at 99.8% (8005 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/zh_Hant/
2023-09-16 00:57:34 +02:00
Li Yidong f67382612d Translated using Weblate (Chinese (Simplified))
Currently translated at 99.9% (8019 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/zh_Hans/
2023-09-16 00:57:34 +02:00
Henrik Kauhanen 3fe7ae07ed Translated using Weblate (Swedish)
Currently translated at 99.9% (8016 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/sv/
2023-09-16 00:57:34 +02:00
dsa-t 8bcfa81bea Translated using Weblate (Russian)
Currently translated at 99.9% (8019 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ru/
2023-09-16 00:57:34 +02:00
Jan Straka c17918d9c1 Translated using Weblate (Czech)
Currently translated at 91.8% (7363 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/cs/
2023-09-16 00:57:34 +02:00
Ivan Chuba f752df0595 Translated using Weblate (Estonian)
Currently translated at 4.9% (400 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/et/
2023-09-16 00:57:34 +02:00
Ivan Chuba 0836b5b661 Translated using Weblate (Ukrainian)
Currently translated at 99.9% (8017 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/uk/
2023-09-16 00:57:34 +02:00
ZbeeGin 2cefccf7bf Translated using Weblate (Polish)
Currently translated at 99.9% (8019 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pl/
2023-09-16 00:57:34 +02:00
Ivan Chuba 3dc86c5a4f Translated using Weblate (Estonian)
Currently translated at 4.9% (399 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/et/
2023-09-16 00:57:34 +02:00
ulikoehler 05ae712e77 Translated using Weblate (German)
Currently translated at 99.9% (8018 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/de/
2023-09-16 00:57:34 +02:00
Tokita, Hiroshi 04db374326 Translated using Weblate (Japanese)
Currently translated at 99.9% (8016 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/ja/
2023-09-16 00:57:33 +02:00
Jan Straka e3558b7dcf Translated using Weblate (Czech)
Currently translated at 91.4% (7338 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/cs/
2023-09-16 00:57:33 +02:00
Wellington Terumi Uemura 99e10c6112 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (8020 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/pt_BR/
2023-09-16 00:57:33 +02:00
temizinsan 537934339e Translated using Weblate (Turkish)
Currently translated at 61.3% (4924 of 8020 strings)

Translation: KiCad EDA/v7
Translate-URL: https://hosted.weblate.org/projects/kicad/v7/tr/
2023-09-16 00:57:33 +02:00
Seth Hillbrand ee343e1263 Fix crash when duplicating symbol
Adding symbol to the screen can change the library reference.  But when
we are pasting, we want the library reference for annotation, so we need
to keep a map of old->new libsymbols and fixup the pasted symbols before
using

Fixes https://gitlab.com/kicad/code/kicad/-/issues/15419
2023-09-15 15:43:50 -07:00
jean-pierre charras 6eeca9aa90 Pcbnew: fix some issues with very small arcs (size a few internal units)
these very small arcs do not allow to calculate a reliable center position,
and therefore a reliable radius.
So handle them as a very small segments to fix plotting/drawing issues.
From master branch.
Fixes #15639
https://gitlab.com/kicad/code/kicad/-/issues/15639
2023-09-15 17:47:21 +02:00
Alex Shvartzkop 86beb339b7 Improve error reporting when running Python action plugins.
Python error traceback is now logged to stderr.
On Windows, a console window will pop up if wxTheApp gets destroyed,
because message dialogs crash due to hooks that wxWidgets sets up.

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

(cherry picked from commit a9a2d4aa7a)
2023-09-15 13:33:28 +03:00
Jeff Young 67b5af23aa Run filled-test before degenerate-ring-test.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15642

(cherry picked from commit 47dc86c1e2)
2023-09-13 23:45:27 +01:00
Roberto Fernandez Bautista 88f65f4e47 Fix loading of legacy zone fills in .brd files + Don't refill after board import
(cherry picked from commit 30a63b7b32)
2023-09-14 01:06:34 +03:00
Roberto Fernandez Bautista af5b6b0eba Fix import of legacy stroked zone fill + add parsing of segments fills
From master: 54f401c72c
2023-09-14 01:06:34 +03:00
Seth Hillbrand 57ef739404 Fix connectivity regression
We have a break somewhere in the connectivity that doesn't fully process
connections but the current code seems to catch these by forcing a
top-down & bottom-up calculation

Fixes https://gitlab.com/kicad/code/kicad/-/issues/14818
2023-09-13 12:31:46 -07:00
Seth Hillbrand 584eb9f531 Remove extra nag/grid assertion
When editing the properties, if you accidentally make an extra line, you
should be able to remove the data and have it ignored.
2023-09-13 12:31:46 -07:00
Alex Shvartzkop 36a4d5a511 QA: refill zones in issue5990.kicad_pcb 2023-09-13 14:38:25 +03:00
Alex Shvartzkop 72737b20cd Fix reading legacy zone fills which were based on stroked polygons.
Ported from 448de72823
with InflateWithLinkedHoles
2023-09-13 03:40:23 +03:00
Jeff Young d05093e6f7 Don't throw the number box baby out with the bathwater.... 2023-09-12 17:39:34 +01:00
Jeff Young a7e6928f4e Don't go through a middle man when reading pad shape primitives.
They're both PCB_SHAPEs.

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

(cherry picked from commit 9f5a268f15)
2023-09-11 22:20:33 +01:00
Alex Shvartzkop 951fd2d693 Altium schematic: support Line dash styles and colors.
Master commit: a2b7bf97b9
2023-09-11 18:33:34 +03:00
Alex Shvartzkop be991cfcd6 Clear view before resetting schematic.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15159

(cherry picked from commit cab0db76f8)
2023-09-11 18:28:05 +03:00
jean-pierre charras aab36d9b85 Gerbview, export to PCB: fix incorrect export of flashed shapes on non copper layers.
From master branch
Fixes #15613
https://gitlab.com/kicad/code/kicad/-/issues/15613
2023-09-11 15:04:55 +02:00
Alex Shvartzkop 3cd6935acb Work around wxGTK printing offset in eeschema.
Affects landscape Letter, Legal, A4 paper.

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

(cherry picked from commit 5da4dfd4a7)
2023-09-11 14:37:39 +03:00
Alex Shvartzkop 6daef080e3 Altium schematic: fix ISSOLID flag for text frames.
Fixed in master by 24d3df5416
2023-09-11 14:23:54 +03:00
Alex Shvartzkop 6ee909b958 Altium schematic: support custom sheet sizes.
(cherry picked from commit 16062bbe33)
2023-09-11 10:06:38 +03:00
Alex Shvartzkop c11ae8bd02 Fix a bug in RebuildBezierToSegmentsPointsList.
(cherry picked from commit 9f63820ed4)
2023-09-11 10:05:59 +03:00
John Beard c7a4ea97c3 Fix oval pad snapping
Previously the snap points computed for oval pads didn't get all the
points correct. This breaks out the "find snap points for ovals"
into a function, reworks the logic, adds some tests.

Also adds "extremum points" when the oval isn't exactly H/V.

(cherry picked from commit 78c8de9b08)

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/15594
2023-09-10 00:49:03 +01:00
John Beard 81ebb1030a Add forward declarations in pcb_grid_helper.h
(cherry pick of part of commit 0f781f328e)
2023-09-10 00:45:32 +01:00
Alex Shvartzkop 86ec36d183 Fix reading/writing thermal spoke angles for custom pads.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15518
2023-09-10 17:32:22 +03:00
jean-pierre charras 207f2e568b drc_test_provider_text_dims.cpp: ensure glyphs to test are OUTLINE_GLYPH.
For non Kicad font texts with a overbar, the overbar is not a OUTLINE_GLYPH.
From Master branch.
Fixes #15604
https://gitlab.com/kicad/code/kicad/-/issues/15604
2023-09-09 10:37:58 +02:00
Alex Shvartzkop 19753719cb SVG import: skip shapes that are not stroked and not filled.
(cherry picked from commit bc846f5fca)
2023-09-08 14:49:08 +03:00
Alex Shvartzkop 5f025dcd73 SVG import: skip invisible shapes. 2023-09-08 14:49:08 +03:00
Alex Shvartzkop c796eeaf8b NanoSVG: change preserveAspectRatio default to "xMidYMid meet".
(cherry picked from commit c64b44913c)
2023-09-08 14:49:08 +03:00
Alex Shvartzkop bdbd7f0c9c NanoSVG: update image size to the actual size after scaling.
(cherry picked from commit 2c07866fff)
2023-09-08 14:49:08 +03:00
Alex Shvartzkop b0e09327db NanoSVG: basic support for stylesheets.
Based on https://github.com/memononen/nanosvg/pull/175

(cherry picked from commit 2cd7c0636f)
2023-09-08 14:49:08 +03:00
Seth Hillbrand 96a3621b8e Update TestDanglingEnds to O(n) speed
The elements don't care which they connect to, so don't search for
points on the page, just collect them all and then test them all

Adjusts f3dd5b73

(cherry picked from commit c2fd2f42eb)
2023-09-07 01:37:42 +02:00
Josue Huaroto 8f259211e7 Change behavior of ZOOM_FIT_ALL and ZOOM_FIT_OBJECTS for PCB_EDITOR
(cherry picked from commit 91d8dabca3)
2023-09-06 16:56:27 +01:00
Josue Huaroto 0d9d8c28f1 Flip Viewport when Flip board is enabled
(cherry picked from commit a8e18e2d8c)
2023-09-06 16:56:01 +01:00
Jeff Young 058a0bbf93 Don't attempt to render degenerate 3D shapes.
Sentry KICAD-382

(cherry picked from commit 70bbaae670)
2023-09-06 16:33:31 +01:00
Jeff Young 4d46e0ceb7 Include underscore in word chars.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14779

(cherry picked from commit 0dddb27408)
2023-09-06 16:33:02 +01:00
Jeff Young 123ff326d4 Don't include plating thickness when drawing hole clearance lines.
We don't include it in the router, and the code didn't
differentiate between plated and non-plated holes, and it confuses
users.

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

(cherry picked from commit 0cde8cff1d)
2023-09-06 16:31:46 +01:00
Jeff Young 14d4c38979 Honour override-individual-item-colors setting for filled shapes.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15572

(cherry picked from commit d593257fbd)
2023-09-06 16:31:22 +01:00
Alex Shvartzkop 9c87a52b6e Altium PCB import: Polygon Cutout only cuts copper fill.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15587

(cherry picked from commit 4f303a8dc2)
2023-09-06 09:26:48 +03:00
Alex Shvartzkop 30c2028852 Revert "Set reporter in DIALOG_SIM_MODEL::TransferDataToWindow."
This reverts commit 5b0d752e0c.
2023-09-06 08:03:00 +03:00
Marek Roszko 95e6be0e81 Prevent crash trying to load missing spice lib
(cherry picked from commit 4fe7c7a902)
2023-09-06 01:13:54 +00:00
jean-pierre charras 955313e97d GAL_OPTIONS_PANEL: replace 2 wxSpinCtrlDouble to try to fix a locale issue.
Sometimes the grid thickness setting does not work, depending on some locale setting.
Core developers are not able to reproduce this issue related to a double conversion.
So these wxSpinCtrlDouble are replaced by a wxSpinCtrl (using ints) and a wxChoice.

From master branch
2023-09-05 18:56:24 +02:00
Marek Roszko 32c2135047 Flip the RegisterSettings order to avoid legacy import crashes 2023-09-04 23:22:39 -04:00
Marek Roszko 702e08b083 Don't call .Load() and cause settings to reload from disk
RegisterSettings can load the new settings json as added by not turning off the load now parameter
2023-09-04 22:41:12 -04:00
jean-pierre charras 8f58e1a9e0 DIALOG_EXPORT_STEP_LOG: print the command line sent to kicad-cli in report window.
It can be useful in case of problems.


(cherry picked from commit 2bf8602912)
2023-09-05 00:26:43 +00:00
Mark Roszko 0cc25f10c6 Pull in ngspice 41 for vcpkg 2023-09-04 19:36:07 +00:00
Jeff Young 61ef88a0ac Don't allow duplication of footprint items outside of footprint editor.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15487

(cherry picked from commit 9bba8e5956)
2023-09-03 22:44:17 +01:00
Jeff Young 02a95b958d Remove up/down buttons until we implement layer ordering.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14574

(cherry picked from commit d27413a032)
2023-09-03 22:43:41 +01:00
Jeff Young 5cd88dbd20 Bug fixes for paste margins on custom-shaped pads.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15125

(cherry picked from commit 60419f542a)
2023-09-03 22:32:40 +01:00
Jeff Young ec53ed6a37 Don't start a router drag when already in an EDIT_TOOL drag or move.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15312

(cherry picked from commit 624203f2e1)
2023-09-03 22:12:43 +01:00
Jeff Young 242413a334 Don't start a pack&move when already in an EDIT_TOOL drag or move.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15545

(cherry picked from commit a24a8aaca7)
2023-09-03 22:12:24 +01:00
Jeff Young f88dce1627 Don't return separate shapes from a custom-shaped pad.
It just confuses the hull generator.

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

(cherry picked from commit 43862d767e)
2023-09-03 22:11:15 +01:00
Jeff Young 5c456370d9 Add items to repeat_items after paste (or duplicate).
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15556

(cherry picked from commit f6e238dc3f)
2023-09-03 22:10:38 +01:00
Jeff Young 93fdd35b31 Support SHORT_NET_NAME(pin_number) and friends on symbols.
While it's of debatable use in the schematic, some users want to
author them there so that they're then copied onto the board.

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

(cherry picked from commit d74e9ba040)
2023-09-03 22:07:11 +01:00
Jeff Young 70d5fccb54 {slash}-to-/ comparison special-cases need to run both ways.
(The library may be legacy format, or the document may be.)

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

(cherry picked from commit 86f96d544b)
2023-09-03 22:05:58 +01:00
Jeff Young 6ca7c3a3a1 Fix merge errors. 2023-09-02 11:18:34 +01:00
Jeff Young 88448ce746 Custom pads with round anchors in pre-7.0 files get 90 degree spokes.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15518

(cherry picked from commit 676c6e81a4)
2023-09-02 11:18:34 +01:00
Jeff Young 1fee2c626b Save ERC settings (including exclusions) when saving file.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15274

(cherry picked from commit 10ed1d1a7f)
2023-09-02 11:18:34 +01:00
Jeff Young 480a9ac77d Implement undo/redo around Pad Edit Mode changes.
(cherry picked from commit 69a1b30b8a)
2023-09-02 11:18:34 +01:00
Jeff Young 889689e31a Stop trying to zero-out offset of custom-shaped pads.
It causes *way* to many issues.

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

(cherry picked from commit 68c839b214)
2023-09-02 11:18:34 +01:00
Jeff Young c8e49599ce Use STD_BITMAP_BUTTON for change symbols dialog.
(cherry picked from commit f3f57f77d9)
2023-09-02 11:18:34 +01:00
Jeff Young 351cb7e104 Re-run autoplacement after symbol replacement (when appropriate).
Also prevents an internal wxWidgets assert by clearing grid
selection before deleting rows.

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

(cherry picked from commit 377ffb00b0)
2023-09-02 11:18:34 +01:00
Adam Simpkins 5c5e41500a kicad-cli: add option to control oval drill export behavior
Add an argument to "kicad-cli pcb export drill" to control the oval
holes drill mode for the excellon output format.

The Generate Drill Files GUI dialog recommends the newer "route"
behavior by default.  Previously this option was not exposed in
kicad-cli.  This commit does not change the default kicad-cli behavior,
but simply adds an argument to control it.


(cherry picked from commit 9b69d84688)
2023-08-31 22:26:59 +00:00
jean-pierre charras 2e739e743d Gerber place file: change DCode size of pads others than 1 or A1 to 0.1 mm
Previously it was a round shape 0.0 mm (allowed but not visible)
Gerber Format rev 2023-08 changed it to 0.1 mm (still a round shape)
2023-08-31 16:44:14 +02:00
Jeff Young 1eee3d350b Fix merge errors. 2023-08-31 12:37:44 +01:00
Jeff Young d2d7e630bd Allow for offset custom-shaped pads with no holes.
(cherry picked from commit 0d39cd5e63)
2023-08-31 12:37:44 +01:00
Jeff Young d11cd173dc Fix previous fix for honouring pad offset.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15494

(cherry picked from commit e0cf49e73c)
2023-08-31 12:37:44 +01:00
Jeff Young 12e0427038 Honour pad offset when creating custom pad anchors (and polygons).
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15494

(cherry picked from commit 300014177f)
2023-08-31 12:37:44 +01:00
Jeff Young 9bcb6f0adf Don't count pins of both De Morgan variants when matching to footprint pads.
(And remove un unused variable from grid settings dialog.)

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

(cherry picked from commit cb003d8ab4)
2023-08-31 12:37:44 +01:00
Jeff Young 09490e1f46 Don't snap a footprint (or group) to its children.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15535

(cherry picked from commit d161602e92)
2023-08-31 12:37:44 +01:00
Jeff Young f33120c540 Remember footprint library browsers liblist width.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15500

(cherry picked from commit a4d1b29b91)
2023-08-31 12:37:44 +01:00
Jeff Young 82ed223b02 Handle non-cardinal major-axis arcs when importing DXF.
(cherry picked from commit a946f7ab1b)
2023-08-31 12:37:44 +01:00
Jeff Young bfdbf969c2 Handle DXF arcs with a flipped coord system.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14905

(cherry picked from commit 75b160e83a)
2023-08-31 12:37:44 +01:00
Jeff Young 7d409b9404 Minor cleanup and removal of stale comments.
Also attempts to fix a focus-loss bug on GTK after zone dialog.

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

(cherry picked from commit 3f26b29aa2)
2023-08-31 12:37:44 +01:00
Jeff Young 7673f220a9 Minor cleanup and removal of stale comments.
(cherry picked from commit c48084bbbf)
2023-08-31 12:37:44 +01:00
Jeff Young 75daa1afec Don't presume all cached glyphs are outline glyphs.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15508

(cherry picked from commit 949458bbe1)
2023-08-31 12:37:44 +01:00
Jeff Young 27657e00fe Handle dimensions and textboxes when plotting contours to DXF.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/11901

(cherry picked from commit 83fe3576c6)
2023-08-31 12:37:44 +01:00
Mark Roszko 26b8812f15 Fix 3d viewer rendering textbox borders that were disabled 2023-08-31 02:50:36 +00:00
jean-pierre charras 07e13c51d1 UNIT_BINDER: allows more room to show values (especially inches need room)
Fixes #15539
https://gitlab.com/kicad/code/kicad/-/issues/15539
2023-08-30 09:14:28 +02:00
jean-pierre charras f9b59b4fdf PANEL_SETUP_SEVERITIES: fix a missing init (m_severitiesPage) creating a crash.
PANEL_SETUP_SEVERITIES::ImportSettingsFrom(): ensure the option to set
actually exists before setting it.
2023-08-29 10:56:40 +02:00
Seth Hillbrand 76a3b3db97 Better handle many (MANY) duplicate refs
In large designs with thousands of duplicate elements (e.g. power
symbols), we need to be smart about vector management.  Removing all but
the first few items should be batched and not element at a time

Ref: KSC-885
(cherry picked from commit b43f037a91)
2023-08-28 17:08:42 -07:00
Seth Hillbrand 4b0416e92a Simplify logic when setting field vector
Previous logic could get stuck in infinite loop if removing element from
the middle of the vector

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

(cherry picked from commit 9636321c09)
2023-08-28 15:29:19 -07:00
jean-pierre charras 5d6bb4b04f Update Clipper2 to commit 7cf615c2799a9328ec32eb116f46b64ed34aecff.
(it fixes (or try to fix) an issue impacting Kicad)
2023-08-28 08:02:28 +02:00
Jeff Young 2764f292cb Don't store address of temp object.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15517
2023-08-27 19:02:57 +01:00
Marek Roszko 7ca59e24c6 Force fontconfig to look at the correct path for fonts.conf on windows
(cherry picked from commit 208d146a03)
2023-08-26 17:59:47 +00:00
Marek Roszko e1a2d60672 Don't call FcInitLoadConfigAndFonts after FcInit() already happened
We are only the default global FcConfig created by calling FcInitLoadConfigAndFonts inside FcInit().
Calling FcInitLoadConfigAndFonts does nothing but creating another FcConfig option that never gets disposed or used because we use the FcConfig functions with null


(cherry picked from commit 53bf7b71c6)
2023-08-26 17:59:28 +00:00
Alex Shvartzkop 9672390104 Fix a search pane crash when a row isn't in the hit list.
Fixes KICAD-Q7
Fixes KICAD-1A6

Cherry-picked from f071dd1406
2023-08-26 00:53:14 +03:00
Alex Shvartzkop 33c2005c18 EAGLE import: fix crash when loading unknown signal class name.
Fixes KICAD-3FA

Cherry-picked from 0fcf9e2c7d and 331176744c
2023-08-26 00:47:43 +03:00
Alex Shvartzkop 3e1309110e EAGLE import: fix crash when loading a polygon.
Fixes KICAD-TW

(cherry picked from commit bfb6269f0a)
2023-08-26 00:41:50 +03:00
Wayne Stambaugh aae7d94ffd Remove duplicate references from change symbol dialog.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15480

(cherry picked from commit 1db9febcfe)
2023-08-25 14:28:13 -04:00
Alex Shvartzkop 5b0d752e0c Set reporter in DIALOG_SIM_MODEL::TransferDataToWindow.
It could've been set to point to local variable "reporter" in loadLibrary.

Fixes KICAD-15C

(cherry picked from commit 26f398a4b1)
2023-08-25 21:09:28 +03:00
jean-pierre charras 0f93752f14 Revert "Record hole knockouts in zone filler earlier"
This reverts commit 1ccaf45740.
Breaks sone thermal shapes.
Not needed after Clipper2 update.
2023-08-25 07:35:06 +02:00
jean-pierre charras 049ecc43e3 Update Clipper2 to commit 4ef91e99756f97cab23e7fa2cd78861deeb61338.
It fixes some of our issues.
However, Clipper issue 618 can create problems in zone filler, Clipper2
will be updated as soon as issue 618 is fixed.
Include also a fix for *nix
From Master branch
2023-08-25 07:35:06 +02:00
Marek Roszko 2209f5e93b Fix accidental plotting of disabled textbox borders
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15252
2023-08-24 21:14:27 -04:00
Marek Roszko a17cd9d054 Make VRML use board edge bounding box for parity with step
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15472
2023-08-24 20:42:58 -04:00
Alex Shvartzkop 4497aaa3fa Prevent crash when a python script tries to use pcbnew too early.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15414

(cherry picked from commit b1b66f66f4)
2023-08-25 00:17:03 +03:00
Jeff Young 00226ae40a Honour aAllowExtraText flag in LIB_FIELD::GetShownText().
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15470
2023-08-21 19:20:00 +01:00
jean-pierre charras 45963a3443 Step export: fix incorrect Z position of holes, after code change.
Fixes #15467
https://gitlab.com/kicad/code/kicad/-/issues/15467
2023-08-21 14:48:48 +02:00
Jeff Young 4aa1a881f3 Pull back some more fixes from master.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15461
2023-08-20 19:08:29 +01:00
Jeff Young f3dd5b73f8 TestDanglingEnds needs to test sheet pins as well.
Also fixes a bug where zooming doesn't get a redraw until mouse moves.

Also fixes a couple of bugs where dangling markers on SCH_SHEET_PINs
and SCH_HIERLABELs weren't getting drawn.

Also simplifies drawing algorithm by removing aesthetic offset (which
wasn't implemented when pin is drawn as part of selection VIEW_GROUP).

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

(cherry picked from commit c8e8b71198)
2023-08-20 18:44:40 +01:00
Jeff Young fd049ef510 Fix selection shadown drawing for global labels.
(The border should get shadowed, and the shape should get filled if
m_Selection.fill_shapes is set.)

(cherry picked from commit 1c13f5a0db)
2023-08-20 18:15:38 +01:00
Jeff Young 7d389f8024 Don't try to be smart about enabling the Clear Annotation button.
(At a minimum it would need to also handle when the scope changes, but
it's not clear we're adding anything by enabling/disabling it to start
with.)

(cherry picked from commit 2278f5dbca)
2023-08-19 20:09:47 +01:00
Jeff Young df63f47deb Save color settings after modification in Appearances Manager.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15390

(cherry picked from commit 1cbc6e33db)
2023-08-19 20:09:47 +01:00
Jeff Young c521efa35d Move checking for null parent higher.
(Otherwise we set the failure flag without telling the user why.

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

(cherry picked from commit 6a6e839cc4)
2023-08-19 20:09:47 +01:00
Jeff Young af1561b848 Don't double-offset effective text shapes.
Also fixes several bugs with intersheet ref fields.  (It's possible for
other fields to have an ID of 0.)

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

(cherry picked from commit eedf319ba4)
2023-08-19 20:09:47 +01:00
jean-pierre charras 691931f74d kicad-cli, export plot PDF and SVG: add missing option --drill-shape-opt.
It allows pad/via holes to ber plotted at actual size, small size, or not.
This option exists in GUI, but was missing in kicad-cli.

(cherry picked from commit f18feb2a46)
2023-08-19 10:56:32 -04:00
Marek Roszko da5e1de1c8 Add a workaround to Nahimic crapware
Fixes https://gitlab.com/kicad/code/kicad/-/issues/11850


(cherry picked from commit 726f09f9ad)
2023-08-18 03:02:06 +00:00
Jeff Young 043892bdc6 Disable "Override individual item colors" on read-only themes.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15426

(cherry picked from commit 88db775d32)
2023-08-17 11:49:58 +01:00
Jeff Young 34d2aeaac3 Update Eagle gold files for spoke angle fixes.
(cherry picked from commit f2a8c25084)
2023-08-17 11:49:58 +01:00
Jeff Young 4481e89046 Fix incorrect assumption about Eagle spoke rotation.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15428

(cherry picked from commit 25b9a9de7e)
2023-08-17 11:49:58 +01:00
Jeff Young 8120e47bfd Better fidelity for Eagle thermal spokes.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15428

(cherry picked from commit a58547dde5)
2023-08-17 11:49:58 +01:00
Jeff Young db526e581c Don't call driverName() unless we have a cache miss.
(That is, in fact, the whole purpose of this cache.)

(cherry picked from commit e48a96ecaf)
2023-08-17 11:49:58 +01:00
jean-pierre charras 246be732a1 Pcbnew, DIALOG_PAD_PROPERTIES: ensure the right spoke angle is displayed.
From master, commit d8ba6c07ac
2023-08-17 08:04:18 +02:00
Marek Roszko 27a0bd2535 Backport changes to merge distance for step export
Fixes https://gitlab.com/kicad/code/kicad/-/issues/14910
2023-08-16 22:12:55 -04:00
Jon Evans 8f57fd82a0 DbLib: Provide more useful feedback when table is misconfigured 2023-08-15 16:45:10 -04:00
Jeff Young 1ef90c898e Don't allow selection of footprint dimensions.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15418

(cherry picked from commit 750b92b17f)
2023-08-15 17:54:00 +01:00
Jeff Young cf133975c1 Avoid edge cases on very wide thermal spokes.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15280

(cherry picked from commit 1cbef0157d)
2023-08-15 17:53:35 +01:00
Jeff Young c468b68c5a Better handling of dangling markers during bus unfold.
(cherry picked from commit c981c3668a)
2023-08-15 17:52:42 +01:00
Jeff Young acbddc904b Don't consider newly-added labels when looking for terminal items.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15313

(cherry picked from commit 6cef504d2d)
2023-08-15 17:52:27 +01:00
Jeff Young 83624acfd2 Allow GetLayer() to be used with single-layer zones.
Also fixes a bug in GetFirstLayer() where we were checking
m_layerSet.size() (which is always 60) rather than
m_layerSet.count() (which is the number of set layers).

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

(cherry picked from commit 8bb895373a)
2023-08-15 17:51:52 +01:00
Jeff Young d915ddc647 Fix missing variable initialization.
(cherry picked from commit b401c214f5)
2023-08-15 17:30:38 +01:00
Jeff Young 61b741c34e Re-entrancy guard for length tuner tool.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15268

(cherry picked from commit 620b6b7169)
2023-08-15 17:30:02 +01:00
Jeff Young aa1910a834 Re-implement some commented-out hole clearance checking in router.
(cherry picked from commit 5e18287ff9)
2023-08-15 17:29:22 +01:00
Jeff Young dba36c07fe Only re-build the members grid when we have to.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/15320

(cherry picked from commit d3329a0781)
2023-08-15 17:26:14 +01:00
Jan Mrázek 8451e6dcf1 Fix failure on multiple DRC runs via scripting
(cherry picked from commit 2d010278ad)
2023-08-15 01:40:04 +00:00
Jon Evans 88dfe6eb9c Stricter API for LIB_TABLE
Prevent nickname map or row parent getting out of sync

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


(cherry picked from commit 4c4bbdc8f3)
2023-08-15 01:39:09 +00:00
Wayne Stambaugh 800b697d06 Begin version 7.0.8 development. 2023-08-13 18:13:28 -04:00
356 changed files with 85823 additions and 78108 deletions
@@ -201,7 +201,8 @@ void BOARD_ADAPTER::addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2
if( textbox->GetLayer() == aLayerId )
{
addShape( textbox, aContainer, aFootprint );
if( textbox->IsBorderEnabled() )
addShape( textbox, aContainer, aFootprint );
addText( textbox, aContainer, aFootprint );
}
@@ -260,6 +261,19 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
{
const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack );
if( arc->IsDegenerated() )
{
// Draw this very small arc like a track segment (a PCB_TRACE_T)
PCB_TRACK track( arc->GetParent() );
track.SetStart( arc->GetStart() );
track.SetEnd( arc->GetEnd() );
track.SetWidth( arc->GetWidth() );
track.SetLayer( arc->GetLayer() );
createTrack( &track, aDstContainer );
return;
}
VECTOR2D center( arc->GetCenter() );
EDA_ANGLE arc_angle = arc->GetAngle();
double radius = arc->GetRadius();
@@ -625,16 +639,12 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
if( inner_radius3DU < 0 )
inner_radius3DU = 0.0;
if( outer_radius3DU == 0.0 )
{
// Don't attempt to render degenerate shapes
}
else if( aShape->IsFilled() )
if( aShape->IsFilled() )
{
aContainer->Add( new FILLED_CIRCLE_2D( center3DU, outer_radius3DU,
*aOwner ) );
}
else
else if( outer_radius3DU > inner_radius3DU )
{
aContainer->Add( new RING_2D( center3DU, inner_radius3DU, outer_radius3DU,
*aOwner ) );
@@ -782,7 +792,7 @@ void BOARD_ADAPTER::buildPadOutlineAsSegments( const PAD* aPad, CONTAINER_2D_BAS
}
// For other shapes, add outlines as thick segments in polygon buffer
const std::shared_ptr<SHAPE_POLY_SET>& corners = aPad->GetEffectivePolygon();
const std::shared_ptr<SHAPE_POLY_SET>& corners = aPad->GetEffectivePolygon( ERROR_INSIDE );
const SHAPE_LINE_CHAIN& path = corners->COutline( 0 );
for( int j = 0; j < path.PointCount(); j++ )
+2 -1
View File
@@ -605,7 +605,8 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
case PCB_TEXTBOX_T:
addText( static_cast<PCB_TEXTBOX*>( item ), layerContainer, item );
addShape( static_cast<PCB_TEXTBOX*>( item ), layerContainer, item );
if( static_cast<PCB_TEXTBOX*>( item )->IsBorderEnabled() )
addShape( static_cast<PCB_TEXTBOX*>( item ), layerContainer, item );
break;
case PCB_DIM_ALIGNED_T:
+1 -1
View File
@@ -51,7 +51,7 @@ void BOARD_ADAPTER::buildPadOutlineAsPolygon( const PAD* aPad, SHAPE_POLY_SET& a
}
// For other shapes, add outlines as thick segments in polygon buffer
const std::shared_ptr<SHAPE_POLY_SET>& corners = aPad->GetEffectivePolygon();
const std::shared_ptr<SHAPE_POLY_SET>& corners = aPad->GetEffectivePolygon( ERROR_INSIDE );
const SHAPE_LINE_CHAIN& path = corners->COutline( 0 );
for( int ii = 0; ii < path.PointCount(); ++ii )
+14 -16
View File
@@ -483,23 +483,21 @@ void MODEL_3D::Draw( bool aTransparent, float aOpacity, bool aUseSelectedMateria
// Sort from back to front
std::sort( materialsSorted.begin(), materialsSorted.end(),
[&]( std::pair<const MODEL_3D::MATERIAL*, float>& a,
std::pair<const MODEL_3D::MATERIAL*, float>& b ) {
// If A is inside B, then A is rendered first
if( b.first->m_bbox.Inside( a.first->m_bbox ) )
{
return true;
}
else
{
if( a.first->m_bbox.Inside( b.first->m_bbox ) )
{
return false;
}
}
[&]( std::pair<const MODEL_3D::MATERIAL*, float>& a,
std::pair<const MODEL_3D::MATERIAL*, float>& b )
{
bool aInsideB = a.first->m_bbox.Inside( b.first->m_bbox );
bool bInsideA = b.first->m_bbox.Inside( a.first->m_bbox );
return a.second > b.second;
} );
// If A is inside B, then A is rendered first
if( aInsideB != bInsideA )
return bInsideA;
if( a.second != b.second )
return a.second > b.second;
return a.first > b.first; // compare pointers as a last resort
} );
for( const std::pair<const MODEL_3D::MATERIAL*, float>& mat : materialsSorted )
{
@@ -1388,10 +1388,14 @@ void RENDER_3D_OPENGL::renderTransparentModels( const glm::mat4 &aCameraViewMatr
// Sort from back to front
std::sort( transparentModelList.begin(), transparentModelList.end(),
[&]( std::pair<const MODELTORENDER *, float>& a,
std::pair<const MODELTORENDER *, float>& b ) {
return a.second > b.second;
} );
[&]( std::pair<const MODELTORENDER *, float>& a,
std::pair<const MODELTORENDER *, float>& b )
{
if( a.second != b.second )
return a.second > b.second;
return a.first > b.first; // use pointers as a last resort
} );
// Start rendering calls
glPushMatrix();
@@ -1911,9 +1911,19 @@ void RENDER_3D_RAYTRACE::initializeBlockPositions()
const SFVEC2UI center( m_realBufferSize.x / 2, m_realBufferSize.y / 2 );
std::sort( m_blockPositions.begin(), m_blockPositions.end(),
[&]( const SFVEC2UI& a, const SFVEC2UI& b ) {
[&]( const SFVEC2UI& a, const SFVEC2UI& b )
{
// Sort order: inside out.
return distance( a, center ) < distance( b, center );
float distanceA = distance( a, center );
float distanceB = distance( b, center );
if( distanceA != distanceB )
return distanceA < distanceB;
if( a[0] != b[0] )
return a[0] < b[0];
return a[1] < b[1];
} );
// Create m_shader buffer
+1 -1
View File
@@ -37,7 +37,7 @@
# KiCad.
#
# Note: This version string should follow the semantic versioning system
set( KICAD_SEMANTIC_VERSION "7.0.7" )
set( KICAD_SEMANTIC_VERSION "7.0.9" )
# Default the version to the semantic version.
# This is overridden by the git repository tag though (if using git)
+1
View File
@@ -176,6 +176,7 @@ set( COMMON_WIDGET_SRCS
widgets/footprint_preview_widget.cpp
widgets/footprint_select_widget.cpp
widgets/gal_options_panel.cpp
widgets/gal_options_panel_base.cpp
widgets/grid_bitmap_toggle.cpp
widgets/grid_color_swatch_helpers.cpp
widgets/grid_combobox.cpp
+1 -1
View File
@@ -155,7 +155,7 @@ long KIDIALOG::getStyle( KD_TYPE aType )
}
bool OverrideLock( wxWindow* aParent, const wxString& aMessage )
bool AskOverrideLock( wxWindow* aParent, const wxString& aMessage )
{
#ifdef __APPLE__
// wxMessageDialog gets the button spacing wrong on Mac so we have to use wxRichMessageDialog.
+41 -4
View File
@@ -217,7 +217,13 @@ bool DATABASE_CONNECTION::CacheTableInfo( const std::string& aTable,
nanodbc::catalog catalog( *m_conn );
nanodbc::catalog::tables tables = catalog.find_tables( fromUTF8( aTable ) );
tables.next();
if( !tables.next() )
{
wxLogTrace( traceDatabase, wxT( "CacheTableInfo: table '%s' not found in catalog" ),
aTable );
return false;
}
std::string key = toUTF8( tables.table_name() );
m_tables[key] = toUTF8( tables.table_type() );
@@ -238,7 +244,7 @@ bool DATABASE_CONNECTION::CacheTableInfo( const std::string& aTable,
catch( nanodbc::database_error& e )
{
m_lastError = e.what();
wxLogTrace( traceDatabase, wxT( "Exception while syncing columns for table %s: %s" ),
wxLogTrace( traceDatabase, wxT( "Exception while syncing columns for table '%s': %s" ),
key, m_lastError );
return false;
}
@@ -429,7 +435,22 @@ bool DATABASE_CONNECTION::SelectOne( const std::string& aTable,
for( short i = 0; i < results.columns(); ++i )
{
std::string column = toUTF8( results.column_name( i ) );
aResult[ column ] = toUTF8( results.get<nanodbc::string>( i, NANODBC_TEXT( "" ) ) );
switch( results.column_datatype( i ) )
{
case SQL_DOUBLE:
case SQL_FLOAT:
case SQL_REAL:
case SQL_DECIMAL:
case SQL_NUMERIC:
{
aResult[column] = fmt::format( "{:G}", results.get<double>( i ) );
break;
}
default:
aResult[column] = toUTF8( results.get<nanodbc::string>( i, NANODBC_TEXT( "" ) ) );
}
}
}
catch( nanodbc::database_error& e )
@@ -528,7 +549,23 @@ bool DATABASE_CONNECTION::SelectAll( const std::string& aTable, const std::strin
for( short j = 0; j < results.columns(); ++j )
{
std::string column = toUTF8( results.column_name( j ) );
result[column] = toUTF8( results.get<nanodbc::string>( j, NANODBC_TEXT( "" ) ) );
switch( results.column_datatype( j ) )
{
case SQL_DOUBLE:
case SQL_FLOAT:
case SQL_REAL:
case SQL_DECIMAL:
case SQL_NUMERIC:
{
result[column] = fmt::format( "{:G}", results.get<double>( j ) );
break;
}
default:
result[column] = toUTF8( results.get<nanodbc::string>( j,
NANODBC_TEXT( "" ) ) );
}
}
aResults.emplace_back( std::move( result ) );
+36 -1
View File
@@ -133,12 +133,41 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl
Pgm().App().SetTopWindow( (EDA_BASE_FRAME*) kiwayHolder );
#endif
Connect( wxEVT_PAINT, wxPaintEventHandler( DIALOG_SHIM::OnPaint ) );
Bind( wxEVT_PAINT, &DIALOG_SHIM::OnPaint, this );
}
DIALOG_SHIM::~DIALOG_SHIM()
{
Unbind( wxEVT_CLOSE_WINDOW, &DIALOG_SHIM::OnCloseWindow, this );
Unbind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this );
Unbind( wxEVT_PAINT, &DIALOG_SHIM::OnPaint, this );
std::function<void( wxWindowList& )> disconnectFocusHandlers = [&]( wxWindowList& children )
{
for( wxWindow* child : children )
{
if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( child ) )
{
textCtrl->Disconnect( wxEVT_SET_FOCUS,
wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ), nullptr,
this );
}
else if( wxStyledTextCtrl* scintilla = dynamic_cast<wxStyledTextCtrl*>( child ) )
{
scintilla->Disconnect( wxEVT_SET_FOCUS,
wxFocusEventHandler( DIALOG_SHIM::onChildSetFocus ), nullptr,
this );
}
else
{
disconnectFocusHandlers( child->GetChildren() );
}
}
};
disconnectFocusHandlers( GetChildren() );
// if the dialog is quasi-modal, this will end its event loop
if( IsQuasiModal() )
EndQuasiModal( wxID_CANCEL );
@@ -282,6 +311,9 @@ bool DIALOG_SHIM::Show( bool show )
ret = wxDialog::Show( show );
}
if( m_parent )
m_parent->SetFocus();
return ret;
}
@@ -483,6 +515,9 @@ int DIALOG_SHIM::ShowQuasiModal()
m_qmodal_showing = false;
if( parent )
parent->SetFocus();
return GetReturnCode();
}
+2
View File
@@ -159,6 +159,7 @@ void PANEL_COLOR_SETTINGS::OnThemeChanged( wxCommandEvent& event )
m_cbTheme->SetSelection( idx );
m_optOverrideColors->SetValue( newSettings->GetOverrideSchItemColors() );
m_optOverrideColors->Enable( !newSettings->IsReadOnly() );
*m_currentSettings = *newSettings;
updateSwatches();
@@ -174,6 +175,7 @@ void PANEL_COLOR_SETTINGS::OnThemeChanged( wxCommandEvent& event )
return;
m_optOverrideColors->SetValue( selected->GetOverrideSchItemColors() );
m_optOverrideColors->Enable( !selected->IsReadOnly() );
*m_currentSettings = *selected;
onNewThemeSelected();
+8 -6
View File
@@ -161,16 +161,18 @@ void PANEL_SETUP_SEVERITIES::ImportSettingsFrom( std::map<int, SEVERITY>& aSetti
{
int errorCode = item.GetErrorCode();
if(! m_buttonMap[ errorCode ][0] ) // this entry does not actually exist
continue;
wxRadioButton* button = nullptr;
switch( aSettings[ errorCode ] )
{
case RPT_SEVERITY_ERROR: m_buttonMap[ errorCode ][0]->SetValue( true ); break;
case RPT_SEVERITY_WARNING: m_buttonMap[ errorCode ][1]->SetValue( true ); break;
case RPT_SEVERITY_IGNORE: m_buttonMap[ errorCode ][2]->SetValue( true ); break;
default: break;
case RPT_SEVERITY_ERROR: button = m_buttonMap[ errorCode ][0]; break;
case RPT_SEVERITY_WARNING: button = m_buttonMap[ errorCode ][1]; break;
case RPT_SEVERITY_IGNORE: button = m_buttonMap[ errorCode ][2]; break;
default: break;
}
if( button ) // this entry must actually exist
button->SetValue( true );
}
if( m_pinMapSpecialCase )
+9 -3
View File
@@ -106,14 +106,22 @@ void DS_PROXY_VIEW_ITEM::ViewDraw( int aLayer, VIEW* aView ) const
buildDrawList( aView, m_properties, &drawList );
BOX2I viewport( aView->GetViewport().GetOrigin(), aView->GetViewport().GetSize() );
// Draw the title block normally even if the view is flipped
bool flipped = gal->IsFlippedX();
if( flipped )
{
int pageWidth = m_pageInfo->GetWidthMils() * m_mils2IUscalefactor;
gal->Save();
gal->Translate( VECTOR2D( m_pageInfo->GetWidthMils() * m_mils2IUscalefactor, 0 ) );
gal->Translate( VECTOR2D( pageWidth, 0 ) );
gal->Scale( VECTOR2D( -1.0, 1.0 ) );
int right = pageWidth - viewport.GetLeft();
int left = right - viewport.GetWidth();
viewport.SetOrigin( left, viewport.GetTop() );
}
DS_PAINTER ws_painter( gal );
@@ -126,8 +134,6 @@ void DS_PROXY_VIEW_ITEM::ViewDraw( int aLayer, VIEW* aView ) const
ws_settings->SetDefaultFont( settings->GetDefaultFont() );
// Draw all the components that make the drawing sheet
BOX2I viewport( aView->GetViewport().GetOrigin(), aView->GetViewport().GetSize() );
for( DS_DRAW_ITEM_BASE* item = drawList.GetFirst(); item; item = drawList.GetNext() )
{
if( viewport.Intersects( item->GetApproxBBox() ) )
+9
View File
@@ -230,6 +230,15 @@ bool EDA_DRAW_FRAME::LockFile( const wxString& aFileName )
m_file_checker = std::make_unique<LOCKFILE>( aFileName );
if( !m_file_checker->Valid() && m_file_checker->IsLockedByMe() )
{
// If we cannot acquire the lock but we appear to be the one who
// locked it, check to see if there is another KiCad instance running.
// If there is not, then we can override the lock. This could happen if
// KiCad crashed or was interrupted
if( !Pgm().SingleInstance()->IsAnotherRunning() )
m_file_checker->OverrideLock();
}
// If the file is valid, return true. This could mean that the file is
// locked or it could mean that the file is read-only
return m_file_checker->Valid();
+16 -4
View File
@@ -114,6 +114,12 @@ wxString EDA_ITEM::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
}
bool isWordChar( const wxUniChar& c )
{
return wxIsalnum( c ) || c == '_';
}
bool EDA_ITEM::Matches( const wxString& aText, const EDA_SEARCH_DATA& aSearchData ) const
{
wxString text = aText;
@@ -129,6 +135,12 @@ bool EDA_ITEM::Matches( const wxString& aText, const EDA_SEARCH_DATA& aSearchDat
searchText.MakeUpper();
}
auto isWordChar =
[]( const wxUniChar& c )
{
return wxIsalnum( c ) || c == '_';
};
if( aSearchData.matchMode == EDA_SEARCH_MATCH_MODE::WHOLEWORD )
{
int ii = 0;
@@ -143,8 +155,8 @@ bool EDA_ITEM::Matches( const wxString& aText, const EDA_SEARCH_DATA& aSearchDat
ii = next;
next += searchText.length();
bool startOK = ( ii == 0 || !wxIsalnum( text.GetChar( ii - 1 ) ) );
bool endOK = ( next == (int) text.length() || !wxIsalnum( text.GetChar( next ) ) );
bool startOK = ( ii == 0 || !isWordChar( text.GetChar( ii - 1 ) ) );
bool endOK = ( next == (int) text.length() || !isWordChar( text.GetChar( next ) ) );
if( startOK && endOK )
return true;
@@ -201,8 +213,8 @@ bool EDA_ITEM::Replace( const EDA_SEARCH_DATA& aSearchData, wxString& aText )
if( aSearchData.matchMode == EDA_SEARCH_MATCH_MODE::WHOLEWORD )
{
startOK = ( ii == 0 || !wxIsalnum( text.GetChar( ii - 1 ) ) );
endOK = ( next == (int) text.length() || !wxIsalnum( text.GetChar( next ) ) );
startOK = ( ii == 0 || !isWordChar( text.GetChar( ii - 1 ) ) );
endOK = ( next == (int) text.length() || !isWordChar( text.GetChar( next ) ) );
}
else
{
+3 -3
View File
@@ -417,11 +417,11 @@ void EDA_SHAPE::RebuildBezierToSegmentsPointsList( int aMinSegLen )
// Ensure last point respects aMinSegLen parameter
if( m_bezierPoints.size() > 2 )
{
int idx = m_bezierPoints.size()-1;
int idx = m_bezierPoints.size() - 1;
if( VECTOR2I( m_bezierPoints[idx] - m_bezierPoints[idx]-1 ).EuclideanNorm() < aMinSegLen )
if( VECTOR2I( m_bezierPoints[idx] - m_bezierPoints[idx] - 1 ).EuclideanNorm() < aMinSegLen )
{
m_bezierPoints[idx]-1 = m_bezierPoints[idx];
m_bezierPoints[idx - 1] = m_bezierPoints[idx];
m_bezierPoints.pop_back();
}
}
+11 -7
View File
@@ -881,7 +881,8 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl
std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangulate,
bool aUseTextRotation ) const
const BOX2I& aBBox,
const EDA_ANGLE& aAngle ) const
{
std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
@@ -893,16 +894,19 @@ std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( bool aTriangula
std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
if( aUseTextRotation )
if( aBBox.GetWidth() )
{
drawPos = aBBox.GetCenter();
attrs.m_Halign = GR_TEXT_H_ALIGN_CENTER;
attrs.m_Valign = GR_TEXT_V_ALIGN_CENTER;
attrs.m_Angle = aAngle;
}
else
{
attrs.m_Angle = GetDrawRotation();
if( font->IsOutline() )
cache = GetRenderCache( font, shownText, drawPos );
}
else
{
attrs.m_Angle = ANGLE_0;
cache = GetRenderCache( font, shownText, VECTOR2I() );
}
if( aTriangulate )
-5
View File
@@ -253,11 +253,6 @@ wxString FILENAME_RESOLVER::ResolvePath( const wxString& aFileName, const wxStri
// first attempt to use the name as specified:
wxString tname = aFileName;
#ifdef _WIN32
// translate from KiCad's internal UNIX-like path to MSWin paths
tname.Replace( wxT( "/" ), wxT( "\\" ) );
#endif
// Note: variable expansion must preferably be performed via a threadsafe wrapper for the
// getenv() system call. If we allow the wxFileName::Normalize() routine to perform expansion
// then we will have a race condition since wxWidgets does not assure a threadsafe wrapper
-1
View File
@@ -47,7 +47,6 @@ wxString FONTCONFIG::Version()
FONTCONFIG::FONTCONFIG()
{
(void) FcInitLoadConfigAndFonts();
};
+111 -42
View File
@@ -94,9 +94,10 @@ public:
private:
struct CACHED_BITMAP
{
GLuint id;
int w, h;
size_t size;
GLuint id;
int w, h;
size_t size;
long long int accessTime;
};
GLuint cacheBitmap( const BITMAP_BASE* aBitmap );
@@ -105,9 +106,9 @@ private:
const size_t m_cacheMaxSize = 256 * 1024 * 1024;
std::map<const KIID, CACHED_BITMAP> m_bitmaps;
std::list<KIID> m_cacheLru;
size_t m_cacheSize;
std::list<GLuint> m_freedTextureIds;
std::list<KIID> m_cacheLru;
size_t m_cacheSize;
std::list<GLuint> m_freedTextureIds;
};
}; // namespace KIGFX
@@ -130,6 +131,7 @@ GLuint GL_BITMAP_CACHE::RequestBitmap( const BITMAP_BASE* aBitmap )
// A bitmap is found in cache bitmap. Ensure the associated texture is still valid.
if( glIsTexture( it->second.id ) )
{
it->second.accessTime = wxGetUTCTimeMillis().GetValue();
return it->second.id;
}
else
@@ -182,56 +184,115 @@ GLuint GL_BITMAP_CACHE::cacheBitmap( const BITMAP_BASE* aBitmap )
m_freedTextureIds.pop_front();
}
bmp.size = bmp.w * bmp.h * 4;
auto buf = std::make_unique<uint8_t[]>( bmp.size );
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
for( int y = 0; y < bmp.h; y++ )
if( imgData.HasAlpha() || imgData.HasMask() )
{
for( int x = 0; x < bmp.w; x++ )
bmp.size = bmp.w * bmp.h * 4;
auto buf = std::make_unique<uint8_t[]>( bmp.size );
uint8_t* dstP = buf.get();
uint8_t* srcP = imgData.GetData();
long long pxCount = static_cast<long long>( bmp.w ) * bmp.h;
if( imgData.HasAlpha() )
{
uint8_t* p = buf.get() + ( bmp.w * y + x ) * 4;
uint8_t* srcAlpha = imgData.GetAlpha();
p[0] = imgData.GetRed( x, y );
p[1] = imgData.GetGreen( x, y );
p[2] = imgData.GetBlue( x, y );
for( long long px = 0; px < pxCount; px++ )
{
memcpy( dstP, srcP, 3 );
dstP[3] = *srcAlpha;
if( imgData.HasAlpha() )
p[3] = imgData.GetAlpha( x, y );
else if( imgData.HasMask() && p[0] == imgData.GetMaskRed()
&& p[1] == imgData.GetMaskGreen() && p[2] == imgData.GetMaskBlue() )
p[3] = wxALPHA_TRANSPARENT;
else
p[3] = wxALPHA_OPAQUE;
srcAlpha += 1;
srcP += 3;
dstP += 4;
}
}
}
else if( imgData.HasMask() )
{
uint8_t maskRed = imgData.GetMaskRed();
uint8_t maskGreen = imgData.GetMaskGreen();
uint8_t maskBlue = imgData.GetMaskBlue();
glBindTexture( GL_TEXTURE_2D, textureID );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.w, bmp.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
buf.get() );
for( long long px = 0; px < pxCount; px++ )
{
memcpy( dstP, srcP, 3 );
if( srcP[0] == maskRed && srcP[1] == maskGreen && srcP[2] == maskBlue )
dstP[3] = wxALPHA_TRANSPARENT;
else
dstP[3] = wxALPHA_OPAQUE;
srcP += 3;
dstP += 4;
}
}
glBindTexture( GL_TEXTURE_2D, textureID );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, bmp.w, bmp.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
buf.get() );
}
else
{
bmp.size = bmp.w * bmp.h * 3;
uint8_t* srcP = imgData.GetData();
glBindTexture( GL_TEXTURE_2D, textureID );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, bmp.w, bmp.h, 0, GL_RGB, GL_UNSIGNED_BYTE, srcP );
}
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
long long currentTime = wxGetUTCTimeMillis().GetValue();
bmp.id = textureID;
bmp.accessTime = currentTime;
#ifndef DISABLE_BITMAP_CACHE
m_cacheLru.emplace_back( aBitmap->GetImageID() );
m_cacheSize += bmp.size;
m_bitmaps.emplace( aBitmap->GetImageID(), std::move( bmp ) );
if( m_cacheLru.size() > m_cacheMaxElements
|| m_cacheSize > m_cacheMaxSize )
if( m_cacheLru.size() + 1 > m_cacheMaxElements || m_cacheSize + bmp.size > m_cacheMaxSize )
{
KIID last = m_cacheLru.front();
CACHED_BITMAP& cachedBitmap = m_bitmaps[last];
KIID toRemove( 0 );
auto toRemoveLru = m_cacheLru.end();
// Remove entries accessed > 1s ago first
for( const auto& [kiid, cachedBmp] : m_bitmaps )
{
const int cacheTimeoutMillis = 1000L;
if( currentTime - cachedBmp.accessTime > cacheTimeoutMillis )
{
toRemove = kiid;
toRemoveLru = std::find( m_cacheLru.begin(), m_cacheLru.end(), toRemove );
break;
}
}
// Otherwise, remove the latest entry (it's less likely to be needed soon)
if( toRemove == niluuid )
{
toRemoveLru = m_cacheLru.end();
toRemoveLru--;
toRemove = *toRemoveLru;
}
CACHED_BITMAP& cachedBitmap = m_bitmaps[toRemove];
m_cacheSize -= cachedBitmap.size;
glDeleteTextures( 1, &cachedBitmap.id );
m_freedTextureIds.emplace_back( cachedBitmap.id );
m_bitmaps.erase( last );
m_cacheLru.pop_front();
m_bitmaps.erase( toRemove );
m_cacheLru.erase( toRemoveLru );
}
m_cacheLru.emplace_back( aBitmap->GetImageID() );
m_cacheSize += bmp.size;
m_bitmaps.emplace( aBitmap->GetImageID(), std::move( bmp ) );
#endif
return textureID;
@@ -1111,13 +1172,21 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn
m_currentManager->Color( m_strokeColor.r, m_strokeColor.g, m_strokeColor.b,
m_strokeColor.a );
std::deque<VECTOR2D> pointList;
pointList.push_back( aStartPoint );
pointList.push_back( diagonalPointA );
pointList.push_back( aEndPoint );
pointList.push_back( diagonalPointB );
pointList.push_back( aStartPoint );
DrawPolyline( pointList );
// DrawLine (and DrawPolyline )
// has problem with 0 length lines so enforce minimum
if( aStartPoint == aEndPoint )
DrawLine( aStartPoint + VECTOR2D( 1.0, 0.0 ), aEndPoint );
else
{
std::deque<VECTOR2D> pointList;
pointList.push_back( aStartPoint );
pointList.push_back( diagonalPointA );
pointList.push_back( aEndPoint );
pointList.push_back( diagonalPointB );
pointList.push_back( aStartPoint );
DrawPolyline( pointList );
}
}
}
+72 -12
View File
@@ -38,6 +38,7 @@
#include <gestfich.h>
#include <string_utils.h>
#include <launch_ext.h>
#include "wx/tokenzr.h"
void QuoteString( wxString& string )
{
@@ -114,22 +115,78 @@ wxString FindKicadFile( const wxString& shortname )
int ExecuteFile( const wxString& aEditorName, const wxString& aFileName, wxProcess *aCallback )
{
wxString fullEditorName;
wxString param;
wxString fullEditorName;
std::vector<wxString> params;
#ifdef __UNIX__
int space = aEditorName.Find( ' ' );
wxString param;
bool inSingleQuotes = false;
bool inDoubleQuotes = false;
if( space > 0 && !aEditorName.Contains( "\"" ) && !aEditorName.Contains( "\'" ) )
auto pushParam =
[&]()
{
if( !param.IsEmpty() )
{
params.push_back( param );
param.clear();
}
};
for( wxUniChar ch : aEditorName )
{
fullEditorName = FindKicadFile( aEditorName.Mid( 0, space ) );
param = aEditorName.Mid( space + 1 );
if( inSingleQuotes )
{
if( ch == '\'' )
{
pushParam();
inSingleQuotes = false;
continue;
}
else
{
param += ch;
}
}
else if( inDoubleQuotes )
{
if( ch == '"' )
{
pushParam();
inDoubleQuotes = false;
}
else
{
param += ch;
}
}
else if( ch == '\'' )
{
pushParam();
inSingleQuotes = true;
}
else if( ch == '"' )
{
pushParam();
inDoubleQuotes = true;
}
else if( ch == ' ' )
{
pushParam();
}
else
{
param += ch;
}
}
else
pushParam();
fullEditorName = FindKicadFile( params[0] );
params.erase( params.begin() );
#else
fullEditorName = FindKicadFile( aEditorName );
#endif
{
fullEditorName = FindKicadFile( aEditorName );
}
if( wxFileExists( fullEditorName ) )
{
@@ -138,8 +195,11 @@ int ExecuteFile( const wxString& aEditorName, const wxString& aFileName, wxProce
args[i++] = fullEditorName.wc_str();
if( !param.IsEmpty() )
args[i++] = param.wc_str();
if( !params.empty() )
{
for( const wxString& p : params )
args[i++] = p.wc_str();
}
if( !aFileName.IsEmpty() )
args[i++] = aFileName.wc_str();
+5
View File
@@ -55,6 +55,11 @@ public:
bool m_plotBorderTitleBlocks;
LSET m_printMaskLayer;
// How holes in pads/vias are plotted:
// 0 = no hole, 1 = small shape, 2 = actual shape
// Not used in some plotters (Gerber)
int m_drillShapeOption;
};
#endif
+2 -2
View File
@@ -39,7 +39,7 @@ public:
m_outputFile(),
m_xOrigin( 0.0 ),
m_yOrigin( 0.0 ),
m_minDistance( 0.01 ) // 0.01 mm is a good value to connect 2 items of the board outlines
m_boardOutlinesChainingEpsilon( 0.01 ) // 0.01 mm is a good value to connect 2 items of the board outlines
{
}
@@ -53,7 +53,7 @@ public:
wxString m_outputFile;
double m_xOrigin;
double m_yOrigin;
double m_minDistance;
double m_boardOutlinesChainingEpsilon;
};
#endif
+6 -1
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -47,6 +47,11 @@ public:
int m_pageSizeMode;
LSET m_printMaskLayer;
// How holes in pads/vias are plotted:
// 0 = no hole, 1 = small shape, 2 = actual shape
// Not used in some plotters (Gerber)
int m_drillShapeOption;
};
#endif
+3
View File
@@ -32,6 +32,9 @@ wxString LayerName( int aLayer )
switch( aLayer )
{
// PCB_LAYER_ID
case UNDEFINED_LAYER: return _( "undefined" );
// Copper
case F_Cu: return wxT( "F.Cu" );
case In1_Cu: return wxT( "In1.Cu" );
case In2_Cu: return wxT( "In2.Cu" );
+123 -31
View File
@@ -127,6 +127,13 @@ LIB_TABLE::~LIB_TABLE()
}
void LIB_TABLE::Clear()
{
m_rows.clear();
m_rowsMap.clear();
}
bool LIB_TABLE::IsEmpty( bool aIncludeFallback )
{
if( !aIncludeFallback || !m_fallBack )
@@ -191,31 +198,26 @@ LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName, bool aCheckIfEnabl
do
{
cur->ensureIndex();
std::shared_lock<std::shared_mutex> lock( cur->m_mutex, std::try_to_lock );
std::shared_lock<std::shared_mutex> lock( cur->m_nickIndexMutex );
if( !cur->m_rowsMap.count( aNickName ) )
continue;
for( const std::pair<const wxString, int>& entry : cur->m_nickIndex )
{
if( entry.first == aNickName )
{
row = &cur->m_rows[entry.second];
row = &*cur->m_rowsMap.at( aNickName );
if( !aCheckIfEnabled || row->GetIsEnabled() )
return row;
}
}
if( !aCheckIfEnabled || row->GetIsEnabled() )
return row;
// Repeat, this time looking for names that were "fixed" by legacy versions because
// the old eeschema file format didn't support spaces in tokens.
for( const std::pair<const wxString, int>& entry : cur->m_nickIndex )
for( const std::pair<const wxString, LIB_TABLE_ROWS_ITER>& entry : cur->m_rowsMap )
{
wxString legacyLibName = entry.first;
legacyLibName.Replace( " ", "_" );
if( legacyLibName == aNickName )
{
row = &cur->m_rows[entry.second];
row = &*entry.second;
if( !aCheckIfEnabled || row->GetIsEnabled() )
return row;
@@ -235,9 +237,7 @@ const LIB_TABLE_ROW* LIB_TABLE::FindRowByURI( const wxString& aURI )
do
{
cur->ensureIndex();
for( unsigned i = 0; i < cur->m_rows.size(); i++ )
for( unsigned i = 0; i < cur->m_rows.size(); i++ )
{
wxString tmp = cur->m_rows[i].GetFullURI( true );
@@ -276,10 +276,10 @@ std::vector<wxString> LIB_TABLE::GetLogicalLibs()
do
{
for( LIB_TABLE_ROWS_CITER it = cur->m_rows.begin(); it!=cur->m_rows.end(); ++it )
for( const LIB_TABLE_ROW& row : cur->m_rows )
{
if( it->GetIsEnabled() )
unique.insert( it->GetNickName() );
if( row.GetIsEnabled() )
unique.insert( row.GetNickName() );
}
} while( ( cur = cur->m_fallBack ) != nullptr );
@@ -303,28 +303,120 @@ std::vector<wxString> LIB_TABLE::GetLogicalLibs()
bool LIB_TABLE::InsertRow( LIB_TABLE_ROW* aRow, bool doReplace )
{
ensureIndex();
std::lock_guard<std::shared_mutex> lock( m_mutex );
std::lock_guard<std::shared_mutex> lock( m_nickIndexMutex );
auto it = m_rowsMap.find( aRow->GetNickName() );
INDEX_CITER it = m_nickIndex.find( aRow->GetNickName() );
if( it != m_rowsMap.end() )
{
if( !doReplace )
return false;
aRow->SetParent( this );
if( it == m_nickIndex.end() )
m_rows.replace( it->second, aRow );
}
else
{
m_rows.push_back( aRow );
m_nickIndex.insert( INDEX_VALUE( aRow->GetNickName(), m_rows.size() - 1 ) );
return true;
}
if( doReplace )
aRow->SetParent( this );
reindex();
return true;
}
bool LIB_TABLE::RemoveRow( const LIB_TABLE_ROW* aRow )
{
std::lock_guard<std::shared_mutex> lock( m_mutex );
bool found = false;
auto it = m_rowsMap.find( aRow->GetNickName() );
if( it != m_rowsMap.end() )
{
m_rows.replace( it->second, aRow );
return true;
if( &*it->second == aRow )
{
found = true;
m_rows.erase( it->second );
}
}
return false;
if( !found )
{
// Bookkeeping got messed up...
for( size_t i = m_rows.size() - 1; i >= 0; --i )
{
if( &m_rows[i] == aRow )
{
m_rows.erase( m_rows.begin() + i );
found = true;
break;
}
}
}
if( found )
reindex();
return found;
}
bool LIB_TABLE::ReplaceRow( size_t aIndex, LIB_TABLE_ROW* aRow )
{
std::lock_guard<std::shared_mutex> lock( m_mutex );
if( aIndex >= m_rows.size() )
return false;
m_rowsMap.erase( m_rows[aIndex].GetNickName() );
m_rows.replace( aIndex, aRow );
reindex();
return true;
}
bool LIB_TABLE::ChangeRowOrder( size_t aIndex, int aOffset )
{
std::lock_guard<std::shared_mutex> lock( m_mutex );
if( aIndex >= m_rows.size() )
return false;
int newPos = static_cast<int>( aIndex ) + aOffset;
if( newPos < 0 || newPos > static_cast<int>( m_rows.size() ) - 1 )
return false;
auto element = m_rows.release( m_rows.begin() + aIndex );
m_rows.insert( m_rows.begin() + newPos, element.release() );
reindex();
return true;
}
void LIB_TABLE::TransferRows( LIB_TABLE_ROWS& aRowsList )
{
std::lock_guard<std::shared_mutex> lock( m_mutex );
m_rows.transfer( m_rows.end(), aRowsList.begin(), aRowsList.end(), aRowsList );
reindex();
}
void LIB_TABLE::reindex()
{
m_rowsMap.clear();
for( LIB_TABLE_ROWS_ITER it = m_rows.begin(); it != m_rows.end(); ++it )
{
it->SetParent( this );
m_rowsMap[it->GetNickName()] = it;
}
}
+21 -12
View File
@@ -90,7 +90,7 @@ void LIB_TREE_NODE::SortNodes()
std::sort( m_Children.begin(), m_Children.end(),
[]( std::unique_ptr<LIB_TREE_NODE>& a, std::unique_ptr<LIB_TREE_NODE>& b )
{
return Compare( *a, *b ) > 0;
return Compare( *a, *b );
} );
for( std::unique_ptr<LIB_TREE_NODE>& node: m_Children )
@@ -98,27 +98,38 @@ void LIB_TREE_NODE::SortNodes()
}
int LIB_TREE_NODE::Compare( LIB_TREE_NODE const& aNode1, LIB_TREE_NODE const& aNode2 )
bool LIB_TREE_NODE::Compare( LIB_TREE_NODE const& aNode1, LIB_TREE_NODE const& aNode2 )
{
if( aNode1.m_Type != aNode2.m_Type )
return 0;
return aNode1.m_Type < aNode2.m_Type;
// Recently used sorts at top
if( aNode1.m_Name.StartsWith( wxT( "-- " ) ) )
return 1;
{
if( aNode2.m_Name.StartsWith( wxT( "-- " ) ) )
{
return aNode1.m_IntrinsicRank > aNode2.m_IntrinsicRank;
}
else
{
return true;
}
}
else if( aNode2.m_Name.StartsWith( wxT( "-- " ) ) )
return 0;
{
return false;
}
// Pinned nodes go next
if( aNode1.m_Pinned && !aNode2.m_Pinned )
return 1;
return true;
else if( aNode2.m_Pinned && !aNode1.m_Pinned )
return -1;
return false;
if( aNode1.m_Parent != aNode2.m_Parent )
return 0;
if( aNode1.m_IntrinsicRank != aNode2.m_IntrinsicRank )
return aNode1.m_IntrinsicRank > aNode2.m_IntrinsicRank;
return aNode1.m_IntrinsicRank - aNode2.m_IntrinsicRank;
return reinterpret_cast<const void*>( &aNode1 ) < reinterpret_cast<const void*>( &aNode2 );
}
@@ -311,8 +322,6 @@ LIB_TREE_NODE_LIB_ID& LIB_TREE_NODE_LIB::AddItem( LIB_TREE_ITEM* aItem )
void LIB_TREE_NODE_LIB::UpdateScore( EDA_COMBINED_MATCHER& aMatcher, const wxString& aLib )
{
m_Score = 0;
// We need to score leaf nodes, which are usually (but not always) children.
if( m_Children.size() )
+29
View File
@@ -288,6 +288,24 @@ wxString PATHS::GetStockPlugins3DPath()
fn.AppendDir( wxT( "plugins" ) );
#elif defined( __WXMAC__ )
fn.Assign( wxStandardPaths::Get().GetPluginsDir(), wxEmptyString );
// This must be mapped to main bundle for everything but kicad.app
const wxArrayString dirs = fn.GetDirs();
// Check if we are the main kicad binary. in this case, the path will be
// /path/to/bundlename.app/Contents/PlugIns
// If we are an aux binary, the path will be something like
// /path/to/bundlename.app/Contents/Applications/<standalone>.app/Contents/PlugIns
if( dirs.GetCount() >= 6 &&
dirs[dirs.GetCount() - 4] == wxT( "Applications" ) &&
dirs[dirs.GetCount() - 6].Lower().EndsWith( wxT( "app" ) ) )
{
fn.RemoveLastDir();
fn.RemoveLastDir();
fn.RemoveLastDir();
fn.RemoveLastDir();
fn.AppendDir( wxT( "PlugIns" ) );
}
#else
if( wxGetEnv( wxT( "KICAD_RUN_FROM_BUILD_DIR" ), nullptr ) )
{
@@ -434,6 +452,17 @@ wxString PATHS::GetOSXKicadDataDir()
#ifdef __WXWINDOWS__
wxString PATHS::GetWindowsFontConfigDir()
{
wxFileName fn;
fn.AssignDir( getWindowsKiCadRoot() );
fn.AppendDir( wxS( "etc" ) );
fn.AppendDir( wxS( "fonts" ) );
return fn.GetPathWithSep();
}
wxString PATHS::getWindowsKiCadRoot()
{
wxFileName root( Pgm().GetExecutablePath() + wxT( "/../" ) );
+11
View File
@@ -161,6 +161,8 @@ void PGM_BASE::Destroy()
// unlike a normal destructor, this is designed to be called more than once safely:
delete m_locale;
m_locale = nullptr;
m_pgm_checker.reset();
}
@@ -443,6 +445,8 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
return false;
}
#endif
m_pgm_checker = std::make_unique<wxSingleInstanceChecker>();
m_pgm_checker->Create( pgm_name, wxStandardPaths::Get().GetTempDir() );
// Init KiCad environment
// the environment variable KICAD (if exists) gives the kicad path:
@@ -479,6 +483,13 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
SetLanguagePath();
SetDefaultLanguage( tmp );
#ifdef _MSC_VER
// We need to set this because the internal fontconfig logic
// seems to search relative to the dll rather the other logic it
// has to look for the /etc folder above the dll
wxSetEnv( "FONTCONFIG_PATH", PATHS::GetWindowsFontConfigDir() );
#endif
m_settings_manager = std::make_unique<SETTINGS_MANAGER>( aHeadless );
// Our unit test mocks break if we continue
+83 -32
View File
@@ -30,6 +30,7 @@
#include <string_utils.h>
#include <convert_basic_shapes_to_polygon.h>
#include <trigo.h>
#include <fmt/core.h>
/**
* Oblique angle for DXF native text
@@ -146,6 +147,26 @@ void DXF_PLOTTER::SetUnits( DXF_UNITS aUnit )
}
// convert aValue to a string, and remove trailing zeros
// In DXF files coordinates need a high precision: at least 9 digits when given
// in inches and 7 digits when in mm.
// So we use 16 digits and remove trailing 0 (if any)
static std::string formatCoord( double aValue )
{
std::string buf;
buf = fmt::format( "{:.16f}", aValue );
// remove trailing zeros
while( !buf.empty() && buf[buf.size() - 1] == '0' )
{
buf.pop_back();
}
return buf;
}
void DXF_PLOTTER::SetViewport( const VECTOR2I& aOffset, double aIusPerDecimil,
double aScale, bool aMirror )
{
@@ -417,11 +438,24 @@ void DXF_PLOTTER::SetColor( const COLOR4D& color )
void DXF_PLOTTER::Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T fill, int width )
{
wxASSERT( m_outputFile );
MoveTo( p1 );
LineTo( VECTOR2I( p1.x, p2.y ) );
LineTo( VECTOR2I( p2.x, p2.y ) );
LineTo( VECTOR2I( p2.x, p1.y ) );
FinishTo( VECTOR2I( p1.x, p1.y ) );
if( p1 != p2 )
{
MoveTo( p1 );
LineTo( VECTOR2I( p1.x, p2.y ) );
LineTo( VECTOR2I( p2.x, p2.y ) );
LineTo( VECTOR2I( p2.x, p1.y ) );
FinishTo( VECTOR2I( p1.x, p1.y ) );
}
else
{
// Draw as a point
wxString cname = getDXFColorName( m_currentColor );
VECTOR2D point_dev = userToDeviceCoordinates( p1 );
fprintf( m_outputFile, "0\nPOINT\n8\n%s\n10\n%g\n20\n%g\n", TO_UTF8( cname ), point_dev.x,
point_dev.y );
}
}
@@ -431,31 +465,43 @@ void DXF_PLOTTER::Circle( const VECTOR2I& centre, int diameter, FILL_T fill, int
double radius = userToDeviceSize( diameter / 2 );
VECTOR2D centre_dev = userToDeviceCoordinates( centre );
wxString cname = getDXFColorName( m_currentColor );
if( radius > 0 )
{
wxString cname = getDXFColorName( m_currentColor );
if( fill == FILL_T::NO_FILL )
{
fprintf( m_outputFile, "0\nCIRCLE\n8\n%s\n10\n%g\n20\n%g\n40\n%g\n",
fprintf( m_outputFile, "0\nCIRCLE\n8\n%s\n10\n%s\n20\n%s\n40\n%s\n",
TO_UTF8( cname ),
centre_dev.x, centre_dev.y, radius );
formatCoord( centre_dev.x ).c_str(),
formatCoord( centre_dev.y ).c_str(),
formatCoord( radius ).c_str() );
}
else if( fill == FILL_T::FILLED_SHAPE )
{
double r = radius*0.5;
double r = radius * 0.5;
fprintf( m_outputFile, "0\nPOLYLINE\n" );
fprintf( m_outputFile, "8\n%s\n66\n1\n70\n1\n", TO_UTF8( cname ) );
fprintf( m_outputFile, "40\n%g\n41\n%g\n", radius, radius);
fprintf( m_outputFile, "40\n%s\n41\n%s\n",
formatCoord( radius ).c_str(),
formatCoord( radius ).c_str() );
fprintf( m_outputFile, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname ) );
fprintf( m_outputFile, "10\n%g\n 20\n%g\n42\n1.0\n",
centre_dev.x-r, centre_dev.y );
fprintf( m_outputFile, "10\n%s\n 20\n%s\n42\n1.0\n",
formatCoord( centre_dev.x-r ).c_str(),
formatCoord( centre_dev.y ).c_str() );
fprintf( m_outputFile, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname ) );
fprintf( m_outputFile, "10\n%g\n 20\n%g\n42\n1.0\n",
centre_dev.x+r, centre_dev.y );
fprintf( m_outputFile, "10\n%s\n 20\n%s\n42\n1.0\n",
formatCoord( centre_dev.x+r ).c_str(),
formatCoord( centre_dev.y ).c_str() );
fprintf( m_outputFile, "0\nSEQEND\n");
}
}
else
{
// Draw as a point
fprintf( m_outputFile, "0\nPOINT\n8\n%s\n10\n%g\n20\n%g\n", TO_UTF8( cname ), centre_dev.x,
centre_dev.y );
}
}
@@ -578,9 +624,12 @@ void DXF_PLOTTER::PenTo( const VECTOR2I& pos, char plume )
// DXF LINE
wxString cname = getDXFColorName( m_currentColor );
const char* lname = getDXFLineType( static_cast<PLOT_DASH_TYPE>( m_currentLineType ) );
fprintf( m_outputFile, "0\nLINE\n8\n%s\n6\n%s\n10\n%g\n20\n%g\n11\n%g\n21\n%g\n",
fprintf( m_outputFile, "0\nLINE\n8\n%s\n6\n%s\n10\n%s\n20\n%s\n11\n%s\n21\n%s\n",
TO_UTF8( cname ), lname,
pen_lastpos_dev.x, pen_lastpos_dev.y, pos_dev.x, pos_dev.y );
formatCoord( pen_lastpos_dev.x ).c_str(),
formatCoord( pen_lastpos_dev.y ).c_str(),
formatCoord( pos_dev.x ).c_str(),
formatCoord( pos_dev.y ).c_str() );
}
m_penLastpos = pos;
@@ -626,8 +675,8 @@ void DXF_PLOTTER::ThickSegment( const VECTOR2I& aStart, const VECTOR2I& aEnd, in
}
void DXF_PLOTTER::Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, int aRadius, FILL_T aFill, int aWidth )
void DXF_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
{
wxASSERT( m_outputFile );
@@ -648,9 +697,11 @@ void DXF_PLOTTER::Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
// Emit a DXF ARC entity
wxString cname = getDXFColorName( m_currentColor );
fprintf( m_outputFile,
"0\nARC\n8\n%s\n10\n%g\n20\n%g\n40\n%g\n50\n%g\n51\n%g\n",
"0\nARC\n8\n%s\n10\n%s\n20\n%s\n40\n%s\n50\n%.8f\n51\n%.8f\n",
TO_UTF8( cname ),
centre_device.x, centre_device.y, radius_device,
formatCoord( centre_device.x ).c_str(),
formatCoord( centre_device.y ).c_str(),
formatCoord( radius_device ).c_str(),
startAngle.AsDegrees(), endAngle.AsDegrees() );
}
@@ -936,21 +987,21 @@ void DXF_PLOTTER::plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor
" 8\n"
"%s\n" // Layer name
" 10\n"
"%g\n" // First point X
"%s\n" // First point X
" 11\n"
"%g\n" // Second point X
"%s\n" // Second point X
" 20\n"
"%g\n" // First point Y
"%s\n" // First point Y
" 21\n"
"%g\n" // Second point Y
"%s\n" // Second point Y
" 40\n"
"%g\n" // Text height
"%s\n" // Text height
" 41\n"
"%g\n" // Width factor
"%s\n" // Width factor
" 50\n"
"%g\n" // Rotation
"%.8f\n" // Rotation
" 51\n"
"%g\n" // Oblique angle
"%.8f\n" // Oblique angle
" 71\n"
"%d\n" // Mirror flags
" 72\n"
@@ -960,9 +1011,9 @@ void DXF_PLOTTER::plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor
aAttributes.m_Bold ?
(aAttributes.m_Italic ? "KICADBI" : "KICADB")
: (aAttributes.m_Italic ? "KICADI" : "KICAD"), TO_UTF8( cname ),
origin_dev.x, origin_dev.x,
origin_dev.y, origin_dev.y,
size_dev.y, fabs( size_dev.x / size_dev.y ),
formatCoord( origin_dev.x ).c_str(), formatCoord( origin_dev.x ).c_str(),
formatCoord( origin_dev.y ).c_str(), formatCoord( origin_dev.y ).c_str(),
formatCoord( size_dev.y ).c_str(), formatCoord( fabs( size_dev.x / size_dev.y ) ).c_str(),
aAttributes.m_Angle.AsDegrees(),
aAttributes.m_Italic ? DXF_OBLIQUE_ANGLE : 0,
aAttributes.m_Mirrored ? 2 : 0, // X mirror flag
+4 -4
View File
@@ -826,8 +826,8 @@ void GERBER_PLOTTER::Circle( const VECTOR2I& aCenter, int aDiameter, FILL_T aFil
void GERBER_PLOTTER::Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, int aRadius, FILL_T aFill, int aWidth )
void GERBER_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
{
SetCurrentLineWidth( aWidth );
@@ -1149,8 +1149,8 @@ void GERBER_PLOTTER::ThickSegment( const VECTOR2I& start, const VECTOR2I& end, i
}
}
void GERBER_PLOTTER::ThickArc( const VECTOR2I& aCentre, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, int aRadius, int aWidth,
void GERBER_PLOTTER::ThickArc( const VECTOR2D& aCentre, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, double aRadius, int aWidth,
OUTLINE_MODE aTraceMode, void* aData )
{
GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
+10 -18
View File
@@ -394,22 +394,16 @@ void HPGL_PLOTTER::Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T aFill, i
VECTOR2D p1_device = userToDeviceCoordinates( p1 );
VECTOR2D p2_device = userToDeviceCoordinates( p2 );
MoveTo( p1 );
// EA command seems to always fill the rectangle, so plot as a polygon instead
std::vector<VECTOR2I> cornerList;
if( aFill == FILL_T::FILLED_SHAPE )
{
startOrAppendItem( p1_device, wxString::Format( "RA %.0f,%.0f;",
p2_device.x,
p2_device.y ) );
}
cornerList.emplace_back( p1.x, p1.y );
cornerList.emplace_back( p2.x, p1.y );
cornerList.emplace_back( p2.x, p2.y );
cornerList.emplace_back( p1.x, p2.y );
cornerList.emplace_back( p1.x, p1.y );
startOrAppendItem( p1_device, wxString::Format( "EA %.0f,%.0f;",
p2_device.x,
p2_device.y ) );
m_current_item->loc_end = m_current_item->loc_start;
m_current_item->bbox.Merge( p2_device );
PenFinish();
PlotPoly( cornerList, aFill, aWidth, nullptr );
}
@@ -435,7 +429,6 @@ void HPGL_PLOTTER::Circle( const VECTOR2I& aCenter, int aDiameter, FILL_T aFill,
chord_angle.AsDegrees(),
hpgl_end_polygon_cmd ) );
m_current_item->lift_before = true;
m_current_item->pen_returns = true;
m_current_item->bbox.Merge( BOX2D( center_dev - radius,
VECTOR2D( 2 * radius, 2 * radius ) ) );
PenFinish();
@@ -448,7 +441,6 @@ void HPGL_PLOTTER::Circle( const VECTOR2I& aCenter, int aDiameter, FILL_T aFill,
radius,
chord_angle.AsDegrees() ) );
m_current_item->lift_before = true;
m_current_item->pen_returns = true;
m_current_item->bbox.Merge( BOX2D( center_dev - radius,
VECTOR2D( 2 * radius, 2 * radius ) ) );
PenFinish();
@@ -567,8 +559,8 @@ void HPGL_PLOTTER::ThickSegment( const VECTOR2I& start, const VECTOR2I& end,
}
void HPGL_PLOTTER::Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, int aRadius, FILL_T aFill, int aWidth )
void HPGL_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
{
if( aRadius <= 0 )
return;
+36 -5
View File
@@ -217,12 +217,43 @@ void PDF_PLOTTER::SetDash( int aLineWidth, PLOT_DASH_TYPE aLineStyle )
void PDF_PLOTTER::Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T fill, int width )
{
wxASSERT( m_workFile );
SetCurrentLineWidth( width );
VECTOR2I size = p2 - p1;
if( size.x == 0 && size.y == 0 )
{
// Can't draw zero-sized rectangles
SetCurrentLineWidth( width );
MoveTo( VECTOR2I( p1.x, p1.y ) );
FinishTo( VECTOR2I( p1.x, p1.y ) );
return;
}
if( std::min( std::abs( size.x ), std::abs( size.y ) ) < width )
{
// Too thick stroked rectangles are buggy, draw as polygon
std::vector<VECTOR2I> cornerList;
cornerList.emplace_back( p1.x, p1.y );
cornerList.emplace_back( p2.x, p1.y );
cornerList.emplace_back( p2.x, p2.y );
cornerList.emplace_back( p1.x, p2.y );
cornerList.emplace_back( p1.x, p1.y );
PlotPoly( cornerList, fill, width, nullptr );
return;
}
VECTOR2D p1_dev = userToDeviceCoordinates( p1 );
VECTOR2D p2_dev = userToDeviceCoordinates( p2 );
SetCurrentLineWidth( width );
fprintf( m_workFile, "%g %g %g %g re %c\n", p1_dev.x, p1_dev.y,
p2_dev.x - p1_dev.x, p2_dev.y - p1_dev.y, fill == FILL_T::NO_FILL ? 'S' : 'B' );
fprintf( m_workFile, "%g %g %g %g re %c\n", p1_dev.x, p1_dev.y, p2_dev.x - p1_dev.x,
p2_dev.y - p1_dev.y, fill == FILL_T::NO_FILL ? 'S' : 'B' );
}
@@ -336,8 +367,8 @@ void PDF_PLOTTER::Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VE
}
void PDF_PLOTTER::Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, int aRadius, FILL_T aFill, int aWidth )
void PDF_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
{
wxASSERT( m_workFile );
+1 -1
View File
@@ -113,7 +113,7 @@ void PSLIKE_PLOTTER::FlashPadOval( const VECTOR2I& aPadPos, const VECTOR2I& aSiz
if( aTraceMode == FILLED )
ThickSegment( a + aPadPos, b + aPadPos, size.x, aTraceMode, nullptr );
else
sketchOval( aPadPos, size, orient, -1 );
sketchOval( aPadPos, size, orient, USE_DEFAULT_LINE_WIDTH );
}
+2 -2
View File
@@ -443,8 +443,8 @@ void SVG_PLOTTER::Circle( const VECTOR2I& pos, int diametre, FILL_T fill, int wi
}
void SVG_PLOTTER::Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, int aRadius, FILL_T aFill, int aWidth )
void SVG_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
{
/* Draws an arc of a circle, centered on (xc,yc), with starting point (x1, y1) and ending
* at (x2, y2). The current pen is used for the outline and the current brush for filling
+27 -9
View File
@@ -145,13 +145,31 @@ double PLOTTER::GetDashGapLenIU( int aLineWidth ) const
return userToDeviceSize( m_renderSettings->GetGapLength( aLineWidth ) );
}
#include <wx/log.h>
void PLOTTER::Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR2I& aEnd,
FILL_T aFill, int aWidth, int aMaxError )
{
EDA_ANGLE startAngle( aStart - aCenter );
EDA_ANGLE endAngle( aEnd - aCenter );
int radius = ( aStart - aCenter ).EuclideanNorm();
// Recalculate aCenter using double to be sure we will use a exact value, from aStart and aEnd
// it must be on the line passing by the middle of segment {aStart, aEnd}
// To simplify calculations, use aStart as origin in intermediate calculations
VECTOR2D center = aCenter - aStart;
VECTOR2D end = aEnd - aStart;
EDA_ANGLE segAngle( end );
// Rotate end and center, to make segment {aStart, aEnd} horizontal
RotatePoint( end, segAngle );
RotatePoint( center, segAngle );
// center.x must be at end.x/2 coordinate
center.x = end.x / 2;
// Now calculate the right center position
RotatePoint( center, -segAngle );
center += aStart;
EDA_ANGLE startAngle( VECTOR2D( aStart ) - center );
EDA_ANGLE endAngle( VECTOR2D( aEnd ) - center );
double radius = ( VECTOR2D( aStart ) - center ).EuclideanNorm();
if( startAngle > endAngle )
{
@@ -168,12 +186,12 @@ void PLOTTER::Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR
startAngle = -startAngle;
endAngle = -endAngle;
Arc( aCenter, startAngle, endAngle, radius, aFill, aWidth );
Arc( center, startAngle, endAngle, radius, aFill, aWidth );
}
void PLOTTER::Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, int aRadius, FILL_T aFill, int aWidth )
void PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, double aRadius, FILL_T aFill, int aWidth )
{
EDA_ANGLE startAngle( aStartAngle );
EDA_ANGLE endAngle( aEndAngle );
@@ -570,8 +588,8 @@ void PLOTTER::ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int widt
}
void PLOTTER::ThickArc( const VECTOR2I& centre, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, int aRadius, int aWidth,
void PLOTTER::ThickArc( const VECTOR2D& centre, const EDA_ANGLE& aStartAngle,
const EDA_ANGLE& aEndAngle, double aRadius, int aWidth,
OUTLINE_MODE aTraceMode, void* aData )
{
if( aTraceMode == FILLED )
+33
View File
@@ -569,9 +569,42 @@ bool PROJECT_FILE::SaveToFile( const wxString& aDirectory, bool aForce )
bool PROJECT_FILE::SaveAs( const wxString& aDirectory, const wxString& aFile )
{
wxFileName oldFilename( GetFilename() );
wxString oldProjectName = oldFilename.GetName();
wxString oldProjectPath = oldFilename.GetPath();
Set( "meta.filename", aFile + "." + ProjectFileExtension );
SetFilename( aFile );
auto updatePath =
[&]( wxString& aPath )
{
if( aPath.StartsWith( oldProjectName + wxS( "." ) ) )
aPath.Replace( oldProjectName, aFile, false );
else if( aPath.StartsWith( oldProjectPath + wxS( "/" ) ) )
aPath.Replace( oldProjectPath, aDirectory, false );
};
updatePath( m_BoardDrawingSheetFile );
for( int ii = LAST_PATH_FIRST; ii < (int) LAST_PATH_SIZE; ++ii )
updatePath( m_PcbLastPath[ ii ] );
auto updatePathByPtr =
[&]( const std::string& aPtr )
{
if( std::optional<wxString> path = Get<wxString>( aPtr ) )
{
updatePath( path.value() );
Set( aPtr, path.value() );
}
};
updatePathByPtr( "schematic.page_layout_descr_file" );
updatePathByPtr( "schematic.plot_directory" );
updatePathByPtr( "schematic.ngspice.workbook_filename" );
updatePathByPtr( "pcbnew.page_layout_descr_file" );
// While performing Save As, we have already checked that we can write to the directory
// so don't carry the previous flag
SetReadOnly( false );
+2 -1
View File
@@ -63,7 +63,8 @@ void RC_ITEM::SetItems( const EDA_ITEM* aItem, const EDA_ITEM* bItem,
{
m_ids.clear();
m_ids.push_back( aItem->m_Uuid );
if( aItem )
m_ids.push_back( aItem->m_Uuid );
if( bItem )
m_ids.push_back( bItem->m_Uuid );
+10 -28
View File
@@ -48,35 +48,17 @@
static int vprint( std::string* result, const char* format, va_list ap )
{
char msg[512];
// This function can call vsnprintf twice.
// But internally, vsnprintf retrieves arguments from the va_list identified by arg as if
// va_arg was used on it, and thus the state of the va_list is likely to be altered by the call.
// see: www.cplusplus.com/reference/cstdio/vsnprintf
// we make a copy of va_list ap for the second call, if happens
va_list tmp;
va_copy( tmp, ap );
size_t len = vsnprintf( nullptr, 0, format, tmp );
va_end( tmp );
size_t len = vsnprintf( msg, sizeof(msg), format, ap );
// Resize the output to hold the required data
size_t size = result->size();
result->resize( size + len );
if( len < sizeof(msg) ) // the output fit into msg
{
result->append( msg, msg + len );
}
else
{
// output was too big, so now incur the expense of allocating
// a buf for holding suffient characters.
std::vector<char> buf;
buf.reserve( len+1 ); // reserve(), not resize() which writes. +1 for trailing nul.
len = vsnprintf( &buf[0], len+1, format, tmp );
result->append( &buf[0], &buf[0] + len );
}
va_end( tmp ); // Release the temporary va_list, initialised from ap
// Now do the actual printing
len = vsnprintf( result->data() + size, len + 1, format, ap );
return len;
}
@@ -443,18 +425,18 @@ int OUTPUTFORMATTER::vprint( const char* fmt, va_list ap )
// we make a copy of va_list ap for the second call, if happens
va_list tmp;
va_copy( tmp, ap );
int ret = vsnprintf( &m_buffer[0], m_buffer.size(), fmt, ap );
int ret = vsnprintf( m_buffer.data(), m_buffer.size(), fmt, ap );
if( ret >= (int) m_buffer.size() )
{
m_buffer.resize( ret + 1000 );
ret = vsnprintf( &m_buffer[0], m_buffer.size(), fmt, tmp );
ret = vsnprintf( m_buffer.data(), m_buffer.size(), fmt, tmp );
}
va_end( tmp ); // Release the temporary va_list, initialised from ap
if( ret > 0 )
write( &m_buffer[0], ret );
write( m_buffer.data(), ret );
return ret;
}
+9
View File
@@ -32,6 +32,15 @@
using namespace STROKEPARAMS_T;
const std::map<PLOT_DASH_TYPE, struct lineTypeStruct> lineTypeNames = {
{ PLOT_DASH_TYPE::SOLID, { _( "Solid" ), BITMAPS::stroke_solid } },
{ PLOT_DASH_TYPE::DASH, { _( "Dashed" ), BITMAPS::stroke_dash } },
{ PLOT_DASH_TYPE::DOT, { _( "Dotted" ), BITMAPS::stroke_dot } },
{ PLOT_DASH_TYPE::DASHDOT, { _( "Dash-Dot" ), BITMAPS::stroke_dashdot } },
{ PLOT_DASH_TYPE::DASHDOTDOT, { _( "Dash-Dot-Dot" ), BITMAPS::stroke_dashdotdot } }
};
void STROKE_PARAMS::Stroke( const SHAPE* aShape, PLOT_DASH_TYPE aLineStyle, int aWidth,
const KIGFX::RENDER_SETTINGS* aRenderSettings,
std::function<void( const VECTOR2I& a, const VECTOR2I& b )> aStroker )
+14
View File
@@ -80,6 +80,20 @@ principle should be easily implemented by adapting the current STL containers.
%ignore to_json;
%ignore from_json;
%rename(GetEffectiveTextShapeNative) EDA_TEXT::GetEffectiveTextShape;
%extend EDA_TEXT
{
%pythoncode
%{
# KiCad 7.0 API Compatibility
def GetEffectiveTextShape(self, aTriangulate=True, aUseTextRotation=True):
return self.GetEffectiveTextShapeNative(aTriangulate)
%}
}
// headers/imports that must be included in the _wrapper.cpp at top
%{
+4
View File
@@ -59,6 +59,10 @@ ACTION_MENU::ACTION_MENU( bool isContextMenu, TOOL_INTERACTIVE* aTool ) :
ACTION_MENU::~ACTION_MENU()
{
Disconnect( wxEVT_COMMAND_MENU_SELECTED, wxMenuEventHandler( ACTION_MENU::OnMenuEvent ),
nullptr, this );
Disconnect( wxEVT_IDLE, wxIdleEventHandler( ACTION_MENU::OnIdle ), nullptr, this );
// Set parent to NULL to prevent submenus from unregistering from a nonexistent object
for( ACTION_MENU* menu : m_submenus )
menu->SetParent( nullptr );
+5
View File
@@ -697,3 +697,8 @@ const TOOL_EVENT EVENTS::InhibitSelectionEditing( TC_MESSAGE, TA_ACTION, "common
const TOOL_EVENT EVENTS::UninhibitSelectionEditing( TC_MESSAGE, TA_ACTION, "common.Interactive.uninhibit" );
const TOOL_EVENT EVENTS::DisambiguatePoint( TC_MESSAGE, TA_ACTION, "common.Interactive.disambiguate" );
// System-wide undo/redo Events
const TOOL_EVENT EVENTS::UndoRedoPreEvent( TC_MESSAGE, TA_UNDO_REDO_POST, AS_GLOBAL );
const TOOL_EVENT EVENTS::UndoRedoPostEvent( TC_MESSAGE, TA_UNDO_REDO_POST, AS_GLOBAL );
+12 -1
View File
@@ -305,9 +305,15 @@ int COMMON_TOOLS::doZoomFit( ZOOM_FIT_TYPE_T aFitType )
// Currently "Zoom to Objects" is only supported in Eeschema & Pcbnew. Support for other
// programs in the suite can be added as needed.
if( aFitType == ZOOM_FIT_ALL )
{
if( frame->IsType( FRAME_PCB_EDITOR ) )
bBox = m_frame->GetDocumentExtents( false );
}
if( aFitType == ZOOM_FIT_OBJECTS )
{
if( frame->IsType( FRAME_SCH ) || frame->IsType( FRAME_PCB_EDITOR ) )
if( frame->IsType( FRAME_SCH ) )
bBox = m_frame->GetDocumentExtents( false );
else
aFitType = ZOOM_FIT_ALL; // Just do a "Zoom to Fit" for unsupported editors
@@ -327,6 +333,7 @@ int COMMON_TOOLS::doZoomFit( ZOOM_FIT_TYPE_T aFitType )
if( !std::isfinite( scale ) )
{
view->SetCenter( VECTOR2D( 0, 0 ) );
canvas->Refresh();
return 0;
}
@@ -355,6 +362,7 @@ int COMMON_TOOLS::doZoomFit( ZOOM_FIT_TYPE_T aFitType )
view->SetScale( scale / margin_scale_factor );
view->SetCenter( bBox.Centre() );
canvas->Refresh();
return 0;
}
@@ -374,6 +382,7 @@ int COMMON_TOOLS::CenterContents( const TOOL_EVENT& aEvent )
VECTOR2D scrollbarSize = VECTOR2D( canvas->GetSize() - canvas->GetClientSize() );
VECTOR2D worldScrollbarSize = getView()->ToWorld( scrollbarSize, false );
getView()->SetCenter( getView()->GetCenter() + worldScrollbarSize / 2.0 );
canvas->Refresh();
return 0;
}
@@ -415,6 +424,8 @@ int COMMON_TOOLS::doZoomToPreset( int idx, bool aCenterOnCursor )
getView()->SetScale( scale );
}
m_frame->GetCanvas()->Refresh();
return 0;
}
+1 -1
View File
@@ -521,7 +521,7 @@ void VIEW::SetViewport( const BOX2D& aViewport )
{
VECTOR2D ssize = ToWorld( m_gal->GetScreenPixelSize(), false );
wxCHECK( ssize.x > 0 && ssize.y > 0, /*void*/ );
wxCHECK( fabs(ssize.x) > 0 && fabs(ssize.y) > 0, /*void*/ );
VECTOR2D centre = aViewport.Centre();
VECTOR2D vsize = aViewport.GetSize();
+28 -154
View File
@@ -21,17 +21,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <wx/sizer.h>
#include <wx/checkbox.h>
#include <wx/choice.h>
#include <wx/radiobox.h>
#include <wx/spinctrl.h>
#include <wx/stattext.h>
#include <wx/statbox.h>
#include <wx/statline.h>
#include <ignore.h>
#include <widgets/gal_options_panel.h>
#include <settings/app_settings.h>
#include <eda_draw_frame.h>
@@ -45,9 +34,9 @@ static const double gridThicknessMin = 1.0;
static const double gridThicknessMax = 10.0;
static const double gridThicknessStep = 0.5;
static const double gridMinSpacingMin = 5;
static const double gridMinSpacingMax = 200;
static const double gridMinSpacingStep = 5;
static const int gridMinSpacingMin = 5;
static const int gridMinSpacingMax = 200;
static const int gridMinSpacingStep = 5;
///TODO: These are duplicated in gal_display_options - Unify!
@@ -68,153 +57,35 @@ static const UTIL::CFG_MAP<KIGFX::GRID_SNAPPING> gridSnapConfigVals =
GAL_OPTIONS_PANEL::GAL_OPTIONS_PANEL( wxWindow* aParent, APP_SETTINGS_BASE* aAppSettings ) :
wxPanel( aParent, wxID_ANY ),
GAL_OPTIONS_PANEL_BASE( aParent ),
m_cfg( aAppSettings )
{
// the main sizer that holds "columns" of settings
m_mainSizer = new wxBoxSizer( wxHORIZONTAL );
SetSizer( m_mainSizer );
// second-level sizers that are one "column" of settings each
wxBoxSizer* sLeftSizer = new wxBoxSizer( wxVERTICAL );
m_mainSizer->Add( sLeftSizer, 1, wxRIGHT | wxBOTTOM | wxEXPAND, 5 );
/*
* Rendering engine
*/
#ifndef __WXMAC__
{
wxString engineChoices[] = { _( "Accelerated graphics" ), _( "Fallback graphics" ) };
m_renderingEngine = new wxRadioBox( this, wxID_ANY, _( "Rendering Engine" ),
wxDefaultPosition, wxDefaultSize,
sizeof( engineChoices ) / sizeof( wxString ),
engineChoices, 1, wxRA_SPECIFY_COLS );
m_renderingEngine->SetItemToolTip( 0, _( "Hardware-accelerated graphics (recommended)" ) );
m_renderingEngine->SetItemToolTip( 1, _( "Software graphics (for computers which do not "
"support KiCad's hardware acceleration "
"requirements)" ) );
sLeftSizer->Add( m_renderingEngine, 0, wxTOP | wxBOTTOM | wxRIGHT | wxEXPAND, 5 );
}
// Rendering engine
#ifdef __WXMAC__
// On MAC, Cairo render does not work.
m_renderingEngine->Hide();
#endif
m_renderingEngine->SetItemToolTip( 0, _( "Hardware-accelerated graphics (recommended)" ) );
m_renderingEngine->SetItemToolTip( 1, _( "Software graphics (for computers which do not "
"support KiCad's hardware acceleration "
"requirements)" ) );
/*
* Grid settings subpanel
*/
// Grid settings subpanel
int selection = 0; // default selection
for( double size = gridThicknessMin; size <= gridThicknessMax; size += gridThicknessStep )
{
wxStaticText* gridLabel = new wxStaticText( this, wxID_ANY, _( "Grid Options" ) );
sLeftSizer->Add( gridLabel, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 13 );
m_gridThicknessList.push_back( size );
m_gridLineWidth->Append( wxString::Format( wxT( "%.1f" ), size ) );
wxStaticLine* staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition,
wxDefaultSize, wxLI_HORIZONTAL );
sLeftSizer->Add( staticline1, 0, wxEXPAND|wxBOTTOM, 5 );
wxBoxSizer* sGridSettings = new wxBoxSizer( wxVERTICAL );
wxString m_gridStyleChoices[] = {
_( "Dots" ),
_( "Lines" ),
_( "Small crosses" )
};
int m_gridStyleNChoices = sizeof( m_gridStyleChoices ) / sizeof( wxString );
m_gridStyle = new wxRadioBox( this, wxID_ANY, _( "Grid Style" ), wxDefaultPosition,
wxDefaultSize, m_gridStyleNChoices, m_gridStyleChoices, 1,
wxRA_SPECIFY_COLS );
sGridSettings->Add( m_gridStyle, 0, wxALL | wxEXPAND, 5 );
wxFlexGridSizer* sGridSettingsGrid;
sGridSettingsGrid = new wxFlexGridSizer( 0, 3, 0, 0 );
sGridSettingsGrid->AddGrowableCol( 1 );
sGridSettingsGrid->SetFlexibleDirection( wxBOTH );
sGridSettingsGrid->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
l_gridLineWidth = new wxStaticText( this, wxID_ANY, _( "Grid thickness:" ) );
l_gridLineWidth->Wrap( -1 );
sGridSettingsGrid->Add( l_gridLineWidth, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP, 5 );
m_gridLineWidth = new wxSpinCtrlDouble( this, wxID_ANY );
m_gridLineWidth->SetRange( gridThicknessMin, gridThicknessMax );
m_gridLineWidth->SetIncrement( gridThicknessStep );
m_gridLineWidth->SetDigits( 1 );
sGridSettingsGrid->Add( m_gridLineWidth, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxTOP, 5 );
l_gridLineWidthUnits = new wxStaticText( this, wxID_ANY, _( "px" ) );
l_gridLineWidthUnits->Wrap( -1 );
sGridSettingsGrid->Add( l_gridLineWidthUnits, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT | wxTOP, 5 );
l_gridMinSpacing = new wxStaticText( this, wxID_ANY, _( "Min grid spacing:" ) );
l_gridMinSpacing->Wrap( -1 );
sGridSettingsGrid->Add( l_gridMinSpacing, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP, 5 );
m_gridMinSpacing = new wxSpinCtrlDouble( this, wxID_ANY);
m_gridMinSpacing->SetRange( gridMinSpacingMin, gridMinSpacingMax );
m_gridMinSpacing->SetIncrement( gridMinSpacingStep );
m_gridMinSpacing->SetDigits( 0 );
sGridSettingsGrid->Add( m_gridMinSpacing, 0, wxALIGN_CENTER_VERTICAL | wxEXPAND | wxTOP, 5 );
l_gridMinSpacingUnits = new wxStaticText( this, wxID_ANY, _( "px" ) );
l_gridMinSpacingUnits->Wrap( -1 );
sGridSettingsGrid->Add( l_gridMinSpacingUnits, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT | wxTOP, 5 );
l_gridSnapOptions = new wxStaticText( this, wxID_ANY, _( "Snap to Grid:" ) );
l_gridSnapOptions->Wrap( -1 );
sGridSettingsGrid->Add( l_gridSnapOptions, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxTOP, 5 );
wxString gridSnapChoices[] = { _( "Always" ), _( "When grid shown" ), _( "Never" ) };
int gridSnapNChoices = sizeof( gridSnapChoices ) / sizeof( wxString );
m_gridSnapOptions = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
gridSnapNChoices, gridSnapChoices );
m_gridSnapOptions->Select( 0 );
sGridSettingsGrid->Add( m_gridSnapOptions, 0,
wxALIGN_CENTER_VERTICAL | wxEXPAND | wxTOP | wxBOTTOM, 5 );
l_gridSnapSpace = new wxStaticText( this, wxID_ANY, _( "px" ) );
l_gridSnapSpace->Wrap( -1 );
l_gridSnapSpace->Hide();
sGridSettingsGrid->Add( l_gridSnapSpace, 0,
wxALIGN_CENTER_VERTICAL | wxALL | wxRESERVE_SPACE_EVEN_IF_HIDDEN,
5 );
sGridSettings->Add( sGridSettingsGrid, 1, wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5 );
sLeftSizer->Add( sGridSettings, 0, wxEXPAND|wxLEFT, 5 );
if( m_cfg->m_Window.grid.line_width == size )
selection = m_gridLineWidth->GetCount() - 1;
}
/*
* Cursor settings subpanel
*/
{
sLeftSizer->Add( 0, 15, 0, wxEXPAND, 5 );
m_gridLineWidth->SetSelection( selection );
wxStaticText* gridLabel = new wxStaticText( this, wxID_ANY, _( "Cursor Options" ) );
sLeftSizer->Add( gridLabel, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 13 );
wxStaticLine* staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition,
wxDefaultSize, wxLI_HORIZONTAL );
sLeftSizer->Add( staticline2, 0, wxEXPAND|wxBOTTOM, 5 );
wxBoxSizer* sCursorSettings = new wxBoxSizer( wxVERTICAL );
sLeftSizer->Add( sCursorSettings, 0, wxEXPAND|wxLEFT, 5 );
wxString m_CursorShapeChoices[] = {
_( "Small crosshair" ),
_( "Full window crosshair" )
};
int m_CursorShapeNChoices = sizeof( m_CursorShapeChoices ) / sizeof( wxString );
m_cursorShape = new wxRadioBox( this, wxID_ANY, _( "Cursor Shape" ), wxDefaultPosition,
wxDefaultSize, m_CursorShapeNChoices, m_CursorShapeChoices,
1, wxRA_SPECIFY_COLS );
m_cursorShape->SetSelection( 0 );
m_cursorShape->SetToolTip( _( "Cursor shape for drawing, placement and movement tools" ) );
sCursorSettings->Add( m_cursorShape, 0, wxALL | wxEXPAND, 5 );
m_forceCursorDisplay = new wxCheckBox( this, wxID_ANY, _( "Always show crosshairs" ) );
sCursorSettings->Add( m_forceCursorDisplay, 0, wxALL | wxEXPAND, 5 );
}
m_gridMinSpacing->SetRange( gridMinSpacingMin, gridMinSpacingMax );
m_gridMinSpacing->SetIncrement( gridMinSpacingStep );
}
@@ -231,7 +102,7 @@ bool GAL_OPTIONS_PANEL::TransferDataToWindow()
m_gridSnapOptions->SetSelection( m_cfg->m_Window.grid.snap );
m_gridStyle->SetSelection( m_cfg->m_Window.grid.style );
m_gridLineWidth->SetValue( m_cfg->m_Window.grid.line_width );
m_gridMinSpacing->SetValue( m_cfg->m_Window.grid.min_spacing );
m_cursorShape->SetSelection( m_cfg->m_Window.cursor.fullscreen_cursor );
@@ -245,7 +116,10 @@ bool GAL_OPTIONS_PANEL::TransferDataFromWindow()
{
m_cfg->m_Window.grid.snap = m_gridSnapOptions->GetSelection();
m_cfg->m_Window.grid.style = m_gridStyle->GetSelection();
m_cfg->m_Window.grid.line_width = m_gridLineWidth->GetValue();
if( m_gridLineWidth->GetSelection() >= 0 )
m_cfg->m_Window.grid.line_width = m_gridThicknessList[ m_gridLineWidth->GetSelection() ];
m_cfg->m_Window.grid.min_spacing = m_gridMinSpacing->GetValue();
m_cfg->m_Window.cursor.fullscreen_cursor = m_cursorShape->GetSelection();
+122
View File
@@ -0,0 +1,122 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.0-39-g3487c3cb)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "gal_options_panel_base.h"
///////////////////////////////////////////////////////////////////////////
GAL_OPTIONS_PANEL_BASE::GAL_OPTIONS_PANEL_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
{
wxBoxSizer* mainSizer;
mainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* sLeftSizer;
sLeftSizer = new wxBoxSizer( wxVERTICAL );
wxString m_renderingEngineChoices[] = { _("Accelerated graphics"), _("Fallback graphics") };
int m_renderingEngineNChoices = sizeof( m_renderingEngineChoices ) / sizeof( wxString );
m_renderingEngine = new wxRadioBox( this, wxID_ANY, _("Rendering Engine"), wxDefaultPosition, wxDefaultSize, m_renderingEngineNChoices, m_renderingEngineChoices, 1, wxRA_SPECIFY_COLS );
m_renderingEngine->SetSelection( 0 );
sLeftSizer->Add( m_renderingEngine, 0, wxALL, 5 );
mainSizer->Add( sLeftSizer, 0, wxEXPAND, 5 );
m_staticText1 = new wxStaticText( this, wxID_ANY, _("Grid Options"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText1->Wrap( -1 );
mainSizer->Add( m_staticText1, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
mainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
wxString m_gridStyleChoices[] = { _("Dots"), _("Lines"), _("Small crosses") };
int m_gridStyleNChoices = sizeof( m_gridStyleChoices ) / sizeof( wxString );
m_gridStyle = new wxRadioBox( this, wxID_ANY, _("Grid Style"), wxDefaultPosition, wxDefaultSize, m_gridStyleNChoices, m_gridStyleChoices, 1, wxRA_SPECIFY_COLS );
m_gridStyle->SetSelection( 0 );
mainSizer->Add( m_gridStyle, 0, wxALL, 5 );
wxFlexGridSizer* fgGridSettingsGrid;
fgGridSettingsGrid = new wxFlexGridSizer( 0, 3, 0, 0 );
fgGridSettingsGrid->AddGrowableCol( 1 );
fgGridSettingsGrid->SetFlexibleDirection( wxBOTH );
fgGridSettingsGrid->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
l_gridLineWidth = new wxStaticText( this, wxID_ANY, _("Grid thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
l_gridLineWidth->Wrap( -1 );
fgGridSettingsGrid->Add( l_gridLineWidth, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
wxArrayString m_gridLineWidthChoices;
m_gridLineWidth = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridLineWidthChoices, 0 );
m_gridLineWidth->SetSelection( 0 );
fgGridSettingsGrid->Add( m_gridLineWidth, 0, wxALL|wxEXPAND, 5 );
l_gridLineWidthUnits = new wxStaticText( this, wxID_ANY, _("px"), wxDefaultPosition, wxDefaultSize, 0 );
l_gridLineWidthUnits->Wrap( -1 );
fgGridSettingsGrid->Add( l_gridLineWidthUnits, 0, wxALL, 5 );
l_gridMinSpacing = new wxStaticText( this, wxID_ANY, _("Min grid spacing:"), wxDefaultPosition, wxDefaultSize, 0 );
l_gridMinSpacing->Wrap( -1 );
fgGridSettingsGrid->Add( l_gridMinSpacing, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
m_gridMinSpacing = new wxSpinCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 5, 200, 10 );
fgGridSettingsGrid->Add( m_gridMinSpacing, 0, wxALL|wxEXPAND, 5 );
l_gridMinSpacingUnits = new wxStaticText( this, wxID_ANY, _("px"), wxDefaultPosition, wxDefaultSize, 0 );
l_gridMinSpacingUnits->Wrap( -1 );
fgGridSettingsGrid->Add( l_gridMinSpacingUnits, 0, wxALL, 5 );
l_gridSnapOptions = new wxStaticText( this, wxID_ANY, _("Snap to grid:"), wxDefaultPosition, wxDefaultSize, 0 );
l_gridSnapOptions->Wrap( -1 );
fgGridSettingsGrid->Add( l_gridSnapOptions, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
wxString m_gridSnapOptionsChoices[] = { _("Always"), _("When grid shown"), _("Never") };
int m_gridSnapOptionsNChoices = sizeof( m_gridSnapOptionsChoices ) / sizeof( wxString );
m_gridSnapOptions = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_gridSnapOptionsNChoices, m_gridSnapOptionsChoices, 0 );
m_gridSnapOptions->SetSelection( 0 );
fgGridSettingsGrid->Add( m_gridSnapOptions, 0, wxALL|wxEXPAND, 5 );
fgGridSettingsGrid->Add( 0, 0, 1, wxEXPAND, 5 );
mainSizer->Add( fgGridSettingsGrid, 0, wxEXPAND, 5 );
mainSizer->Add( 0, 15, 0, 0, 5 );
m_stGridLabel = new wxStaticText( this, wxID_ANY, _("Cursor Options"), wxDefaultPosition, wxDefaultSize, 0 );
m_stGridLabel->Wrap( -1 );
mainSizer->Add( m_stGridLabel, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_staticline2 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
mainSizer->Add( m_staticline2, 0, wxEXPAND | wxALL, 5 );
wxBoxSizer* sCursorSettings;
sCursorSettings = new wxBoxSizer( wxVERTICAL );
wxString m_cursorShapeChoices[] = { _("Small crosshair"), _("Full window crosshair") };
int m_cursorShapeNChoices = sizeof( m_cursorShapeChoices ) / sizeof( wxString );
m_cursorShape = new wxRadioBox( this, wxID_ANY, _("Cursor Shape"), wxDefaultPosition, wxDefaultSize, m_cursorShapeNChoices, m_cursorShapeChoices, 1, wxRA_SPECIFY_COLS );
m_cursorShape->SetSelection( 0 );
m_cursorShape->SetToolTip( _("Cursor shape for drawing, placement and movement tools") );
sCursorSettings->Add( m_cursorShape, 0, wxALL, 5 );
m_forceCursorDisplay = new wxCheckBox( this, wxID_ANY, _("Always show crosshairs"), wxDefaultPosition, wxDefaultSize, 0 );
sCursorSettings->Add( m_forceCursorDisplay, 0, wxALL, 5 );
mainSizer->Add( sCursorSettings, 1, wxEXPAND, 5 );
this->SetSizer( mainSizer );
this->Layout();
}
GAL_OPTIONS_PANEL_BASE::~GAL_OPTIONS_PANEL_BASE()
{
}
File diff suppressed because it is too large Load Diff
+62
View File
@@ -0,0 +1,62 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.0-39-g3487c3cb)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/radiobox.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/statline.h>
#include <wx/choice.h>
#include <wx/spinctrl.h>
#include <wx/checkbox.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class GAL_OPTIONS_PANEL_BASE
///////////////////////////////////////////////////////////////////////////////
class GAL_OPTIONS_PANEL_BASE : public wxPanel
{
private:
protected:
wxRadioBox* m_renderingEngine;
wxStaticText* m_staticText1;
wxStaticLine* m_staticline1;
wxRadioBox* m_gridStyle;
wxStaticText* l_gridLineWidth;
wxChoice* m_gridLineWidth;
wxStaticText* l_gridLineWidthUnits;
wxStaticText* l_gridMinSpacing;
wxSpinCtrl* m_gridMinSpacing;
wxStaticText* l_gridMinSpacingUnits;
wxStaticText* l_gridSnapOptions;
wxChoice* m_gridSnapOptions;
wxStaticText* m_stGridLabel;
wxStaticLine* m_staticline2;
wxRadioBox* m_cursorShape;
wxCheckBox* m_forceCursorDisplay;
public:
GAL_OPTIONS_PANEL_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 387,523 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
~GAL_OPTIONS_PANEL_BASE();
};
+4 -1
View File
@@ -66,8 +66,11 @@ UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource
if( textEntry )
{
wxClientDC dc( m_valueCtrl );
// Gives enough room to display a value in inches i )n textEntry
// 4 digits + '.' + 10 digits + 2 chars (units) look enough.
wxSize minSize = m_valueCtrl->GetMinSize();
int minWidth = dc.GetTextExtent( wxT( "XXX.XXXXXXX" ) ).GetWidth();
int minWidth = dc.GetTextExtent( wxT( "XXXX.XXXXXXXXXXUU" ) ).GetWidth();
if( minSize.GetWidth() < minWidth )
m_valueCtrl->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
+219 -170
View File
@@ -55,7 +55,7 @@
* Flag to enable connectivity profiling
* @ingroup trace_env_vars
*/
static const wxChar ConnProfileMask[] = wxT( "CONN_PROFILE" );
static const wxChar DanglingProfileMask[] = wxT( "CONN_PROFILE" );
/*
* Flag to enable connectivity tracing
@@ -64,11 +64,72 @@ static const wxChar ConnProfileMask[] = wxT( "CONN_PROFILE" );
static const wxChar ConnTrace[] = wxT( "CONN" );
void CONNECTION_SUBGRAPH::RemoveItem( SCH_ITEM* aItem )
{
m_items.erase( aItem );
m_drivers.erase( aItem );
if( aItem == m_driver )
{
m_driver = nullptr;
m_driver_connection = nullptr;
}
if( aItem->Type() == SCH_SHEET_PIN_T )
m_hier_pins.erase( static_cast<SCH_SHEET_PIN*>( aItem ) );
if( aItem->Type() == SCH_HIER_LABEL_T )
m_hier_ports.erase( static_cast<SCH_HIERLABEL*>( aItem ) );
}
bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
{
PRIORITY highest_priority = PRIORITY::INVALID;
std::vector<SCH_ITEM*> candidates;
std::vector<SCH_ITEM*> strong_drivers;
auto candidate_cmp = [&]( SCH_ITEM* a, SCH_ITEM* b ) -> bool
{
// meet irreflexive requirements of std::sort
if( a == b )
return false;
SCH_CONNECTION* ac = a->Connection( &m_sheet );
SCH_CONNECTION* bc = b->Connection( &m_sheet );
// Ensure we don't pick the subset over the superset
if( ac->IsBus() && bc->IsBus() )
return bc->IsSubsetOf( ac );
// Ensure we don't pick a hidden power pin on a regular symbol over
// one on a power symbol
if( a->Type() == SCH_PIN_T && b->Type() == SCH_PIN_T )
{
SCH_PIN* pa = static_cast<SCH_PIN*>( a );
SCH_PIN* pb = static_cast<SCH_PIN*>( b );
bool aPower = pa->GetLibPin()->GetParent()->IsPower();
bool bPower = pb->GetLibPin()->GetParent()->IsPower();
if( aPower && !bPower )
return true;
else if( bPower && !aPower )
return false;
}
const wxString& a_name = GetNameForDriver( a );
const wxString& b_name = GetNameForDriver( b );
bool a_lowQualityName = a_name.Contains( "-Pad" );
bool b_lowQualityName = b_name.Contains( "-Pad" );
if( a_lowQualityName && !b_lowQualityName )
return false;
else if( b_lowQualityName && !a_lowQualityName )
return true;
else
return a_name < b_name;
};
PRIORITY highest_priority = PRIORITY::INVALID;
std::set<SCH_ITEM*, decltype( candidate_cmp )> candidates( candidate_cmp );
std::set<SCH_ITEM*> strong_drivers;
m_driver = nullptr;
@@ -88,17 +149,17 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
continue;
if( item_priority >= PRIORITY::HIER_LABEL )
strong_drivers.push_back( item );
strong_drivers.insert( item );
if( item_priority > highest_priority )
{
candidates.clear();
candidates.push_back( item );
candidates.insert( item );
highest_priority = item_priority;
}
else if( !candidates.empty() && ( item_priority == highest_priority ) )
{
candidates.push_back( item );
candidates.insert( item );
}
}
@@ -128,56 +189,10 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
}
}
}
else
{
// For all other driver types, sort by quality of name
std::sort( candidates.begin(), candidates.end(),
[&]( SCH_ITEM* a, SCH_ITEM* b ) -> bool
{
// meet irreflexive requirements of std::sort
if( a == b )
return false;
SCH_CONNECTION* ac = a->Connection( &m_sheet );
SCH_CONNECTION* bc = b->Connection( &m_sheet );
// Ensure we don't pick the subset over the superset
if( ac->IsBus() && bc->IsBus() )
return bc->IsSubsetOf( ac );
// Ensure we don't pick a hidden power pin on a regular symbol over
// one on a power symbol
if( a->Type() == SCH_PIN_T && b->Type() == SCH_PIN_T )
{
SCH_PIN* pa = static_cast<SCH_PIN*>( a );
SCH_PIN* pb = static_cast<SCH_PIN*>( b );
bool aPower = pa->GetLibPin()->GetParent()->IsPower();
bool bPower = pb->GetLibPin()->GetParent()->IsPower();
if( aPower && !bPower )
return true;
else if( bPower && !aPower )
return false;
}
const wxString& a_name = GetNameForDriver( a );
const wxString& b_name = GetNameForDriver( b );
bool a_lowQualityName = a_name.Contains( "-Pad" );
bool b_lowQualityName = b_name.Contains( "-Pad" );
if( a_lowQualityName && !b_lowQualityName )
return false;
else if( b_lowQualityName && !a_lowQualityName )
return true;
else
return a_name < b_name;
} );
}
}
if( !m_driver )
m_driver = candidates[0];
m_driver = *candidates.begin();
}
if( strong_drivers.size() > 1 )
@@ -185,7 +200,10 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
// Drop weak drivers
if( m_strong_driver )
m_drivers = strong_drivers;
{
m_drivers.clear();
m_drivers.insert( strong_drivers.begin(), strong_drivers.end() );
}
// Cache driver connection
if( m_driver )
@@ -200,30 +218,6 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCheckMultipleDrivers )
m_driver_connection = nullptr;
}
if( aCheckMultipleDrivers && m_multiple_drivers )
{
// First check if all the candidates are actually the same
bool same = true;
const wxString& first = GetNameForDriver( candidates[0] );
SCH_ITEM* second_item = nullptr;
for( unsigned i = 1; i < candidates.size(); i++ )
{
if( GetNameForDriver( candidates[i] ) != first )
{
second_item = candidates[i];
same = false;
break;
}
}
if( !same )
{
m_first_driver = m_driver;
m_second_driver = second_item;
}
}
return ( m_driver != nullptr );
}
@@ -233,9 +227,16 @@ void CONNECTION_SUBGRAPH::getAllConnectedItems( std::set<std::pair<SCH_SHEET_PAT
CONNECTION_SUBGRAPH* sg = this;
while( sg->m_absorbed_by )
{
wxASSERT( sg->m_graph == sg->m_absorbed_by->m_graph );
sg = sg->m_absorbed_by;
}
// If we are unable to insert the subgraph into the set, then we have already
// visited it and don't need to add it again.
if( aSubgraphs.insert( sg ).second == false )
return;
aSubgraphs.insert( sg );
aSubgraphs.insert( sg->m_absorbed_subgraphs.begin(), sg->m_absorbed_subgraphs.end() );
for( SCH_ITEM* item : sg->m_items )
@@ -356,9 +357,12 @@ wxString CONNECTION_SUBGRAPH::driverName( SCH_ITEM* aItem ) const
const wxString& CONNECTION_SUBGRAPH::GetNameForDriver( SCH_ITEM* aItem ) const
{
auto [it, success] = m_driver_name_cache.try_emplace( aItem, driverName( aItem ) );
auto it = m_driver_name_cache.find( aItem );
return it->second;
if( it != m_driver_name_cache.end() )
return it->second;
return m_driver_name_cache.emplace( aItem, driverName( aItem ) ).first->second;
}
@@ -426,15 +430,15 @@ void CONNECTION_SUBGRAPH::Absorb( CONNECTION_SUBGRAPH* aOther )
void CONNECTION_SUBGRAPH::AddItem( SCH_ITEM* aItem )
{
m_items.push_back( aItem );
m_items.insert( aItem );
if( aItem->Connection( &m_sheet )->IsDriver() )
m_drivers.push_back( aItem );
m_drivers.insert( aItem );
if( aItem->Type() == SCH_SHEET_PIN_T )
m_hier_pins.push_back( static_cast<SCH_SHEET_PIN*>( aItem ) );
m_hier_pins.insert( static_cast<SCH_SHEET_PIN*>( aItem ) );
else if( aItem->Type() == SCH_HIER_LABEL_T )
m_hier_ports.push_back( static_cast<SCH_HIERLABEL*>( aItem ) );
m_hier_ports.insert( static_cast<SCH_HIERLABEL*>( aItem ) );
}
@@ -506,7 +510,12 @@ void CONNECTION_GRAPH::Merge( CONNECTION_GRAPH& aGraph )
std::back_inserter( m_subgraphs ) );
for( CONNECTION_SUBGRAPH* sg : aGraph.m_subgraphs )
{
if( sg->m_driver_connection )
sg->m_driver_connection->SetGraph( this );
sg->m_graph = this;
}
std::copy( aGraph.m_driver_subgraphs.begin(),
aGraph.m_driver_subgraphs.end(),
@@ -543,6 +552,7 @@ void CONNECTION_GRAPH::Merge( CONNECTION_GRAPH& aGraph )
m_last_bus_code = std::max( m_last_bus_code, aGraph.m_last_bus_code );
m_last_net_code = std::max( m_last_net_code, aGraph.m_last_net_code );
m_last_subgraph_code = std::max( m_last_subgraph_code, aGraph.m_last_subgraph_code );
}
@@ -585,6 +595,7 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
PROF_TIMER update_items( "updateItemConnectivity" );
m_sheetList = aSheetList;
std::set<SCH_ITEM*> dirty_items;
for( const SCH_SHEET_PATH& sheet : aSheetList )
{
@@ -596,8 +607,12 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
for( SCH_ITEM* item : sheet.LastScreen()->Items() )
{
if( item->IsConnectable() && ( aUnconditional || item->IsConnectivityDirty() ) )
{
wxLogTrace( ConnTrace, wxT( "Adding item %s to connectivity graph update" ),
item->GetTypeDesc() );
items.push_back( item );
dirty_items.insert( item );
}
// Ensure the hierarchy info stored in SCREENS is built and up to date
// (multi-unit symbols)
if( item->Type() == SCH_SYMBOL_T )
@@ -629,19 +644,22 @@ void CONNECTION_GRAPH::Recalculate( const SCH_SHEET_LIST& aSheetList, bool aUnco
}
}
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
for( SCH_ITEM* item : dirty_items )
item->SetConnectivityDirty( false );
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
update_items.Show();
PROF_TIMER build_graph( "buildConnectionGraph" );
buildConnectionGraph( aChangedItemHandler );
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
build_graph.Show();
recalc_time.Stop();
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
recalc_time.Show();
}
@@ -655,11 +673,17 @@ std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> CONNECTION_GRAPH::ExtractAffected
{
// Find the primary subgraph on this sheet
while( aSubgraph->m_absorbed_by )
{
wxASSERT( aSubgraph->m_graph == aSubgraph->m_absorbed_by->m_graph );
aSubgraph = aSubgraph->m_absorbed_by;
}
// Find the top most connected subgraph on all sheets
while( aSubgraph->m_hier_parent )
{
wxASSERT( aSubgraph->m_graph == aSubgraph->m_hier_parent->m_graph );
aSubgraph = aSubgraph->m_hier_parent;
}
// Recurse through all subsheets to collect connected items
aSubgraph->getAllConnectedItems( retvals, subgraphs );
@@ -751,23 +775,23 @@ void CONNECTION_GRAPH::removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgrap
{
auto it = std::lower_bound( m_driver_subgraphs.begin(), m_driver_subgraphs.end(), sg );
if( it != m_driver_subgraphs.end() )
m_driver_subgraphs.erase( it );
while( it != m_driver_subgraphs.end() && *it == sg )
it = m_driver_subgraphs.erase( it );
}
{
auto it = std::lower_bound( m_subgraphs.begin(), m_subgraphs.end(), sg );
if( it != m_subgraphs.end() )
m_subgraphs.erase( it );
while( it != m_subgraphs.end() && *it == sg )
it = m_subgraphs.erase( it );
}
for( auto el : m_sheet_to_subgraphs_map )
{
auto it = std::lower_bound( el.second.begin(), el.second.end(), sg );
if( it != el.second.end() )
el.second.erase( it );
while( it != el.second.end() && *it == sg )
it = el.second.erase( it );
}
auto remove_sg = [sg]( auto it ) -> bool
@@ -844,6 +868,7 @@ void CONNECTION_GRAPH::removeSubgraphs( std::set<CONNECTION_SUBGRAPH*>& aSubgrap
for( CONNECTION_SUBGRAPH* sg : aSubgraphs )
{
sg->m_code = -1;
sg->m_graph = nullptr;
delete sg;
}
}
@@ -931,8 +956,6 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
for( const VECTOR2I& point : points )
connection_map[ point ].push_back( item );
}
item->SetConnectivityDirty( false );
}
for( const auto& it : connection_map )
@@ -1319,11 +1342,15 @@ void CONNECTION_GRAPH::generateBusAliasMembers()
wxString name = conn->FullLocalName();
CONNECTION_SUBGRAPH* new_sg = new CONNECTION_SUBGRAPH( this );
// This connection cannot form a part of the item because the item is not, itself
// connected to this subgraph. It exists as part of a virtual item that may be connected
// to other items but is not in the schematic.
SCH_CONNECTION* new_conn = new SCH_CONNECTION( item, subgraph->m_sheet );
new_conn->SetGraph( this );
new_conn->SetName( name );
new_conn->SetType( CONNECTION_TYPE::NET );
subgraph->StoreImplicitConnection( new_conn );
int code = assignNewNetCode( *new_conn );
wxLogTrace( ConnTrace, wxS( "SG(%ld), Adding full local name (%s) with sg (%d) on subsheet %s" ), subgraph->m_code,
@@ -1637,10 +1664,16 @@ void CONNECTION_GRAPH::processSubGraphs()
// by the chosen driver of the subgraph, so we need to create a dummy connection
add_connections_to_check( subgraph );
std::set<SCH_CONNECTION*> checked_connections;
for( unsigned i = 0; i < connections_to_check.size(); i++ )
{
auto member = connections_to_check[i];
// Don't check the same connection twice
if( !checked_connections.insert( member.get() ).second )
continue;
if( member->IsBus() )
{
connections_to_check.insert( connections_to_check.end(),
@@ -1776,7 +1809,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
PROF_TIMER sub_graph( "buildItemSubGraphs" );
buildItemSubGraphs();
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
sub_graph.Show();
@@ -1796,7 +1829,7 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
PROF_TIMER proc_sub_graph( "ProcessSubGraphs" );
processSubGraphs();
if( wxLog::IsAllowedTraceMask( ConnProfileMask ) )
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
proc_sub_graph.Show();
// Absorbed subgraphs should no longer be considered
@@ -2180,47 +2213,96 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
std::unordered_set<CONNECTION_SUBGRAPH*> visited;
std::unordered_set<SCH_CONNECTION*> stale_bus_members;
auto visit =
[&]( CONNECTION_SUBGRAPH* aParent )
auto visit =[&]( CONNECTION_SUBGRAPH* aParent )
{
for( SCH_SHEET_PIN* pin : aParent->m_hier_pins )
{
SCH_SHEET_PATH path = aParent->m_sheet;
path.push_back( pin->GetParent() );
auto it = m_sheet_to_subgraphs_map.find( path );
if( it == m_sheet_to_subgraphs_map.end() )
continue;
for( CONNECTION_SUBGRAPH* candidate : it->second )
{
for( SCH_SHEET_PIN* pin : aParent->m_hier_pins )
if( !candidate->m_strong_driver
|| candidate->m_hier_ports.empty()
|| visited.count( candidate ) )
{
SCH_SHEET_PATH path = aParent->m_sheet;
path.push_back( pin->GetParent() );
continue;
}
auto it = m_sheet_to_subgraphs_map.find( path );
if( it == m_sheet_to_subgraphs_map.end() )
continue;
for( CONNECTION_SUBGRAPH* candidate : it->second )
for( SCH_HIERLABEL* label : candidate->m_hier_ports )
{
if( candidate->GetNameForDriver( label ) == aParent->GetNameForDriver( pin ) )
{
if( !candidate->m_strong_driver
|| candidate->m_hier_ports.empty()
|| visited.count( candidate ) )
{
continue;
}
wxLogTrace( ConnTrace, wxS( "%lu: found child %lu (%s)" ), aParent->m_code,
candidate->m_code, candidate->m_driver_connection->Name() );
for( SCH_HIERLABEL* label : candidate->m_hier_ports )
{
if( candidate->GetNameForDriver( label ) == aParent->GetNameForDriver( pin ) )
{
wxLogTrace( ConnTrace, wxS( "%lu: found child %lu (%s)" ), aParent->m_code,
candidate->m_code, candidate->m_driver_connection->Name() );
candidate->m_hier_parent = aParent;
aParent->m_hier_children.insert( candidate );
candidate->m_hier_parent = aParent;
aParent->m_hier_children.insert( candidate );
wxASSERT( candidate->m_graph == aParent->m_graph );
search_list.push_back( candidate );
break;
}
}
search_list.push_back( candidate );
break;
}
}
};
}
}
auto propagate_bus_neighbors = [&]( CONNECTION_SUBGRAPH* aParentGraph ) {
for( SCH_HIERLABEL* label : aParent->m_hier_ports )
{
SCH_SHEET_PATH path = aParent->m_sheet;
path.pop_back();
auto it = m_sheet_to_subgraphs_map.find( path );
if( it == m_sheet_to_subgraphs_map.end() )
continue;
for( CONNECTION_SUBGRAPH* candidate : it->second )
{
if( candidate->m_hier_pins.empty()
|| visited.count( candidate )
|| candidate->m_driver_connection->Type() != aParent->m_driver_connection->Type() )
{
continue;
}
const KIID& last_parent_uuid = aParent->m_sheet.Last()->m_Uuid;
for( SCH_SHEET_PIN* pin : candidate->m_hier_pins )
{
// If the last sheet UUIDs won't match, no need to check the full path
if( pin->GetParent()->m_Uuid != last_parent_uuid )
continue;
SCH_SHEET_PATH pin_path = path;
pin_path.push_back( pin->GetParent() );
if( pin_path != aParent->m_sheet )
continue;
if( aParent->GetNameForDriver( label ) == candidate->GetNameForDriver( pin ) )
{
wxLogTrace( ConnTrace, wxS( "%lu: found additional parent %lu (%s)" ),
aParent->m_code, candidate->m_code,
candidate->m_driver_connection->Name() );
aParent->m_hier_children.insert( candidate );
search_list.push_back( candidate );
break;
}
}
}
}
};
auto propagate_bus_neighbors = [&]( CONNECTION_SUBGRAPH* aParentGraph )
{
for( const auto& kv : aParentGraph->m_bus_neighbors )
{
for( CONNECTION_SUBGRAPH* neighbor : kv.second )
@@ -2338,9 +2420,8 @@ void CONNECTION_GRAPH::propagateToNeighbors( CONNECTION_SUBGRAPH* aSubgraph, boo
{
auto child = search_list[i];
visited.insert( child );
visit( child );
if( visited.insert( child ).second )
visit( child );
child->m_dirty = false;
}
@@ -2793,38 +2874,7 @@ int CONNECTION_GRAPH::RunERC()
bool CONNECTION_GRAPH::ercCheckMultipleDrivers( const CONNECTION_SUBGRAPH* aSubgraph )
{
wxCHECK( aSubgraph, false );
/*
* This was changed late in 6.0 to fix https://gitlab.com/kicad/code/kicad/-/issues/9367
* so I'm going to leave the original code in for just a little while. If anyone comes
* across this in 7.0 development (or later), feel free to delete.
*/
#if 0
if( aSubgraph->m_second_driver )
{
SCH_ITEM* primary = aSubgraph->m_first_driver;
SCH_ITEM* secondary = aSubgraph->m_second_driver;
wxPoint pos = primary->Type() == SCH_PIN_T ?
static_cast<SCH_PIN*>( primary )->GetTransformedPosition() :
primary->GetPosition();
const wxString& primaryName = aSubgraph->GetNameForDriver( primary );
const wxString& secondaryName = aSubgraph->GetNameForDriver( secondary );
wxString msg = wxString::Format( _( "Both %s and %s are attached to the same "
"items; %s will be used in the netlist" ),
primaryName, secondaryName, primaryName );
std::shared_ptr<ERC_ITEM> ercItem = ERC_ITEM::Create( ERCE_DRIVER_CONFLICT );
ercItem->SetItems( primary, secondary );
ercItem->SetErrorMessage( msg );
SCH_MARKER* marker = new SCH_MARKER( ercItem, pos );
aSubgraph->m_sheet.LastScreen()->Append( marker );
return false;
}
#else
if( aSubgraph->m_multiple_drivers )
{
for( SCH_ITEM* driver : aSubgraph->m_drivers )
@@ -2859,7 +2909,6 @@ bool CONNECTION_GRAPH::ercCheckMultipleDrivers( const CONNECTION_SUBGRAPH* aSubg
}
}
}
#endif
return true;
}
@@ -3077,7 +3126,7 @@ bool CONNECTION_GRAPH::ercCheckBusToBusEntryConflicts( const CONNECTION_SUBGRAPH
bus_name = bus_wire->Connection( &sheet )->Name();
std::set<wxString> test_names;
test_names.insert( bus_entry->Connection( &sheet )->Name() );
test_names.insert( bus_entry->Connection( &sheet )->FullLocalName() );
wxString baseName = sheet.PathHumanReadable();
@@ -3090,11 +3139,11 @@ bool CONNECTION_GRAPH::ercCheckBusToBusEntryConflicts( const CONNECTION_SUBGRAPH
{
for( const auto& sub_member : member->Members() )
{
if( test_names.count( sub_member->Name() ) )
if( test_names.count( sub_member->FullLocalName() ) )
conflict = false;
}
}
else if( test_names.count( member->Name() ) )
else if( test_names.count( member->FullLocalName() ) )
{
conflict = false;
}
+23 -16
View File
@@ -86,12 +86,14 @@ public:
m_bus_entry( nullptr ),
m_driver( nullptr ),
m_driver_connection( nullptr ),
m_hier_parent( nullptr ),
m_first_driver( nullptr ),
m_second_driver( nullptr )
m_hier_parent( nullptr )
{}
~CONNECTION_SUBGRAPH() = default;
~CONNECTION_SUBGRAPH()
{
for( SCH_CONNECTION* connection : m_bus_element_connections )
delete connection;
}
/**
* Determines which potential driver should drive the subgraph.
@@ -130,7 +132,7 @@ public:
void UpdateItemConnections();
/// Provides a read-only reference to the items in the subgraph
const std::vector<SCH_ITEM*>& GetItems() const
const std::set<SCH_ITEM*>& GetItems() const
{
return m_items;
}
@@ -162,6 +164,15 @@ public:
return PRIORITY::NONE;
}
void RemoveItem( SCH_ITEM* aItem );
// Use this to keep a connection pointer that is not owned by any item
// This will be destroyed with the subgraph
void StoreImplicitConnection( SCH_CONNECTION* aConnection )
{
m_bus_element_connections.insert( aConnection );
}
private:
wxString driverName( SCH_ITEM* aItem ) const;
@@ -206,9 +217,9 @@ public:
/// Bus entry in graph, if any
SCH_ITEM* m_bus_entry;
std::vector<SCH_ITEM*> m_items;
std::set<SCH_ITEM*> m_items;
std::vector<SCH_ITEM*> m_drivers;
std::set<SCH_ITEM*> m_drivers;
SCH_ITEM* m_driver;
@@ -237,10 +248,10 @@ public:
std::unordered_set<CONNECTION_SUBGRAPH*> > m_bus_parents;
// Cache for lookup of any hierarchical (sheet) pins on this subgraph (for referring down)
std::vector<SCH_SHEET_PIN*> m_hier_pins;
std::set<SCH_SHEET_PIN*> m_hier_pins;
// Cache for lookup of any hierarchical ports on this subgraph (for referring up)
std::vector<SCH_HIERLABEL*> m_hier_ports;
std::set<SCH_HIERLABEL*> m_hier_ports;
// If not null, this indicates the subgraph on a higher level sheet that is linked to this one
CONNECTION_SUBGRAPH* m_hier_parent;
@@ -251,14 +262,10 @@ public:
/// A cache of escaped netnames from schematic items
mutable std::unordered_map<SCH_ITEM*, wxString> m_driver_name_cache;
/**
* Stores the primary driver for the multiple drivers ERC check. This is the chosen driver
* before subgraphs are absorbed (so m_driver may be different)
*/
SCH_ITEM* m_first_driver;
/// A cache of connections that are part of this subgraph but that don't have
/// an owning element (i.e. bus members)
std::set<SCH_CONNECTION*> m_bus_element_connections;
/// Used for multiple drivers ERC message; stores the second possible driver (or nullptr)
SCH_ITEM* m_second_driver;
};
struct NET_NAME_CODE_CACHE_KEY
-3
View File
@@ -226,8 +226,6 @@ void DIALOG_ANNOTATE::OnApplyClick( wxCommandEvent& event )
m_Parent->GetCanvas()->Refresh();
m_btnClear->Enable();
m_sdbSizer1Cancel->SetDefault();
// Don't close dialog if there are things the user needs to address
@@ -248,7 +246,6 @@ void DIALOG_ANNOTATE::OnClearAnnotationClick( wxCommandEvent& event )
bool appendUndo = false;
m_Parent->DeleteAnnotation( GetScope(), GetRecursive(), &appendUndo );
m_btnClear->Enable( false );
}
@@ -34,6 +34,7 @@
#include <schematic.h>
#include <template_fieldnames.h>
#include <widgets/wx_html_report_panel.h>
#include <widgets/std_bitmap_button.h>
bool g_selectRefDes = false;
bool g_selectValue = false;
@@ -702,6 +703,10 @@ int DIALOG_CHANGE_SYMBOLS::processSymbols( const std::map<SCH_SYMBOL*,
symbol->SetSchSymbolLibraryName( wxEmptyString );
screen->Append( symbol );
if( resetPositions )
symbol->AutoAutoplaceFields( screen );
frame->GetCanvas()->GetView()->Update( symbol );
msg = getSymbolReferences( *symbol, symbol_change_info.m_LibId );
@@ -720,8 +725,18 @@ wxString DIALOG_CHANGE_SYMBOLS::getSymbolReferences( SCH_SYMBOL& aSymbol, const
wxString references;
LIB_ID oldId = aSymbol.GetLibId();
SCH_EDIT_FRAME* parent = dynamic_cast< SCH_EDIT_FRAME* >( GetParent() );
wxCHECK( parent, msg );
SCH_SHEET_LIST sheets = parent->Schematic().GetSheets();
for( const SCH_SYMBOL_INSTANCE& instance : aSymbol.GetInstanceReferences() )
{
// Only include the symbol instances for the current project.
if( !sheets.HasPath( instance.m_Path ) )
continue;
if( references.IsEmpty() )
references = instance.m_Reference;
else
@@ -5,6 +5,7 @@
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/std_bitmap_button.h"
#include "widgets/wx_html_report_panel.h"
#include "dialog_change_symbols_base.h"
@@ -20,7 +21,7 @@ DIALOG_CHANGE_SYMBOLS_BASE::DIALOG_CHANGE_SYMBOLS_BASE( wxWindow* parent, wxWind
wxBoxSizer* matchSizerMargins;
matchSizerMargins = new wxBoxSizer( wxVERTICAL );
m_matchSizer = new wxGridBagSizer( 3, 5 );
m_matchSizer = new wxGridBagSizer( 3, 0 );
m_matchSizer->SetFlexibleDirection( wxBOTH );
m_matchSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
@@ -48,7 +49,7 @@ DIALOG_CHANGE_SYMBOLS_BASE::DIALOG_CHANGE_SYMBOLS_BASE( wxWindow* parent, wxWind
m_specifiedId = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
m_matchSizer->Add( m_specifiedId, wxGBPosition( 5, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_matchIdBrowserButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_matchIdBrowserButton = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_matchSizer->Add( m_matchIdBrowserButton, wxGBPosition( 5, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 3 );
@@ -77,9 +78,9 @@ DIALOG_CHANGE_SYMBOLS_BASE::DIALOG_CHANGE_SYMBOLS_BASE( wxWindow* parent, wxWind
bSizer1 = new wxBoxSizer( wxHORIZONTAL );
m_newId = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
bSizer1->Add( m_newId, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizer1->Add( m_newId, 1, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 );
m_newIdBrowserButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_newIdBrowserButton = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizer1->Add( m_newIdBrowserButton, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT, 5 );
@@ -79,7 +79,7 @@
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">1</property>
<property name="growablerows">1</property>
<property name="hgap">5</property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">m_matchSizer</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
@@ -694,7 +694,7 @@
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
@@ -860,7 +860,7 @@
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxTextCtrl" expanded="1">
<property name="BottomDockable">1</property>
@@ -984,7 +984,7 @@
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
@@ -10,6 +10,7 @@
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class STD_BITMAP_BUTTON;
class WX_HTML_REPORT_PANEL;
#include "dialog_shim.h"
@@ -56,11 +57,11 @@ class DIALOG_CHANGE_SYMBOLS_BASE : public DIALOG_SHIM
wxTextCtrl* m_specifiedValue;
wxRadioButton* m_matchById;
wxTextCtrl* m_specifiedId;
wxBitmapButton* m_matchIdBrowserButton;
STD_BITMAP_BUTTON* m_matchIdBrowserButton;
wxStaticLine* m_staticline1;
wxBoxSizer* m_newIdSizer;
wxTextCtrl* m_newId;
wxBitmapButton* m_newIdBrowserButton;
STD_BITMAP_BUTTON* m_newIdBrowserButton;
wxStaticBoxSizer* m_updateFieldsSizer;
wxCheckListBox* m_fieldsBox;
wxButton* m_selAllBtn;
+5 -1
View File
@@ -482,7 +482,11 @@ void DIALOG_CHOOSE_SYMBOL::PopulateFootprintSelector( LIB_ID const& aLibId )
LIB_FIELD* fp_field = symbol->GetFieldById( FOOTPRINT_FIELD );
wxString fp_name = fp_field ? fp_field->GetFullText() : wxString( "" );
symbol->GetPins( temp_pins );
// All units, but only a single De Morgan variant.
if( symbol->HasConversion() )
symbol->GetPins( temp_pins, 0, 1 );
else
symbol->GetPins( temp_pins );
m_fp_sel_ctrl->FilterByPinCount( temp_pins.size() );
m_fp_sel_ctrl->FilterByFootprintFilters( symbol->GetFPFilters(), true );
+1 -1
View File
@@ -667,7 +667,7 @@ void DIALOG_SCH_FIELD_PROPERTIES::UpdateField( SCH_FIELD* aField, SCH_SHEET_PATH
}
else if( parent && parent->Type() == SCH_GLOBAL_LABEL_T )
{
if( fieldType == 0 )
if( aField->GetCanonicalName() == wxT( "Intersheetrefs" ) )
{
if( m_visible->GetValue() != parent->Schematic()->Settings().m_IntersheetRefsShow )
{
@@ -592,6 +592,7 @@ void DIALOG_LIB_SYMBOL_PROPERTIES::OnDeleteField( wxCommandEvent& event )
}
m_grid->CommitPendingChanges( true /* quiet mode */ );
m_grid->ClearSelection();
// Reverse sort so deleting a row doesn't change the indexes of the other rows.
selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015-2022 KiCad Developers, see AUTHORS.TXT for contributors.
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -324,7 +324,69 @@ bool DIALOG_PRINT_USING_PRINTER::TransferDataFromWindow()
int sheet_count = m_parent->Schematic().Root().CountSheets();
wxPrintDialogData printDialogData( m_parent->GetPageSetupData().GetPrintData() );
wxPrintData data = m_parent->GetPageSetupData().GetPrintData();
#if defined( __WXGTK__ ) && !wxCHECK_VERSION( 3, 2, 3 )
// In GTK, the default bottom margin is bigger by 0.31 inches for
// Letter, Legal, A4 paper sizes (see gtk_paper_size_get_default_bottom_margin).
//
// wxWidgets doesn't handle this properly when paper is in
// landscape orientation.
//
// Using custom page size avoids the problematic
// gtk_page_setup_set_paper_size_and_default_margins call in wxWidgets.
wxPaperSize paperId = data.GetPaperId();
const wxChar* paperType = nullptr;
// clang-format off
std::set<wxPaperSize> letterSizes = {
// na_letter
wxPAPER_LETTER,
wxPAPER_LETTERSMALL,
wxPAPER_NOTE,
wxPAPER_LETTER_TRANSVERSE,
wxPAPER_LETTER_ROTATED
};
std::set<wxPaperSize> legalSizes = {
// na_legal
wxPAPER_LEGAL
};
std::set<wxPaperSize> a4Sizes = {
// iso_a4
wxPAPER_A4,
wxPAPER_A4SMALL,
wxPAPER_A4_TRANSVERSE,
wxPAPER_A4_ROTATED
};
// clang-format on
if( letterSizes.count( paperId ) )
paperType = PAGE_INFO::USLetter;
else if( legalSizes.count( paperId ) )
paperType = PAGE_INFO::USLegal;
else if( a4Sizes.count( paperId ) )
paperType = PAGE_INFO::A4;
if( paperType )
{
PAGE_INFO pageInfo( paperType, data.GetOrientation() == wxPORTRAIT );
if( pageInfo.IsPortrait() )
data.SetPaperSize( wxSize( EDA_UNIT_UTILS::Mils2mm( pageInfo.GetWidthMils() ),
EDA_UNIT_UTILS::Mils2mm( pageInfo.GetHeightMils() ) ) );
else
data.SetPaperSize( wxSize( EDA_UNIT_UTILS::Mils2mm( pageInfo.GetHeightMils() ),
EDA_UNIT_UTILS::Mils2mm( pageInfo.GetWidthMils() ) ) );
data.SetOrientation( pageInfo.GetWxOrientation() );
data.SetPaperId( wxPAPER_NONE );
}
#endif
wxPrintDialogData printDialogData( data );
printDialogData.SetMaxPage( sheet_count );
if( sheet_count > 1 )
@@ -67,6 +67,8 @@ DIALOG_SCHEMATIC_SETUP::DIALOG_SCHEMATIC_SETUP( SCH_EDIT_FRAME* aFrame ) :
}, _( "Field Name Templates" ) );
m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Electrical Rules" ) );
m_severitiesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
{
+2 -3
View File
@@ -208,9 +208,8 @@ bool DIALOG_SHEET_PROPERTIES::Validate()
for( size_t i = SHEET_MANDATORY_FIELDS; i < m_fields->size(); ++i )
{
SCH_FIELD& field = m_fields->at( i );
wxString fieldName = field.GetName( false );
if( fieldName.IsEmpty() )
if( field.GetName( false ).empty() && !field.GetText().empty() )
{
DisplayErrorMessage( this, _( "Fields must have a name." ) );
@@ -367,7 +366,7 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
SCH_FIELD& field = m_fields->at( ii );
const wxString& fieldName = field.GetCanonicalName();
if( fieldName.IsEmpty() && field.GetText().IsEmpty() )
if( field.IsEmpty() )
m_fields->erase( m_fields->begin() + ii );
else if( fieldName.IsEmpty() )
field.SetName( _( "untitled" ) );
+22 -15
View File
@@ -49,19 +49,20 @@ using CATEGORY = SIM_MODEL::PARAM::CATEGORY;
template <typename T_symbol, typename T_field>
DIALOG_SIM_MODEL<T_symbol, T_field>::DIALOG_SIM_MODEL( wxWindow* aParent, T_symbol& aSymbol,
std::vector<T_field>& aFields )
: DIALOG_SIM_MODEL_BASE( aParent ),
m_symbol( aSymbol ),
m_fields( aFields ),
m_libraryModelsMgr( &Prj() ),
m_builtinModelsMgr( &Prj() ),
m_prevModel( nullptr ),
m_curModelType( SIM_MODEL::TYPE::NONE ),
m_scintillaTricks( nullptr ),
m_firstCategory( nullptr ),
m_prevParamGridSelection( nullptr ),
m_lastParamGridWidth( 0 ),
m_inKillFocus( false )
std::vector<T_field>& aFields ) :\
DIALOG_SIM_MODEL_BASE( aParent ),
m_symbol( aSymbol ),
m_fields( aFields ),
m_libraryModelsMgr( &Prj() ),
m_builtinModelsMgr( &Prj() ),
m_prevModel( nullptr ),
m_curModelType( SIM_MODEL::TYPE::NONE ),
m_scintillaTricksCode( nullptr ),
m_scintillaTricksSubckt( nullptr ),
m_firstCategory( nullptr ),
m_prevParamGridSelection( nullptr ),
m_lastParamGridWidth( 0 ),
m_inKillFocus( false )
{
m_browseButton->SetBitmap( KiBitmap( BITMAPS::small_folder ) );
@@ -81,7 +82,8 @@ DIALOG_SIM_MODEL<T_symbol, T_field>::DIALOG_SIM_MODEL( wxWindow* aParent, T_symb
m_typeChoice->Clear();
m_scintillaTricks = new SCINTILLA_TRICKS( m_codePreview, wxT( "{}" ), false );
m_scintillaTricksCode = new SCINTILLA_TRICKS( m_codePreview, wxT( "{}" ), false );
m_scintillaTricksSubckt = new SCINTILLA_TRICKS( m_subckt, wxT( "()" ), false );
m_paramGridMgr->Bind( wxEVT_PG_SELECTED, &DIALOG_SIM_MODEL::onParamGridSelectionChange, this );
@@ -131,7 +133,8 @@ DIALOG_SIM_MODEL<T_symbol, T_field>::~DIALOG_SIM_MODEL()
// Delete the GRID_TRICKS.
m_pinAssignmentsGrid->PopEventHandler( true );
delete m_scintillaTricks;
delete m_scintillaTricksCode;
delete m_scintillaTricksSubckt;
}
@@ -185,6 +188,9 @@ bool DIALOG_SIM_MODEL<T_symbol, T_field>::TransferDataToWindow()
{
m_libraryPathText->ChangeValue( libraryFilename );
m_curModelType = SIM_MODEL::ReadTypeFromFields( m_fields, &reporter );
// load library will mangle the set reporter
m_libraryModelsMgr.SetReporter( &reporter );
m_libraryModelsMgr.CreateModel( nullptr, m_sortedPartPins, m_fields );
m_modelNameChoice->Append( _( "<unknown>" ) );
@@ -660,6 +666,7 @@ void DIALOG_SIM_MODEL<T_symbol, T_field>::updatePinAssignments( SIM_MODEL* aMode
{
SIM_MODEL_SUBCKT* subckt = static_cast<SIM_MODEL_SUBCKT*>( aModel );
m_subckt->SetText( subckt->GetSpiceCode() );
m_subckt->SetEditable( false );
}
else
{
+2 -1
View File
@@ -130,7 +130,8 @@ private:
std::map<SIM_MODEL::DEVICE_T, SIM_MODEL::TYPE> m_curModelTypeOfDeviceType;
SIM_MODEL::TYPE m_curModelType;
SCINTILLA_TRICKS* m_scintillaTricks;
SCINTILLA_TRICKS* m_scintillaTricksCode;
SCINTILLA_TRICKS* m_scintillaTricksSubckt;
wxPGProperty* m_firstCategory; // Used to add principal parameters to root.
wxPGProperty* m_prevParamGridSelection;
+10 -4
View File
@@ -6,7 +6,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2017-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -54,10 +54,16 @@ DIALOG_SYMBOL_REMAP::DIALOG_SYMBOL_REMAP( SCH_EDIT_FRAME* aParent ) :
{
m_remapped = false;
if( !wxFileName::IsDirWritable( Prj().GetProjectPath() ) )
wxString projectPath = Prj().GetProjectPath();
if( !wxFileName::IsDirWritable( projectPath ) )
{
DisplayInfoMessage( this, _( "Remapping is not possible because you have insufficient "
"privileges to the project folder '%s'." ) );
wxString msg =
wxString::Format( _( "Remapping is not possible because you have insufficient "
"privileges to the project folder '%s'." ),
projectPath );
DisplayInfoMessage( this, msg );
// Disable the remap button.
m_remapped = true;
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@@ -296,10 +296,10 @@ DIALOG_TEXT_PROPERTIES_BASE::DIALOG_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWi
bSizer11 = new wxBoxSizer( wxHORIZONTAL );
m_hyperlinkCombo = new WX_COMBOBOX( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
bSizer11->Add( m_hyperlinkCombo, 1, wxALIGN_CENTER_VERTICAL, 5 );
bSizer11->Add( m_hyperlinkCombo, 1, wxALIGN_CENTER_VERTICAL|wxFIXED_MINSIZE, 5 );
m_textEntrySizer->Add( bSizer11, wxGBPosition( 9, 1 ), wxGBSpan( 1, 6 ), wxEXPAND|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 5 );
m_textEntrySizer->Add( bSizer11, wxGBPosition( 9, 1 ), wxGBSpan( 1, 5 ), wxEXPAND|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 5 );
m_textEntrySizer->AddGrowableCol( 3 );
@@ -2925,7 +2925,7 @@
</object>
<object class="gbsizeritem" expanded="1">
<property name="border">5</property>
<property name="colspan">6</property>
<property name="colspan">5</property>
<property name="column">1</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxALIGN_CENTER_VERTICAL</property>
<property name="row">9</property>
@@ -2937,7 +2937,7 @@
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxFIXED_MINSIZE</property>
<property name="proportion">1</property>
<object class="wxBitmapComboBox" expanded="1">
<property name="BottomDockable">1</property>
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
+6 -6
View File
@@ -53,9 +53,6 @@ PANEL_SETUP_BUSES::PANEL_SETUP_BUSES( wxWindow* aWindow, SCH_EDIT_FRAME* aFrame
m_membersGrid->PushEventHandler( new GRID_TRICKS( m_membersGrid,
[this]( wxCommandEvent& aEvent )
{
wxIdleEvent dummy;
reloadMembersGridOnIdle( dummy );
OnAddMember( aEvent );
} ) );
@@ -306,6 +303,12 @@ void PANEL_SETUP_BUSES::OnMemberGridCellChanging( wxGridEvent& event )
// Parse a space-separated list and add each one
wxStringTokenizer tok( name, " " );
if( tok.CountTokens() > 1 )
{
m_membersGridDirty = true;
Bind( wxEVT_IDLE, &PANEL_SETUP_BUSES::reloadMembersGridOnIdle, this );
}
while( tok.HasMoreTokens() )
alias->Members().push_back( tok.GetNextToken() );
}
@@ -314,9 +317,6 @@ void PANEL_SETUP_BUSES::OnMemberGridCellChanging( wxGridEvent& event )
alias->Members().push_back( m_membersGrid->GetCellValue( ii, 0 ) );
}
}
m_membersGridDirty = true;
Bind( wxEVT_IDLE, &PANEL_SETUP_BUSES::reloadMembersGridOnIdle, this );
}
}
+5 -20
View File
@@ -180,7 +180,7 @@ protected:
tbl->AppendRows( tmp_tbl.GetCount() - tbl->GetNumberRows() );
for( unsigned i = 0; i < tmp_tbl.GetCount(); ++i )
tbl->m_rows.replace( i, tmp_tbl.At( i ).clone() );
tbl->ReplaceRow( i, tmp_tbl.At( i ).clone() );
}
m_grid->AutoSizeColumns( false );
@@ -447,9 +447,6 @@ bool PANEL_SYM_LIB_TABLE::verifyTables()
{
SYMBOL_LIB_TABLE_ROW& row = dynamic_cast<SYMBOL_LIB_TABLE_ROW&>( table->At( r ) );
if( !row.GetParent() )
row.SetParent( table );
if( !row.GetIsEnabled() )
continue;
@@ -667,11 +664,7 @@ void PANEL_SYM_LIB_TABLE::moveUpHandler( wxCommandEvent& event )
// @todo: add multiple selection moves.
if( curRow >= 1 )
{
boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
tbl->m_rows.release( tbl->m_rows.begin() + curRow );
--curRow;
tbl->m_rows.insert( tbl->m_rows.begin() + curRow, move_me.release() );
tbl->ChangeRowOrder( curRow--, -1 );
if( tbl->GetView() )
{
@@ -697,11 +690,7 @@ void PANEL_SYM_LIB_TABLE::moveDownHandler( wxCommandEvent& event )
// @todo: add multiple selection moves.
if( unsigned( curRow + 1 ) < tbl->m_rows.size() )
{
boost::ptr_vector< LIB_TABLE_ROW >::auto_type move_me =
tbl->m_rows.release( tbl->m_rows.begin() + curRow );
++curRow;
tbl->m_rows.insert( tbl->m_rows.begin() + curRow, move_me.release() );
tbl->ChangeRowOrder( curRow++, 1 );
if( tbl->GetView() )
{
@@ -889,9 +878,7 @@ bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow()
m_parent->m_GlobalTableChanged = true;
m_globalTable->Clear();
m_globalTable->m_rows.transfer( m_globalTable->m_rows.end(), global_model()->m_rows.begin(),
global_model()->m_rows.end(), global_model()->m_rows );
m_globalTable->reindex();
m_globalTable->TransferRows( global_model()->m_rows );
}
if( project_model() && *project_model() != *m_projectTable )
@@ -899,9 +886,7 @@ bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow()
m_parent->m_ProjectTableChanged = true;
m_projectTable->Clear();
m_projectTable->m_rows.transfer( m_projectTable->m_rows.end(), project_model()->m_rows.begin(),
project_model()->m_rows.end(), project_model()->m_rows );
m_projectTable->reindex();
m_projectTable->TransferRows( project_model()->m_rows );
}
return true;
+7 -4
View File
@@ -332,12 +332,15 @@ bool IFACE::OnKifaceStart( PGM_BASE* aProgram, int aCtlBits )
// This is process-level-initialization, not project-level-initialization of the DSO.
// Do nothing in here pertinent to a project!
InitSettings( new EESCHEMA_SETTINGS );
aProgram->GetSettingsManager().RegisterSettings( KifaceSettings(), false );
// Register the symbol editor settings as well because they share a KiFACE and need to be
// loaded prior to use to avoid threading deadlocks
aProgram->GetSettingsManager().RegisterSettings( new SYMBOL_EDITOR_SETTINGS, false );
aProgram->GetSettingsManager().Load();
aProgram->GetSettingsManager().RegisterSettings( new SYMBOL_EDITOR_SETTINGS );
// We intentionally register KifaceSettings after SYMBOL_EDITOR_SETTINGS
// In legacy configs, many settings were in a single editor config nd the migration routine
// for the main editor file will try and call into the now separate settings stores
// to move the settings into them
aProgram->GetSettingsManager().RegisterSettings( KifaceSettings() );
start_common( aCtlBits );
+1 -1
View File
@@ -164,7 +164,7 @@ void SCH_EDIT_FRAME::saveProjectSettings()
void SCH_EDIT_FRAME::SaveProjectLocalSettings()
{
// No schematic local settings yet
RecordERCExclusions();
}
+4 -18
View File
@@ -619,8 +619,6 @@ int ERC_TESTER::TestPinToPin()
}
}
std::set<std::pair<ERC_SCH_PIN_CONTEXT, ERC_SCH_PIN_CONTEXT>> tested;
ERC_SCH_PIN_CONTEXT needsDriver;
bool hasDriver = false;
@@ -638,8 +636,9 @@ int ERC_TESTER::TestPinToPin()
}
}
for( ERC_SCH_PIN_CONTEXT& refPin : pins )
for( auto refIt = pins.begin(); refIt != pins.end(); ++refIt )
{
ERC_SCH_PIN_CONTEXT& refPin = *refIt;
ELECTRICAL_PINTYPE refType = refPin.Pin()->GetType();
if( DrivenPinTypes.count( refType ) )
@@ -663,22 +662,9 @@ int ERC_TESTER::TestPinToPin()
else
hasDriver |= ( DrivingPinTypes.count( refType ) != 0 );
for( ERC_SCH_PIN_CONTEXT& testPin : pins )
for( auto testIt = refIt + 1; testIt != pins.end(); ++testIt )
{
if( testPin == refPin )
continue;
ERC_SCH_PIN_CONTEXT first_pin = refPin;
ERC_SCH_PIN_CONTEXT second_pin = testPin;
if( second_pin < first_pin )
std::swap( first_pin, second_pin );
std::pair<ERC_SCH_PIN_CONTEXT, ERC_SCH_PIN_CONTEXT> pair =
std::make_pair( first_pin, second_pin );
if( auto [ins_pin, inserted ] = tested.insert( pair ); !inserted )
continue;
ERC_SCH_PIN_CONTEXT& testPin = *testIt;
// Multiple pins in the same symbol that share a type,
// name and position are considered
+32 -8
View File
@@ -580,7 +580,7 @@ wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
return StringFromBool( field.IsNameShown() );
case FDC_H_ALIGN:
switch ( field.GetHorizJustify() )
switch ( field.GetEffectiveHorizJustify() )
{
case GR_TEXT_H_ALIGN_LEFT: return _( "Left" );
case GR_TEXT_H_ALIGN_CENTER: return _( "Center" );
@@ -590,7 +590,7 @@ wxString FIELDS_GRID_TABLE<T>::GetValue( int aRow, int aCol )
break;
case FDC_V_ALIGN:
switch ( field.GetVertJustify() )
switch ( field.GetEffectiveVertJustify() )
{
case GR_TEXT_V_ALIGN_TOP: return _( "Top" );
case GR_TEXT_V_ALIGN_CENTER: return _( "Center" );
@@ -727,28 +727,52 @@ void FIELDS_GRID_TABLE<T>::SetValue( int aRow, int aCol, const wxString &aValue
break;
case FDC_H_ALIGN:
{
GR_TEXT_H_ALIGN_T horizontalJustification;
if( value == _( "Left" ) )
field.SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
horizontalJustification = GR_TEXT_H_ALIGN_LEFT;
else if( value == _( "Center" ) )
field.SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
horizontalJustification = GR_TEXT_H_ALIGN_CENTER;
else if( value == _( "Right" ) )
field.SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
horizontalJustification = GR_TEXT_H_ALIGN_RIGHT;
else
wxFAIL_MSG( wxT( "unknown horizontal alignment: " ) + value );
// Note that we must set justifications before we can ask if they're flipped. If the old
// justification is center then it won't know (whereas if the new justification is center
// the we don't care).
field.SetHorizJustify( horizontalJustification );
if( field.IsHorizJustifyFlipped() )
field.SetHorizJustify( EDA_TEXT::MapHorizJustify( - horizontalJustification ) );
break;
}
case FDC_V_ALIGN:
{
GR_TEXT_V_ALIGN_T verticalJustification;
if( value == _( "Top" ) )
field.SetVertJustify( GR_TEXT_V_ALIGN_TOP );
verticalJustification = GR_TEXT_V_ALIGN_TOP;
else if( value == _( "Center" ) )
field.SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
verticalJustification = GR_TEXT_V_ALIGN_CENTER;
else if( value == _( "Bottom" ) )
field.SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
verticalJustification = GR_TEXT_V_ALIGN_BOTTOM;
else
wxFAIL_MSG( wxT( "unknown vertical alignment: " ) + value);
// Note that we must set justifications before we can ask if they're flipped. If the old
// justification is center then it won't know (whereas if the new justification is center
// the we don't care).
field.SetVertJustify( verticalJustification );
if( field.IsVertJustifyFlipped() )
field.SetVertJustify( EDA_TEXT::MapVertJustify( -verticalJustification ) );
break;
}
case FDC_ITALIC:
field.SetItalic( BoolFromString( value ) );
+25 -2
View File
@@ -103,7 +103,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
{
msg.Printf( _( "Schematic '%s' is already open." ), wx_filename.GetFullName() );
if( !OverrideLock( this, msg ) )
if( !AskOverrideLock( this, msg ) )
return false;
m_file_checker->OverrideLock( false );
@@ -590,6 +590,15 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
if( !AskToSaveChanges() )
return;
if( Schematic().RootScreen() && !Schematic().RootScreen()->Items().empty() )
{
wxString msg = _( "This operation replaces the contents of the current project.\n\n"
"Do you want to proceed?" );
if( !IsOK( this, msg ) )
return;
}
// Set the project location if none is set or if we are running in standalone mode
bool setProject = Prj().GetProjectFullName().IsEmpty() || Kiface().IsSingle();
wxString path = wxPathOnly( Prj().GetProjectFullName() );
@@ -638,6 +647,9 @@ void SCH_EDIT_FRAME::OnImportProject( wxCommandEvent& aEvent )
Schematic().SetProject( nullptr );
GetSettingsManager()->UnloadProject( &Prj(), false );
// Clear view before destroying schematic as repaints depend on schematic being valid
SetScreen( nullptr );
Schematic().Reset();
wxFileName projectFn( dlg.GetPath() );
@@ -696,6 +708,17 @@ bool SCH_EDIT_FRAME::saveSchematicFile( SCH_SHEET* aSheet, const wxString& aSave
if( !IsWritable( schematicFileName ) )
return false;
wxFileName projectFile( schematicFileName );
projectFile.SetExt( ProjectFileExtension );
if( projectFile.FileExists() )
{
// Save various ERC settings, such as violation severities (which may have been edited
// via the ERC dialog as well as the Schematic Setup dialog), ERC exclusions, etc.
saveProjectSettings();
}
wxString tempFile = wxFileName::CreateTempFileName( wxS( "eeschema" ) );
// Save
@@ -1220,7 +1243,7 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
msg.Printf( _( "Schematic '%s' is already open by '%s' at '%s'." ), aFileName,
m_file_checker->GetUsername(), m_file_checker->GetHostname() );
if( !OverrideLock( this, msg ) )
if( !AskOverrideLock( this, msg ) )
return false;
m_file_checker->OverrideLock();
+1 -1
View File
@@ -415,7 +415,7 @@ wxString LIB_FIELD::GetShownText( bool aAllowExtraText, int aDepth ) const
{
wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
if( IsNameShown() )
if( IsNameShown() && aAllowExtraText )
text = GetName() << wxT( ": " ) << text;
return text;
+6
View File
@@ -118,6 +118,12 @@ public:
KIFONT::FONT* getDrawFont() const override;
bool IsHorizJustifyFlipped() const { return false; }
bool IsVertJustifyFlipped() const { return false; }
GR_TEXT_H_ALIGN_T GetEffectiveHorizJustify() const { return GetHorizJustify(); }
GR_TEXT_V_ALIGN_T GetEffectiveVertJustify() const { return GetVertJustify(); }
/**
* Copy parameters of this field to another field. Pointers are not copied.
*
+3 -2
View File
@@ -847,7 +847,7 @@ void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) const
* when m_convert == 0, the body item is common to shapes
*/
LIB_SYMBOL_SPTR parent = m_parent.lock();
LIB_SYMBOL_SPTR parent = m_parent.lock();
const LIB_ITEMS_CONTAINER& drawItems = parent ? parent->m_drawings : m_drawings;
for( const LIB_ITEM& item : drawItems[LIB_PIN_T] )
@@ -856,7 +856,7 @@ void LIB_SYMBOL::GetPins( LIB_PINS& aList, int aUnit, int aConvert ) const
if( aUnit && item.m_unit && ( item.m_unit != aUnit ) )
continue;
// Shape filtering:
// De Morgan variant filtering:
if( aConvert && item.m_convert && ( item.m_convert != aConvert ) )
continue;
@@ -1276,6 +1276,7 @@ bool LIB_SYMBOL::HasConversion() const
return false;
}
int LIB_SYMBOL::GetMaxPinNumber() const
{
int maxPinNumber = 0;
+5 -1
View File
@@ -106,10 +106,14 @@ void SCH_EDIT_FRAME::doReCreateMenuBar()
ACTION_MENU* submenuImport = new ACTION_MENU( false, selTool );
submenuImport->SetTitle( _( "Import" ) );
submenuImport->SetIcon( BITMAPS::import );
submenuImport->Add( _( "Non-KiCad Schematic..." ),
if( Kiface().IsSingle() )
{
submenuImport->Add( _( "Non-KiCad Schematic..." ),
_( "Replace current schematic sheet with one imported from another application" ),
ID_IMPORT_NON_KICAD_SCH,
BITMAPS::import_document );
}
submenuImport->Add( EE_ACTIONS::importFPAssignments, ACTION_MENU::NORMAL, _( "Footprint Assignments..." ) );
fileMenu->Add( submenuImport );
+2
View File
@@ -43,6 +43,8 @@ public:
bool IsDanglingStart() const { return m_isDanglingStart; }
bool IsDanglingEnd() const { return m_isDanglingEnd; }
void SetEndDangling( bool aDanglingState ) { m_isDanglingEnd = aDanglingState; }
// Do not create a copy constructor. The one generated by the compiler is adequate.
~SCH_BUS_ENTRY_BASE() { }
+9 -2
View File
@@ -1496,9 +1496,10 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
}
else
{
auto& changed_list = m_undoList.m_CommandsList.back();
PICKED_ITEMS_LIST* changed_list = m_undoList.m_CommandsList.back();
std::set<SCH_ITEM*> changed_items;
std::vector<VECTOR2I> pts;
std::set<std::pair<SCH_SHEET_PATH, SCH_ITEM*>> item_paths;
for( unsigned ii = 0; ii < changed_list->GetCount(); ++ii )
{
@@ -1507,11 +1508,16 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
if( !item || !IsEeschemaType( item->Type() ) )
continue;
SCH_SCREEN* screen = static_cast<SCH_SCREEN*>( changed_list->GetScreenForItem( ii ) );
SCH_ITEM* sch_item = static_cast<SCH_ITEM*>( item );
SCH_SHEET_PATHS& paths = screen->GetClientSheetPaths();
std::vector<VECTOR2I> tmp_pts = sch_item->GetConnectionPoints();
pts.insert( pts.end(), tmp_pts.begin(), tmp_pts.end() );
changed_items.insert( sch_item );
for( SCH_SHEET_PATH& path : paths )
item_paths.insert( std::make_pair( path, sch_item ) );
}
for( VECTOR2I& pt: pts )
@@ -1546,6 +1552,8 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
Schematic().ConnectionGraph()->ExtractAffectedItems(
changed_items );
all_items.insert( item_paths.begin(), item_paths.end() );
CONNECTION_GRAPH new_graph( &Schematic() );
new_graph.SetLastCodes( Schematic().ConnectionGraph() );
@@ -1556,7 +1564,6 @@ void SCH_EDIT_FRAME::RecalculateConnections( SCH_CLEANUP_FLAGS aCleanupFlags )
{
case SCH_FIELD_T:
case SCH_PIN_T:
case SCH_SHEET_PIN_T:
static_cast<SCH_ITEM*>( item->GetParent() )->SetConnectivityDirty();
break;
+8 -4
View File
@@ -92,8 +92,10 @@ SCH_FIELD::SCH_FIELD( const SCH_FIELD& aField ) :
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aField.m_renderCache )
{
KIFONT::OUTLINE_GLYPH* outline_glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() );
m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline_glyph ) );
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
m_renderCache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
}
m_renderCacheValid = aField.m_renderCacheValid;
@@ -116,8 +118,10 @@ SCH_FIELD& SCH_FIELD::operator=( const SCH_FIELD& aField )
for( const std::unique_ptr<KIFONT::GLYPH>& glyph : aField.m_renderCache )
{
KIFONT::OUTLINE_GLYPH* outline_glyph = static_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() );
m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline_glyph ) );
if( KIFONT::OUTLINE_GLYPH* outline = dynamic_cast<KIFONT::OUTLINE_GLYPH*>( glyph.get() ) )
m_renderCache.emplace_back( std::make_unique<KIFONT::OUTLINE_GLYPH>( *outline ) );
else if( KIFONT::STROKE_GLYPH* stroke = dynamic_cast<KIFONT::STROKE_GLYPH*>( glyph.get() ) )
m_renderCache.emplace_back( std::make_unique<KIFONT::STROKE_GLYPH>( *stroke ) );
}
m_renderCacheValid = aField.m_renderCacheValid;
+13 -1
View File
@@ -94,7 +94,7 @@ public:
bool IsHypertext() const override
{
return m_id == 0 && m_parent && m_parent->Type() == SCH_GLOBAL_LABEL_T;
return GetCanonicalName() == wxT( "Intersheetrefs" );
}
void DoHypertextAction( EDA_DRAW_FRAME* aFrame ) const override;
@@ -134,6 +134,18 @@ public:
return GetShownText( nullptr, aAllowExtraText, aDepth );
}
/**
* Return true if both the name and value of the field are empty. Whitespace
* does not count as non-empty
*/
bool IsEmpty()
{
wxString name( m_name );
wxString value( GetText() );
return name.Trim().empty() && value.Trim().empty();
}
COLOR4D GetFieldColor() const;
void SetLastResolvedState( const SCH_ITEM* aItem ) override
+8 -7
View File
@@ -149,9 +149,6 @@ SCH_CONNECTION* SCH_ITEM::Connection( const SCH_SHEET_PATH* aSheet ) const
if( !IsConnectable() )
return nullptr;
wxCHECK_MSG( !IsConnectivityDirty(), nullptr,
wxT( "Shouldn't be asking for connection if connectivity is dirty!" ) );
if( !aSheet )
aSheet = &Schematic()->CurrentSheet();
@@ -167,7 +164,12 @@ SCH_CONNECTION* SCH_ITEM::Connection( const SCH_SHEET_PATH* aSheet ) const
void SCH_ITEM::SetConnectionGraph( CONNECTION_GRAPH* aGraph )
{
for( auto& [path, conn] : m_connection_map )
{
conn->SetGraph( aGraph );
for( auto& member : conn->AllMembers() )
member->SetGraph( aGraph );
}
}
@@ -213,10 +215,11 @@ void SCH_ITEM::AddConnectionTo( const SCH_SHEET_PATH& aSheet, SCH_ITEM* aItem )
SCH_CONNECTION* SCH_ITEM::InitializeConnection( const SCH_SHEET_PATH& aSheet,
CONNECTION_GRAPH* aGraph )
{
SetConnectivityDirty( false );
SCH_CONNECTION* connection = Connection( &aSheet );
// N.B. Do not clear the dirty connectivity flag here because we may need
// to create a connection for a different sheet, and we don't want to
// skip the connection creation because the flag is cleared.
if( connection )
{
connection->Reset();
@@ -239,8 +242,6 @@ SCH_CONNECTION* SCH_ITEM::GetOrInitConnection( const SCH_SHEET_PATH& aSheet,
if( !IsConnectable() )
return nullptr;
SetConnectivityDirty( false );
SCH_CONNECTION* connection = Connection( &aSheet );
if( connection )
+40 -4
View File
@@ -1037,8 +1037,27 @@ void SCH_LABEL_BASE::Plot( PLOTTER* aPlotter, bool aBackground ) const
{
aPlotter->PlotText( textpos, color, GetShownText( true ), attrs, font );
if( s_poly.size() )
aPlotter->PlotPoly( s_poly, FILL_T::NO_FILL, penWidth );
if( GetShape() == LABEL_FLAG_SHAPE::F_DOT )
{
aPlotter->MoveTo( s_poly[0] );
aPlotter->LineTo( s_poly[1] );
int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
aPlotter->FilledCircle( s_poly[2], diameter , FILLED, nullptr );
}
else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
{
aPlotter->MoveTo( s_poly[0] );
aPlotter->LineTo( s_poly[1] );
int diameter = ( s_poly[2] - s_poly[1] ).EuclideanNorm() * 2;
aPlotter->ThickCircle( s_poly[2], diameter, penWidth, FILLED, nullptr );
}
else
{
if( !s_poly.empty() )
aPlotter->PlotPoly( s_poly, FILL_T::NO_FILL, penWidth );
}
// Plot attributes to a hypertext menu
std::vector<wxString> properties;
@@ -1092,8 +1111,25 @@ void SCH_LABEL_BASE::Print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aO
CreateGraphicShape( aSettings, s_poly, GetTextPos() + aOffset );
if( !s_poly.empty() )
GRPoly( DC, s_poly.size(), &s_poly[0], false, penWidth, color, color );
if( GetShape() == LABEL_FLAG_SHAPE::F_DOT )
{
GRLine( DC, s_poly[0], s_poly[1], penWidth, color );
int radius = ( s_poly[2] - s_poly[1] ).EuclideanNorm();
GRFilledCircle( DC, s_poly[2], radius, penWidth, color, color );
}
else if( GetShape() == LABEL_FLAG_SHAPE::F_ROUND )
{
GRLine( DC, s_poly[0], s_poly[1], penWidth, color );
int radius = ( s_poly[2] - s_poly[1] ).EuclideanNorm();
GRCircle( DC, s_poly[2], radius, penWidth, color );
}
else
{
if( !s_poly.empty() )
GRPoly( DC, s_poly.size(), &s_poly[0], false, penWidth, color, color );
}
for( SCH_FIELD& field : m_fields )
field.Print( aSettings, aOffset );
+96 -97
View File
@@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 CERN
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
@@ -86,7 +86,10 @@ std::vector<KICAD_T> SCH_PAINTER::g_ScaledSelectionTypes = {
SCH_LINE_T,
LIB_SHAPE_T, SCH_SHAPE_T,
SCH_BITMAP_T,
SCH_GLOBAL_LABEL_T,
SCH_DIRECTIVE_LABEL_T,
SCH_HIER_LABEL_T,
SCH_SHEET_PIN_T,
LIB_SYMBOL_T, SCH_SYMBOL_T,
SCH_SHEET_T,
LIB_PIN_T, SCH_PIN_T
@@ -186,7 +189,7 @@ SCH_PAINTER::SCH_PAINTER( GAL* aGal ) :
m_schematic( nullptr )
{ }
bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
bool SCH_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
{
const EDA_ITEM* item = dynamic_cast<const EDA_ITEM*>( aItem );
@@ -198,7 +201,7 @@ bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
return false;
}
void SCH_PAINTER::draw( const EDA_ITEM *aItem, int aLayer, bool aDimmed )
void SCH_PAINTER::draw( const EDA_ITEM* aItem, int aLayer, bool aDimmed )
{
#ifdef CONNECTIVITY_DEBUG
@@ -369,7 +372,7 @@ float SCH_PAINTER::getShadowWidth( bool aForHighlight ) const
}
COLOR4D SCH_PAINTER::getRenderColor( const EDA_ITEM *aItem, int aLayer, bool aDrawingShadows,
COLOR4D SCH_PAINTER::getRenderColor( const EDA_ITEM* aItem, int aLayer, bool aDrawingShadows,
bool aDimmed ) const
{
COLOR4D color = m_schSettings.GetLayerColor( aLayer );
@@ -666,7 +669,7 @@ void SCH_PAINTER::triLine( const VECTOR2D &a, const VECTOR2D &b, const VECTOR2D
}
void SCH_PAINTER::draw( const LIB_SYMBOL *aSymbol, int aLayer, bool aDrawFields, int aUnit,
void SCH_PAINTER::draw( const LIB_SYMBOL* aSymbol, int aLayer, bool aDrawFields, int aUnit,
int aConvert, bool aDimmed )
{
if( !aUnit )
@@ -751,7 +754,11 @@ bool SCH_PAINTER::setDeviceColors( const LIB_ITEM* aItem, int aLayer, bool aDimm
{
COLOR4D fillColour = shape->GetFillColor();
if( aDimmed )
if( m_schSettings.m_OverrideItemColors )
{
fillColour = getRenderColor( aItem, LAYER_DEVICE_BACKGROUND, false, aDimmed );
}
else if( aDimmed )
{
fillColour = fillColour.Mix(
m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ), 0.5f );
@@ -928,7 +935,7 @@ void SCH_PAINTER::draw( const LIB_SHAPE *aShape, int aLayer, bool aDimmed )
}
void SCH_PAINTER::draw( const LIB_FIELD *aField, int aLayer, bool aDimmed )
void SCH_PAINTER::draw( const LIB_FIELD* aField, int aLayer, bool aDimmed )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
@@ -1704,7 +1711,7 @@ void SCH_PAINTER::drawDanglingSymbol( const VECTOR2I& aPos, const COLOR4D& aColo
}
void SCH_PAINTER::draw( const SCH_JUNCTION *aJct, int aLayer )
void SCH_PAINTER::draw( const SCH_JUNCTION* aJct, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
@@ -1936,7 +1943,6 @@ void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer )
void SCH_PAINTER::draw( const SCH_TEXT* aText, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
bool drawingDangling = aLayer == LAYER_DANGLING;
if( drawingShadows && !( aText->IsBrightened() || aText->IsSelected() ) )
return;
@@ -1972,18 +1978,6 @@ void SCH_PAINTER::draw( const SCH_TEXT* aText, int aLayer )
return;
}
if( drawingDangling )
{
if( aText->IsDangling() )
{
drawDanglingSymbol( aText->GetTextPos(), color,
schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE / 2 ), true,
drawingShadows, aText->IsBrightened() );
}
return;
}
m_gal->SetStrokeColor( color );
m_gal->SetFillColor( color );
@@ -2507,9 +2501,10 @@ void SCH_PAINTER::draw( const SCH_FIELD* aField, int aLayer, bool aDimmed )
}
void SCH_PAINTER::draw( const SCH_GLOBALLABEL *aLabel, int aLayer )
void SCH_PAINTER::draw( const SCH_GLOBALLABEL* aLabel, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
bool drawingDangling = aLayer == LAYER_DANGLING;
if( !drawingShadows || eeconfig()->m_Selection.draw_selected_children )
{
@@ -2525,6 +2520,18 @@ void SCH_PAINTER::draw( const SCH_GLOBALLABEL *aLabel, int aLayer )
COLOR4D color = getRenderColor( aLabel, LAYER_GLOBLABEL, drawingShadows );
if( drawingDangling )
{
if( aLabel->IsDangling() )
{
drawDanglingSymbol( aLabel->GetTextPos(), color,
schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE / 2 ), true,
drawingShadows, aLabel->IsBrightened() );
}
return;
}
std::vector<VECTOR2I> pts;
std::deque<VECTOR2D> pts2;
@@ -2533,46 +2540,30 @@ void SCH_PAINTER::draw( const SCH_GLOBALLABEL *aLabel, int aLayer )
for( const VECTOR2I& p : pts )
pts2.emplace_back( VECTOR2D( p.x, p.y ) );
// The text is drawn inside the graphic shape.
// On Cairo the graphic shape is filled by the background before drawing the text.
// However if the text is selected, it is draw twice: first on LAYER_SELECTION_SHADOWS
// and second on the text layer. The second must not erase the first drawing.
bool fillBg = ( ( aLayer == LAYER_SELECTION_SHADOWS ) || !aLabel->IsSelected() )
&& aLayer != LAYER_DANGLING;
m_gal->SetIsFill( fillBg );
m_gal->SetFillColor( m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ) );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( getTextThickness( aLabel ) );
m_gal->SetLineWidth( getLineWidth( aLabel, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->DrawPolyline( pts2 );
draw( static_cast<const SCH_TEXT*>( aLabel ), aLayer );
}
void SCH_PAINTER::draw( const SCH_LABEL *aLabel, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
if( !drawingShadows || eeconfig()->m_Selection.draw_selected_children )
if( drawingShadows )
{
for( const SCH_FIELD& field : aLabel->GetFields() )
draw( &field, aLayer, false );
m_gal->SetIsFill( eeconfig()->m_Selection.fill_shapes );
m_gal->SetFillColor( color );
m_gal->DrawPolygon( pts2 );
}
else
{
m_gal->SetIsFill( false );
m_gal->DrawPolyline( pts2 );
}
if( isFieldsLayer( aLayer ) )
return;
if( drawingShadows && !( aLabel->IsBrightened() || aLabel->IsSelected() ) )
return;
draw( static_cast<const SCH_TEXT*>( aLabel ), aLayer );
}
void SCH_PAINTER::draw( const SCH_HIERLABEL *aLabel, int aLayer )
void SCH_PAINTER::draw( const SCH_LABEL* aLabel, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
bool drawingDangling = aLayer == LAYER_DANGLING;
if( !drawingShadows || eeconfig()->m_Selection.draw_selected_children )
{
@@ -2588,6 +2579,53 @@ void SCH_PAINTER::draw( const SCH_HIERLABEL *aLabel, int aLayer )
COLOR4D color = getRenderColor( aLabel, LAYER_HIERLABEL, drawingShadows );
if( drawingDangling )
{
if( aLabel->IsDangling() )
{
drawDanglingSymbol( aLabel->GetTextPos(), color,
schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE / 2 ), true,
drawingShadows, aLabel->IsBrightened() );
}
return;
}
draw( static_cast<const SCH_TEXT*>( aLabel ), aLayer );
}
void SCH_PAINTER::draw( const SCH_HIERLABEL* aLabel, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
bool drawingDangling = aLayer == LAYER_DANGLING;
if( !( drawingShadows || drawingDangling ) || eeconfig()->m_Selection.draw_selected_children )
{
for( const SCH_FIELD& field : aLabel->GetFields() )
draw( &field, aLayer, false );
}
if( isFieldsLayer( aLayer ) )
return;
if( drawingShadows && !( aLabel->IsBrightened() || aLabel->IsSelected() ) )
return;
COLOR4D color = getRenderColor( aLabel, LAYER_HIERLABEL, drawingShadows );
if( drawingDangling )
{
if( aLabel->IsDangling() )
{
drawDanglingSymbol( aLabel->GetTextPos(), color,
schIUScale.MilsToIU( DANGLING_SYMBOL_SIZE / 2 ), true,
drawingShadows, aLabel->IsBrightened() );
}
return;
}
if( m_schematic )
{
SCH_CONNECTION* conn = nullptr;
@@ -2610,7 +2648,7 @@ void SCH_PAINTER::draw( const SCH_HIERLABEL *aLabel, int aLayer )
m_gal->SetIsFill( true );
m_gal->SetFillColor( m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND ) );
m_gal->SetIsStroke( true );
m_gal->SetLineWidth( getTextThickness( aLabel ) );
m_gal->SetLineWidth( getLineWidth( aLabel, drawingShadows ) );
m_gal->SetStrokeColor( color );
m_gal->DrawPolyline( pts2 );
@@ -2618,7 +2656,7 @@ void SCH_PAINTER::draw( const SCH_HIERLABEL *aLabel, int aLayer )
}
void SCH_PAINTER::draw( const SCH_DIRECTIVE_LABEL *aLabel, int aLayer )
void SCH_PAINTER::draw( const SCH_DIRECTIVE_LABEL* aLabel, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
@@ -2688,53 +2726,14 @@ void SCH_PAINTER::draw( const SCH_SHEET *aSheet, int aLayer )
{
for( const SCH_FIELD& field : aSheet->GetFields() )
draw( &field, aLayer, false );
for( SCH_SHEET_PIN* sheetPin : aSheet->GetPins() )
draw( static_cast<SCH_HIERLABEL*>( sheetPin ), aLayer );
}
if( isFieldsLayer( aLayer ) )
return;
if( aLayer == LAYER_HIERLABEL || aLayer == LAYER_SELECTION_SHADOWS )
{
for( SCH_SHEET_PIN* sheetPin : aSheet->GetPins() )
{
if( drawingShadows )
{
if( ( aSheet->IsBrightened() || aSheet->IsSelected() )
&& eeconfig()->m_Selection.draw_selected_children )
{
// fall through to draw
}
else if( sheetPin->IsBrightened() || sheetPin->IsSelected() )
{
// fall through to draw
}
else
{
continue;
}
}
int width = std::max( aSheet->GetPenWidth(), m_schSettings.GetDefaultPenWidth() );
VECTOR2I initial_pos = sheetPin->GetTextPos();
VECTOR2I offset_pos = initial_pos;
// For aesthetic reasons, the SHEET_PIN is drawn with a small offset of width / 2
switch( sheetPin->GetSide() )
{
case SHEET_SIDE::TOP: offset_pos.y += KiROUND( width / 2.0 ); break;
case SHEET_SIDE::BOTTOM: offset_pos.y -= KiROUND( width / 2.0 ); break;
case SHEET_SIDE::RIGHT: offset_pos.x -= KiROUND( width / 2.0 ); break;
case SHEET_SIDE::LEFT: offset_pos.x += KiROUND( width / 2.0 ); break;
default: break;
}
sheetPin->SetTextPos( offset_pos );
draw( static_cast<SCH_HIERLABEL*>( sheetPin ), aLayer );
m_gal->DrawLine( offset_pos, initial_pos );
sheetPin->SetTextPos( initial_pos );
}
}
VECTOR2D pos = aSheet->GetPosition();
VECTOR2D size = aSheet->GetSize();
@@ -2759,7 +2758,7 @@ void SCH_PAINTER::draw( const SCH_SHEET *aSheet, int aLayer )
}
void SCH_PAINTER::draw( const SCH_NO_CONNECT *aNC, int aLayer )
void SCH_PAINTER::draw( const SCH_NO_CONNECT* aNC, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
@@ -2838,7 +2837,7 @@ void SCH_PAINTER::draw( const SCH_BUS_ENTRY_BASE *aEntry, int aLayer )
}
void SCH_PAINTER::draw( const SCH_BITMAP *aBitmap, int aLayer )
void SCH_PAINTER::draw( const SCH_BITMAP* aBitmap, int aLayer )
{
m_gal->Save();
m_gal->Translate( aBitmap->GetPosition() );
@@ -2883,7 +2882,7 @@ void SCH_PAINTER::draw( const SCH_BITMAP *aBitmap, int aLayer )
}
void SCH_PAINTER::draw( const SCH_MARKER *aMarker, int aLayer )
void SCH_PAINTER::draw( const SCH_MARKER* aMarker, int aLayer )
{
bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
+2
View File
@@ -110,6 +110,8 @@ public:
void SetIsDangling( bool isDangling ) { m_isDangling = isDangling; }
void SetLibPin( LIB_PIN* aLibPin ) { m_libPin = aLibPin; }
/**
* @param aPin Comparison Pin
* @return True if aPin is stacked with this pin
@@ -274,7 +274,7 @@ ASCH_TEXT_FRAME::ASCH_TEXT_FRAME( const std::map<wxString, wxString>& aProps )
AreaColor = ALTIUM_PARSER::ReadInt( aProps, "AREACOLOR", 0 );
BorderColor = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
IsSolid = ALTIUM_PARSER::ReadBool( aProps, "WORDWRAP", true );
IsSolid = ALTIUM_PARSER::ReadBool( aProps, "ISSOLID", false );
Alignment = ReadEnum<ASCH_TEXT_FRAME_ALIGNMENT>( aProps, "ALIGNMENT", 1, 3,
ASCH_TEXT_FRAME_ALIGNMENT::LEFT );
@@ -331,13 +331,8 @@ ASCH_POLYLINE::ASCH_POLYLINE( const std::map<wxString, wxString>& aProps )
LineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
int linestyleVar = ALTIUM_PARSER::ReadInt( aProps, "LINESTYLEEXT", 0 );
// overwrite if present.
linestyleVar = ALTIUM_PARSER::ReadInt( aProps, "LINESTYLE", linestyleVar );
LineStyle = linestyleVar >= 0 && linestyleVar <= 3 ?
static_cast<ASCH_POLYLINE_LINESTYLE>( linestyleVar ) :
ASCH_POLYLINE_LINESTYLE::SOLID;
auto lineStyleExt = ReadEnum( aProps, "LINESTYLEEXT", 0, 3, ASCH_POLYLINE_LINESTYLE::SOLID );
LineStyle = ReadEnum( aProps, "LINESTYLE", 0, 3, lineStyleExt ); // overwrite if present.
}
@@ -447,7 +442,11 @@ ASCH_LINE::ASCH_LINE( const std::map<wxString, wxString>& aProps )
point2 = VECTOR2I( ReadKiCadUnitFrac( aProps, "CORNER.X" ),
-ReadKiCadUnitFrac( aProps, "CORNER.Y" ) );
lineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
LineWidth = ReadKiCadUnitFrac( aProps, "LINEWIDTH" );
Color = ALTIUM_PARSER::ReadInt( aProps, "COLOR", 0 );
auto lineStyleExt = ReadEnum( aProps, "LINESTYLEEXT", 0, 3, ASCH_POLYLINE_LINESTYLE::SOLID );
LineStyle = ReadEnum( aProps, "LINESTYLE", 0, 3, lineStyleExt ); // overwrite if present.
}
@@ -679,8 +678,6 @@ ASCH_BUS::ASCH_BUS( const std::map<wxString, wxString>& aProps )
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::BUS );
indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 );
int locationcount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
for( int i = 1; i <= locationcount; i++ )
@@ -698,8 +695,6 @@ ASCH_WIRE::ASCH_WIRE( const std::map<wxString, wxString>& aProps )
{
wxASSERT( ReadRecord( aProps ) == ALTIUM_SCH_RECORD::WIRE );
indexinsheet = ALTIUM_PARSER::ReadInt( aProps, "INDEXINSHEET", 0 );
int locationcount = ALTIUM_PARSER::ReadInt( aProps, "LOCATIONCOUNT", 0 );
for( int i = 1; i <= locationcount; i++ )
@@ -800,6 +795,11 @@ ASCH_SHEET::ASCH_SHEET( const std::map<wxString, wxString>& aProps )
for( int i = 1; i <= fontidcount; i++ )
fonts.emplace_back( aProps, i );
useCustomSheet = ALTIUM_PARSER::ReadBool( aProps, "USECUSTOMSHEET", false );
customSize = VECTOR2I( ReadKiCadUnitFrac( aProps, "CUSTOMX" ),
ReadKiCadUnitFrac( aProps, "CUSTOMY" ) );
sheetSize = ReadEnum<ASCH_SHEET_SIZE>( aProps, "SHEETSTYLE", 0, 17, ASCH_SHEET_SIZE::A4 );
sheetOrientation = ReadEnum<ASCH_SHEET_WORKSPACEORIENTATION>(
aProps, "WORKSPACEORIENTATION", 0, 1, ASCH_SHEET_WORKSPACEORIENTATION::LANDSCAPE );
@@ -437,7 +437,10 @@ struct ASCH_LINE
VECTOR2I point1;
VECTOR2I point2;
int lineWidth;
int LineWidth;
int Color;
ASCH_POLYLINE_LINESTYLE LineStyle;
explicit ASCH_LINE( const std::map<wxString, wxString>& aProps );
};
@@ -773,6 +776,9 @@ struct ASCH_SHEET
{
std::vector<ASCH_SHEET_FONT> fonts;
bool useCustomSheet;
VECTOR2I customSize;
ASCH_SHEET_SIZE sheetSize;
ASCH_SHEET_WORKSPACEORIENTATION sheetOrientation;
@@ -1743,7 +1743,10 @@ void SCH_ALTIUM_PLUGIN::ParseLine( const std::map<wxString, wxString>& aProperti
// close polygon
SCH_LINE* line = new SCH_LINE( elem.point1 + m_sheetOffset, SCH_LAYER_ID::LAYER_NOTES );
line->SetEndPoint( elem.point2 + m_sheetOffset );
line->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) ); // TODO?
COLOR4D color = GetColorFromInt( elem.Color );
line->SetStroke( STROKE_PARAMS( elem.LineWidth, GetPlotDashType( elem.LineStyle ),
color == PUREBLUE ? COLOR4D::UNSPECIFIED : color ) );
line->SetFlags( IS_NEW );
screen->Append( line );
@@ -1773,7 +1776,9 @@ void SCH_ALTIUM_PLUGIN::ParseLine( const std::map<wxString, wxString>& aProperti
line->AddPoint( GetRelativePosition( elem.point1 + m_sheetOffset, symbol ) );
line->AddPoint( GetRelativePosition( elem.point2 + m_sheetOffset, symbol ) );
line->SetStroke( STROKE_PARAMS( elem.lineWidth, PLOT_DASH_TYPE::SOLID ) );
COLOR4D color = GetColorFromInt( elem.Color );
line->SetStroke( STROKE_PARAMS( elem.LineWidth, GetPlotDashType( elem.LineStyle ),
color == PUREBLUE ? COLOR4D::UNSPECIFIED : color ) );
}
}
@@ -2788,27 +2793,36 @@ void SCH_ALTIUM_PLUGIN::ParseSheet( const std::map<wxString, wxString>& aPropert
bool isPortrait = m_altiumSheet->sheetOrientation == ASCH_SHEET_WORKSPACEORIENTATION::PORTRAIT;
switch( m_altiumSheet->sheetSize )
if( m_altiumSheet->useCustomSheet )
{
default:
case ASCH_SHEET_SIZE::A4: pageInfo.SetType( "A4", isPortrait ); break;
case ASCH_SHEET_SIZE::A3: pageInfo.SetType( "A3", isPortrait ); break;
case ASCH_SHEET_SIZE::A2: pageInfo.SetType( "A2", isPortrait ); break;
case ASCH_SHEET_SIZE::A1: pageInfo.SetType( "A1", isPortrait ); break;
case ASCH_SHEET_SIZE::A0: pageInfo.SetType( "A0", isPortrait ); break;
case ASCH_SHEET_SIZE::A: pageInfo.SetType( "A", isPortrait ); break;
case ASCH_SHEET_SIZE::B: pageInfo.SetType( "B", isPortrait ); break;
case ASCH_SHEET_SIZE::C: pageInfo.SetType( "C", isPortrait ); break;
case ASCH_SHEET_SIZE::D: pageInfo.SetType( "D", isPortrait ); break;
case ASCH_SHEET_SIZE::E: pageInfo.SetType( "E", isPortrait ); break;
case ASCH_SHEET_SIZE::LETTER: pageInfo.SetType( "USLetter", isPortrait ); break;
case ASCH_SHEET_SIZE::LEGAL: pageInfo.SetType( "USLegal", isPortrait ); break;
case ASCH_SHEET_SIZE::TABLOID: pageInfo.SetType( "A3", isPortrait ); break;
case ASCH_SHEET_SIZE::ORCAD_A: pageInfo.SetType( "A", isPortrait ); break;
case ASCH_SHEET_SIZE::ORCAD_B: pageInfo.SetType( "B", isPortrait ); break;
case ASCH_SHEET_SIZE::ORCAD_C: pageInfo.SetType( "C", isPortrait ); break;
case ASCH_SHEET_SIZE::ORCAD_D: pageInfo.SetType( "D", isPortrait ); break;
case ASCH_SHEET_SIZE::ORCAD_E: pageInfo.SetType( "E", isPortrait ); break;
PAGE_INFO::SetCustomWidthMils( schIUScale.IUToMils( m_altiumSheet->customSize.x ) );
PAGE_INFO::SetCustomHeightMils( schIUScale.IUToMils( m_altiumSheet->customSize.y ) );
pageInfo.SetType( PAGE_INFO::Custom, isPortrait );
}
else
{
switch( m_altiumSheet->sheetSize )
{
default:
case ASCH_SHEET_SIZE::A4: pageInfo.SetType( "A4", isPortrait ); break;
case ASCH_SHEET_SIZE::A3: pageInfo.SetType( "A3", isPortrait ); break;
case ASCH_SHEET_SIZE::A2: pageInfo.SetType( "A2", isPortrait ); break;
case ASCH_SHEET_SIZE::A1: pageInfo.SetType( "A1", isPortrait ); break;
case ASCH_SHEET_SIZE::A0: pageInfo.SetType( "A0", isPortrait ); break;
case ASCH_SHEET_SIZE::A: pageInfo.SetType( "A", isPortrait ); break;
case ASCH_SHEET_SIZE::B: pageInfo.SetType( "B", isPortrait ); break;
case ASCH_SHEET_SIZE::C: pageInfo.SetType( "C", isPortrait ); break;
case ASCH_SHEET_SIZE::D: pageInfo.SetType( "D", isPortrait ); break;
case ASCH_SHEET_SIZE::E: pageInfo.SetType( "E", isPortrait ); break;
case ASCH_SHEET_SIZE::LETTER: pageInfo.SetType( "USLetter", isPortrait ); break;
case ASCH_SHEET_SIZE::LEGAL: pageInfo.SetType( "USLegal", isPortrait ); break;
case ASCH_SHEET_SIZE::TABLOID: pageInfo.SetType( "A3", isPortrait ); break;
case ASCH_SHEET_SIZE::ORCAD_A: pageInfo.SetType( "A", isPortrait ); break;
case ASCH_SHEET_SIZE::ORCAD_B: pageInfo.SetType( "B", isPortrait ); break;
case ASCH_SHEET_SIZE::ORCAD_C: pageInfo.SetType( "C", isPortrait ); break;
case ASCH_SHEET_SIZE::ORCAD_D: pageInfo.SetType( "D", isPortrait ); break;
case ASCH_SHEET_SIZE::ORCAD_E: pageInfo.SetType( "E", isPortrait ); break;
}
}
screen->SetPageSettings( pageInfo );
@@ -192,6 +192,11 @@ LIB_SYMBOL* SCH_SEXPR_PARSER::ParseSymbol( LIB_SYMBOL_MAP& aSymbolLibMap, int aF
name = FromUTF8();
// Some symbol LIB_IDs have the '/' character escaped which can break derived symbol links.
// The '/' character is no longer an illegal LIB_ID character so it doesn't need to be
// escaped.
name.Replace( wxS( "{slash}" ), wxT( "/" ) );
LIB_ID id;
int bad_pos = id.Parse( name );
@@ -268,6 +273,12 @@ LIB_SYMBOL* SCH_SEXPR_PARSER::ParseSymbol( LIB_SYMBOL_MAP& aSymbolLibMap, int aF
}
name = FromUTF8();
// Some symbol LIB_IDs have the '/' character escaped which can break derived
// symbol links. The '/' character is no longer an illegal LIB_ID character so
// it doesn't need to be escaped.
name.Replace( wxS( "{slash}" ), wxT( "/" ) );
auto it = aSymbolLibMap.find( name );
if( it == aSymbolLibMap.end() )
@@ -293,6 +304,11 @@ LIB_SYMBOL* SCH_SEXPR_PARSER::ParseSymbol( LIB_SYMBOL_MAP& aSymbolLibMap, int aF
name = FromUTF8();
// Some symbol LIB_IDs have the '/' character escaped which can break derived
// symbol links. The '/' character is no longer an illegal LIB_ID character so
// it doesn't need to be escaped.
name.Replace( wxS( "{slash}" ), wxT( "/" ) );
if( !name.StartsWith( m_symbolName ) )
{
error.Printf( _( "Invalid symbol unit name prefix %s" ), name.c_str() );
@@ -2593,6 +2609,11 @@ SCH_SYMBOL* SCH_SEXPR_PARSER::parseSchematicSymbol()
}
libName = FromUTF8();
// Some symbol LIB_IDs or lib_name have the '/' character escaped which can break
// symbol links. The '/' character is no longer an illegal LIB_ID character so
// it doesn't need to be escaped.
libName.Replace( "{slash}", "/" );
NeedRIGHT();
break;
}
@@ -2606,6 +2627,11 @@ SCH_SYMBOL* SCH_SEXPR_PARSER::parseSchematicSymbol()
LIB_ID libId;
wxString name = FromUTF8();
// Some symbol LIB_IDs have the '/' character escaped which can break
// symbol links. The '/' character is no longer an illegal LIB_ID character so
// it doesn't need to be escaped.
name.Replace( "{slash}", "/" );
int bad_pos = libId.Parse( name );
if( bad_pos >= 0 )
@@ -1495,6 +1495,13 @@ LIB_SYMBOL* SCH_SEXPR_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wx
if( it == m_cache->m_symbols.end() && aSymbolName.Contains( '/' ) )
it = m_cache->m_symbols.find( EscapeString( aSymbolName, CTX_LEGACY_LIBID ) );
if( it == m_cache->m_symbols.end() && aSymbolName.Contains( wxT( "{slash}" ) ) )
{
wxString unescaped = aSymbolName;
unescaped.Replace( wxT( "{slash}" ), wxT( "/" ) );
it = m_cache->m_symbols.find( unescaped );
}
if( it == m_cache->m_symbols.end() )
return nullptr;
@@ -353,6 +353,8 @@ void SCH_LEGACY_PLUGIN::LoadContent( LINE_READER& aReader, SCH_SCREEN* aScreen,
aScreen->Append( loadText( aReader ) );
else if( strCompare( "BusAlias", line ) )
aScreen->AddBusAlias( loadBusAlias( aReader, aScreen ) );
else if( strCompare( "Kmarq", line ) )
continue; // Ignore legacy (until 2009) ERC marker entry
else if( strCompare( "$EndSCHEMATC", line ) )
return;
else
+1 -2
View File
@@ -652,8 +652,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
}
// Remove aAdditionalRefs references
for( size_t i = originalSize; i < ( aAdditionalRefs.GetCount() + originalSize ); i++ )
RemoveItem( originalSize );
m_flatList.erase( m_flatList.begin() + originalSize, m_flatList.end() );
wxASSERT( originalSize == GetCount() ); // Make sure we didn't make a mistake
}
+42 -15
View File
@@ -63,6 +63,12 @@
#include "sch_bus_entry.h"
#include "sim/sim_model_ideal.h"
/*
* Flag to enable profiling of the TestDanglingEnds() function.
* @ingroup trace_env_vars
*/
static const wxChar DanglingProfileMask[] = wxT( "DANGLING_PROFILE" );
SCH_SCREEN::SCH_SCREEN( EDA_ITEM* aParent ) :
BASE_SCREEN( aParent, SCH_SCREEN_T ),
m_fileFormatVersionAtLoad( 0 ),
@@ -835,7 +841,7 @@ bool SCH_SCREEN::IsTerminalPoint( const VECTOR2I& aPosition, int aLayer ) const
label = GetLabel( aPosition );
if( label && label->IsConnected( aPosition ) )
if( label && !label->IsNew() && label->IsConnected( aPosition ) )
return true;
break;
@@ -847,7 +853,7 @@ bool SCH_SCREEN::IsTerminalPoint( const VECTOR2I& aPosition, int aLayer ) const
break;
case LAYER_WIRE:
if( GetItem( aPosition, 1, SCH_BUS_WIRE_ENTRY_T) )
if( GetItem( aPosition, 1, SCH_BUS_WIRE_ENTRY_T ) )
return true;
if( GetItem( aPosition, 1, SCH_JUNCTION_T ) )
@@ -861,7 +867,7 @@ bool SCH_SCREEN::IsTerminalPoint( const VECTOR2I& aPosition, int aLayer ) const
label = GetLabel( aPosition, 1 );
if( label && label->IsConnected( aPosition ) )
if( label && !label->IsNew() && label->IsConnected( aPosition ) )
return true;
sheetPin = GetSheetPin( aPosition );
@@ -1168,12 +1174,14 @@ void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
item->Plot( aPlotter, background );
}
// Plot the background items
for( const SCH_ITEM* item : other )
{
aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
item->Plot( aPlotter, background );
}
// Plot the foreground items
for( const SCH_ITEM* item : other )
{
aPlotter->SetCurrentLineWidth( std::max( item->GetPenWidth(), defaultPenWidth ) );
@@ -1187,7 +1195,10 @@ void SCH_SCREEN::Plot( PLOTTER* aPlotter ) const
aPlotter->SetCurrentLineWidth( std::max( sym->GetPenWidth(), defaultPenWidth ) );
for( SCH_FIELD field : sym->GetFields() )
{
field.ClearRenderCache();
field.Plot( aPlotter, false );
}
sym->PlotPins( aPlotter );
@@ -1355,24 +1366,40 @@ void SCH_SCREEN::GetSheets( std::vector<SCH_ITEM*>* aItems ) const
void SCH_SCREEN::TestDanglingEnds( const SCH_SHEET_PATH* aPath,
std::function<void( SCH_ITEM* )>* aChangedHandler ) const
{
PROF_TIMER timer( __FUNCTION__ );
std::vector<DANGLING_END_ITEM> endPoints;
auto getends =
[&]( SCH_ITEM* item )
{
if( item->IsConnectable() )
item->GetEndPoints( endPoints );
};
auto update_state =
[&]( SCH_ITEM* item )
{
if( item->UpdateDanglingState( endPoints, aPath ) )
{
if( aChangedHandler )
(*aChangedHandler)( item );
}
};
for( SCH_ITEM* item : Items() )
{
if( item->IsConnectable() )
{
endPoints.clear();
for( SCH_ITEM* overlapping : Items().Overlapping( item->GetBoundingBox() ) )
overlapping->GetEndPoints( endPoints );
if( item->UpdateDanglingState( endPoints, aPath ) )
{
if( aChangedHandler )
(*aChangedHandler)( item );
}
}
getends( item );
item->RunOnChildren( getends );
}
for( SCH_ITEM* item : Items() )
{
update_state( item );
item->RunOnChildren( update_state );
}
if( wxLog::IsAllowedTraceMask( DanglingProfileMask ) )
timer.Show();
}
+19 -19
View File
@@ -347,19 +347,17 @@ void SCH_SHEET::SwapData( SCH_ITEM* aItem )
void SCH_SHEET::SetFields( const std::vector<SCH_FIELD>& aFields )
{
m_fields = aFields;
int next_id = SHEET_MANDATORY_FIELDS;
for( int ii = 0; ii < int( m_fields.size() ); )
{
if( m_fields[ii].GetId() < 0 || m_fields[ii].GetId() >= ssize_t( m_fields.size() ) )
m_fields[ii].SetId( next_id++ );
// Ensure that mandatory fields are at the beginning
std::sort( m_fields.begin(), m_fields.end(),
[]( const SCH_FIELD& a, const SCH_FIELD& b )
{
return a.GetId() < b.GetId();
} );
if( m_fields[ii].GetId() != ii )
std::swap( m_fields[ii], m_fields[m_fields[ii].GetId()]);
if( m_fields[ii].GetId() == ii )
++ii;
}
// After mandatory fields, the rest should be sequential user fields
for( int ii = SHEET_MANDATORY_FIELDS; ii < static_cast<int>( m_fields.size() ); ++ii )
m_fields[ii].SetId( ii );
// Make sure that we get the UNIX variant of the file path
SetFileName( m_fields[SHEETFILENAME].GetText() );
@@ -648,14 +646,16 @@ void SCH_SHEET::AutoplaceFields( SCH_SCREEN* aScreen, bool /* aManual */ )
void SCH_SHEET::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 7;
aLayers[0] = LAYER_HIERLABEL;
aLayers[1] = LAYER_SHEETNAME;
aLayers[2] = LAYER_SHEETFILENAME;
aLayers[3] = LAYER_SHEETFIELDS;
aLayers[4] = LAYER_SHEET;
aLayers[5] = LAYER_SHEET_BACKGROUND;
aLayers[6] = LAYER_SELECTION_SHADOWS;
aCount = 8;
aLayers[0] = LAYER_DANGLING; // Sheet pins are drawn by their parent sheet, so the
// parent needs to draw to LAYER_DANGLING
aLayers[1] = LAYER_HIERLABEL;
aLayers[2] = LAYER_SHEETNAME;
aLayers[3] = LAYER_SHEETFILENAME;
aLayers[4] = LAYER_SHEETFIELDS;
aLayers[5] = LAYER_SHEET;
aLayers[6] = LAYER_SHEET_BACKGROUND;
aLayers[7] = LAYER_SELECTION_SHADOWS;
}
+14 -3
View File
@@ -1045,15 +1045,15 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::FindSheetForPath( const SCH_SHEET_PATH* aPath )
}
SCH_SHEET_PATH* SCH_SHEET_LIST::FindSheetForScreen( const SCH_SCREEN* aScreen )
SCH_SHEET_PATH SCH_SHEET_LIST::FindSheetForScreen( const SCH_SCREEN* aScreen )
{
for( SCH_SHEET_PATH& sheetpath : *this )
{
if( sheetpath.LastScreen() == aScreen )
return &sheetpath;
return sheetpath;
}
return nullptr;
return SCH_SHEET_PATH();
}
@@ -1302,3 +1302,14 @@ int SCH_SHEET_LIST::GetLastVirtualPageNumber() const
return lastVirtualPageNumber;
}
bool SCH_SHEET_LIST::HasPath( const KIID_PATH& aPath ) const
{
for( const SCH_SHEET_PATH& path : *this )
{
if( path.Path() == aPath )
return true;
}
return false;
}
+5 -3
View File
@@ -573,10 +573,10 @@ public:
SCH_SHEET_PATH* FindSheetForPath( const SCH_SHEET_PATH* aPath );
/**
* Return a pointer to the first #SCH_SHEET_PATH object (not necessarily the only one) using
* a particular screen.
* Return the first #SCH_SHEET_PATH object (not necessarily the only one) using a particular
* screen.
*/
SCH_SHEET_PATH* FindSheetForScreen( const SCH_SCREEN* aScreen );
SCH_SHEET_PATH FindSheetForScreen( const SCH_SCREEN* aScreen );
/**
* Return a #SCH_SHEET_LIST with a copy of all the #SCH_SHEET_PATH using a particular screen.
@@ -672,6 +672,8 @@ public:
void RemoveSymbolInstances( const SCH_SHEET_PATH& aPrefixSheetPath );
bool HasPath( const KIID_PATH& aPath ) const;
private:
SCH_SHEET_PATH m_currentSheetPath;
};

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